Two related gaps, different scopes
1. Store — applies to every channel operation. recall_channel operations select a store at call time and do not report which one they selected.
2. Caller identity — applies only to operations that resolve one. action=unread resolves a caller identity for membership and cursor lookup (_handle_unread → channel_unread_read → _agent_id) and does not report it. action=who does not resolve a caller identity at all (_handle_who → channel_who → _open_db), so it has nothing to report; asking it to surface a process identity would be a new feature, not the closing of this gap.
Repro
recall_channel(action=unread, channel=dev, detail=low) — returns a result or a membership error. Reports neither the store nor the identity it used.
recall_channel(action=who, channel=dev, detail=low) — returns a result. Reports the store it read: no.
For contrast, journal --repair --dry-run prints an absolute resolved path under the selected .synapt/recall root and exits 0. format_repair_report always names the store it examined. Channel operations should be consistent with that.
Why it matters
project_data_dir() selects a root by precedence — explicit SYNAPT_RECALL_ROOT, then the git main-worktree root, then a gripspace-root search, then cwd — and appends .synapt/recall. _db_path() returns that root's local channels/channels.db.
Two callers resolving to different roots read different stores while issuing identical calls against the same channel name. The symptom is a membership error or an apparently empty channel, and that is indistinguishable from a channel that genuinely has no messages. Because the operations do not report the selection, a caller cannot tell the two apart from the response.
Evidence
A server process started without SYNAPT_RECALL_ROOT or SYNAPT_AGENT_ID, whose cwd was not inside a git repository, resolved a per-directory store rather than the intended shared one. The two candidate databases differed in size by a factor of about 55, and the intended store already held the expected membership row. Setting SYNAPT_RECALL_ROOT and SYNAPT_AGENT_ID at spawn time resolved both correctly, verified read-only.
Proposed
- Have channel operations report the resolved store path, matching what
journal --repair already does for its own store.
- Have operations that resolve a caller identity report it. This does not apply to
who.
- Document the precedence chain.
- Consider whether silent per-directory fallback is the right default when a shared root is discoverable, or whether it should be opt-in.
Spawn-time environment is an adequate workaround. It does not close the observability gap.
Two related gaps, different scopes
1. Store — applies to every channel operation.
recall_channeloperations select a store at call time and do not report which one they selected.2. Caller identity — applies only to operations that resolve one.
action=unreadresolves a caller identity for membership and cursor lookup (_handle_unread→channel_unread_read→_agent_id) and does not report it.action=whodoes not resolve a caller identity at all (_handle_who→channel_who→_open_db), so it has nothing to report; asking it to surface a process identity would be a new feature, not the closing of this gap.Repro
recall_channel(action=unread, channel=dev, detail=low)— returns a result or a membership error. Reports neither the store nor the identity it used.recall_channel(action=who, channel=dev, detail=low)— returns a result. Reports the store it read: no.For contrast,
journal --repair --dry-runprints an absolute resolved path under the selected.synapt/recallroot and exits 0.format_repair_reportalways names the store it examined. Channel operations should be consistent with that.Why it matters
project_data_dir()selects a root by precedence — explicitSYNAPT_RECALL_ROOT, then the git main-worktree root, then a gripspace-root search, then cwd — and appends.synapt/recall._db_path()returns that root's localchannels/channels.db.Two callers resolving to different roots read different stores while issuing identical calls against the same channel name. The symptom is a membership error or an apparently empty channel, and that is indistinguishable from a channel that genuinely has no messages. Because the operations do not report the selection, a caller cannot tell the two apart from the response.
Evidence
A server process started without
SYNAPT_RECALL_ROOTorSYNAPT_AGENT_ID, whose cwd was not inside a git repository, resolved a per-directory store rather than the intended shared one. The two candidate databases differed in size by a factor of about 55, and the intended store already held the expected membership row. SettingSYNAPT_RECALL_ROOTandSYNAPT_AGENT_IDat spawn time resolved both correctly, verified read-only.Proposed
journal --repairalready does for its own store.who.Spawn-time environment is an adequate workaround. It does not close the observability gap.