Field Note 01 · April 2026

Hidden Connector

Three surfaces, one backend. There is an API door — just not for me. Started with data portability, built the sync.

Principle — agent-era intentional surface assignment

Code → src/importers/claude_api_sync.ts

01

Gap

Setting up the vault to work more with Claude Code. The vault is my local Obsidian notes directory; Claude Code writes session transcripts into it automatically. Migration phase exposes the asymmetry:

The only thing claude.ai offers is a bulk export — zip file, on demand, stale by design. That’s not a sync, that’s a filing cabinet. Without a real sync, ~90% of my Claude thinking stays locked on the one surface that won’t let it leave. Vault premise breaks.

02

Discovery chain

1. Didn’t accept export-or-nothing. Started looking for a real sync. While setting up a local integration that lets Claude Desktop read my vault, noticed Desktop, mobile, and web all showed identical session lists — same titles, same timestamps. Three surfaces, one backend. Which meant: there is an API door. Just not for me.

2. First solve — rejected deliberately. Honest first instinct was a surface-level workaround: script a cloud agent to open the desktop app, wait for Desktop to sync the web session down, then let my local integration pick up the new files:

remote agent → opens Desktop → Desktop syncs web → local integration harvests

Four links, any one breaks. Remote agent failure, Desktop failure, sync lag, harvest miss. Not a sync — a hostage situation stacked on top of a GUI I don’t control. The brainstorm clarified what reliability would require: cut dependencies, don’t add them.

3. Pivot. Don’t go through the app. Go to the service. Every surface sends an auth credential — find it.

4. Hunt. Two quotes from the session carry the texture better than paraphrase:

Claude

“I can’t interact with Windows GUI apps, only the WSL terminal.”

Claude

“The Cookies DB is locked (Claude Desktop has it open). Can’t read it while the app is running.”

Windows app-storage angle: dead end. Detour to web DevTools network tab. Two endpoints surfaced immediately:

03

Solution

Two endpoints, one cookie, incremental by default.

GET /chat_conversations_v2           → list
GET /chat_conversations/{uuid}       → content
Cookie: sessionKey=<from DevTools>

The key-rotation step is the human-in-the-loop piece. Not hidden automation masking a manual dependency — the system surfaces the expiry cleanly and hands control back at the only moment it needs a human. Deliberate.

04

Attribution

05

Why this matters

Started with data portability. Built the sync.

Side effect I didn’t plan for: isolating the transport layer meant nothing downstream had to know where the data came from. Parser, link graph, MCP search — all blind to source. Separation of concerns showed up on its own. Bonus, not goal.

The bigger lesson is still in motion for me —

In the cloud era we’ve become so accustomed to having our applications available on any surface at any time anywhere — we’ve designed UIs and security systems accordingly. But as agents become embedded and go deeper into our local environments, down the abstraction layer, it’s more important that we are very intentional about the way our agents can live: where we quarantine or isolate them, how we think about security, UIs, human-in-the-loop. All designed intentionally. Not one-size-fits-all.

Three live questions, same question asked three ways:

Surface assignment isn’t a one-time call. Running decision, re-evaluated every time the agent layer pushes deeper.

Open / deferred: format (repo / blog / both) → post-content sprint · arch questions → /program · template fit → reassess after #2.

← rowbyroh