live · gmail
Email context
“Find the message about the upcoming interview.”
Searches Gmail read-only with a query built from the request, then reads only the messages the answer needs.
- gmail.readonly
DHLM / Personal intelligence system
I built DHLM to bring the information I actually need into one private workspace—connecting approved sources, useful AI assistance, and deliberate human control.
Request: What’s on my calendar this week?
Answer: Three events through Friday. The earliest is Tuesday’s design review at 10:00.
L1 Calendar · read-only
01 / Why I built it
My work moves between school, analytics, software projects, business, and career planning. The context I need rarely lives in one place. An email contains one detail, a calendar event another, and a file holds the rest.
DHLM is my answer to that fragmentation: a focused place to ask better questions, retrieve relevant information, and turn scattered context into a clearer next step.
Fragmented sources becomes Connected context
Gmail, Calendar, Drive, and my own notes can answer one question together.
Repeated searching becomes Focused retrieval
A rule-based router decides which sources a question needs. Nothing else is fetched.
Powerful tools becomes Explicit boundaries
Read-only by default. Writing needs a separate grant and a confirmation every time.
Inside DHLM
One private workspace. Every approved source, one question away.
02 / What DHLM supports
Every workflow starts with a plain request. DHLM works out which approved sources that request needs, fetches only those, and answers with the sources attached.
live · gmail
“Find the message about the upcoming interview.”
Searches Gmail read-only with a query built from the request, then reads only the messages the answer needs.
Request: Find the message about the upcoming interview.
Avery Chen confirmed a 45-minute interview for Thursday at 2:00 PM and asked you to bring one analytics project to discuss L1.
Illustrative preview · Synthetic data
live · calendar
“What is coming up this week?”
Lists the next seven days of events from Google Calendar. Scheduled events are shown as events; anything the model suggests is labeled as a suggestion.
Request: What is coming up this week?
Two events this week: the design review Tuesday at 10:00 L1 and the Northwind interview Thursday at 2:00 L2. Suggestion, not on your calendar: set aside time Wednesday to prepare.
Illustrative preview · Synthetic data
live · drive
“Find the notes for this project.”
Searches Drive file names and metadata, then reads Google Docs, Sheets, Slides, or plain-text files when asked.
Request: Find the notes for this project.
The working notes are in “Harbor Dashboard — working notes” L1. The latest section lists three open questions about the metrics definitions L2.
Illustrative preview · Synthetic data
career · applications
“Which applications need my attention?”
The career workspace keeps application records. A Gmail sync I run labels recruiter, interview, and confirmation emails with rules and links them to applications for review.
Request: Which applications need my attention?
Two need attention: reply to Northwind’s interview request C1, and consider a follow-up with Lumen Labs—it has been 12 days since you applied C2.
Illustrative preview · Synthetic data
draft · confirm required
“Help me draft a reply.”
Drafts in my writing style. Saving it to Gmail is an optional, separately granted action with a preview and a one-time confirmation. DHLM never sends email.
Request: Help me draft a reply.
Here’s a short reply in your style. Review it, then choose “Create Gmail draft” to prepare it. Nothing is sent.
Prepare → review exact preview → confirm within 5 minutes → draft saved. Sending stays manual.
Illustrative preview · Synthetic data
quick action · on request
“Give me my morning brief.”
A quick action I run when I want it: calendar, recent email, and my current priorities in one answer. It is not a scheduled job.
Request: Give me my morning brief.
Design review at 10:00 L1. Northwind confirmed Thursday’s interview L2. Your top priority is still the Harbor dashboard draft K1.
Illustrative preview · Synthetic data
03 / Request architecture
Simplified architecture. The case study uses synthetic data.
01Ask
Every chat request passes the same gate: a signed session for the one authorized account, a same-origin check, and a rate limit. A rule-based router then classifies the question and names the sources it needs.
01 Ask
“What’s on my calendar this week, and did the recruiter reply?”
route: live · calendar, gmail
Synthetic
02Authorize & retrieve
Live data is fetched in parallel, once per source, and only if the connected Google grant includes that read scope. Personal notes come from a ranked search over my own Markdown knowledge files.
02 Authorize & retrieve
Synthetic
03Assemble & reason
DHLM assembles a system instruction, the ranked notes with their precedence, and the live results, then streams a response from Gemini. A daily budget decides whether a deeper model is allowed.
03 Assemble & reason
Gemini · default model · streaming
daily budget: within limit
Synthetic
04Return & review
Sources appear beside the streamed answer and usage is logged. Anything that would change an account—a draft, an event, a memory update—stays a separate step that I review and confirm.
04 Return & review
Three events this week, including Thursday’s interview L1. The recruiter replied Tuesday to confirm the time L2.
L1 Calendar L2 Gmail
Synthetic
04 / What I built
I designed and built the application, the integrations, and the controls around them. Google provides the data APIs and the Gemini models; DHLM decides what to ask them, when, and with which permission.
Application, integrations, and controls by Davis Higgins
Server-rendered pages, streaming route handlers, and one gate in front of everything.
How the app is structured
Service-specific clients that check the granted scope before every call.
What the integrations actually read
A configured model, a strict prompt, and a daily budget.
How requests reach the model
Private Postgres tables that only the server can reach.
What is stored, and where
Deterministic where it matters and tested where it could break.
Validation, tests, and scheduled work
05 / Authentication and control
Identity
Google sign-in establishes who I am. It asks only for a basic profile, and the server compares the verified email with the one authorized account. Anyone else is turned away.
openid · email · profile
Integration permissions
Gmail, Calendar, and Drive are connected in a separate consent step with read-only scopes. Signing in does not hand DHLM my inbox or my files.
gmail.readonly · calendar.readonly · drive.readonly
| Service | Default | Optional action | Boundary |
|---|---|---|---|
| Google identity | Basic profile only | None | One authorized account, checked on the server |
| Gmail | Read-only search and read, when connected | Create drafts, if enabled | Preview and confirmation; never sends |
| Calendar | Read-only upcoming events, when connected | Create events, if enabled | Preview and confirmation |
| Drive | Read-only search and supported text, when connected | None | Docs, Sheets, Slides, and text under 2 MB |
The Google refresh token lives in an encrypted, HTTP-only cookie—not in the database.
Grants and OAuth state are sealed with AES-256-GCM. The session is a signed token in an HTTP-only, same-site cookie that is marked secure in production.
Sign-in uses PKCE and a one-time state value that expires after ten minutes.
Drafts and events are prepared, previewed, and then confirmed with a single-use token.
The prepare step returns the exact preview and a signed token bound to that action and a hash of its details. It expires in five minutes and can be used once.
If anything in the draft or event changes after review, the token no longer matches and the action is refused.
Disconnecting revokes the token at Google and deletes the local cookie.
Sign-ins, denied sign-ins, connections, and every prepared or executed write are written to an audit log.
The assistant can suggest updates to what DHLM knows about me. Nothing changes until I approve it.
Relevant context may be sent to Google Gemini to generate a response. DHLM keeps that processing tied to the signed-in user’s request. Read the privacy policy.
Perspective & boundaries
06 / Perspective and limits
DHLM is a private system built around my workflows—not a public multi-user service. Its value comes from connecting useful information with clear boundaries, not giving an AI unrestricted access.
Drive answers draw on Google Docs, Sheets, Slides, and plain-text files under 2 MB. Other formats are found by name, not read.
If Google access expires or a scope is missing, DHLM says so and asks me to reconnect instead of guessing.
A model can misread context or miss something. Sources sit beside each answer so I can check it.
Drafts and calendar events stay off until I grant them separately, and each one still needs confirmation.
Useful AI. Clear boundaries.
The numbers that define the boundary: what DHLM can reach, who can use it, and what it will never do on its own.
3
Gmail · Calendar · Drive
1
Single user
5
Single-use confirmation
0
Human directed
Next.js 16
Application framework
React 19
Interface
TypeScript
Strict mode throughout
Tailwind CSS 4
Private app styling
Google Gen AI SDK
Gemini, server-side only
Gmail API
Read-only by default
Calendar API
Read-only by default
Drive API
Read-only by default
Supabase Postgres
Server-only persistence
Zod
Request and config validation
Vitest
Unit tests
Playwright
End-to-end tests
Vercel
Hosting