Files
deepseek-harness/docs/event-producer-consumer.md
Yichen Jiang e6483f0afc feat(settings): detect stale writers with a revision, and announce raw changes
The remaining P1 from the #939 review, plus the P2 it shares a mechanism with.

Nothing carried a version, so two tabs editing one namespace silently
overwrote each other — reproduced as tab B's `reasoning` lost to tab A's
older draft. The seam's per-namespace write queue orders writes; it cannot
tell a fresh writer from one replaying a snapshot a predecessor superseded.

Each namespace now carries a monotonic `revision` over its RAW section. A
write may send `expectedRevision`, checked at the FRONT of the queue (not at
call time, which would race the very predecessor it guards against); a
mismatch rejects with `SettingsConflictError` → `settings-conflict` on the
wire, carrying both revisions. The editor captures the revision it opened at
and, on conflict, asks the user to reopen rather than replaying its snapshot.

The same counter fixes the missing broadcast. `settings/updated` is gated on
the resolved value — correct for consumers, wrong for configuration surfaces:
storing an override equal to the composition base leaves the resolved value
alone while changing what the document says (the field is now overridden, not
inherited) and moving every open editor's revision. `settings/document-updated
(ns, revision)` fires on any raw-section change, in-process or external, and
`host/settings-changed` now rides it.

That event also closes the stale model picker: editing a provider's `models`
changes no route, so `llm/adapters-updated` never fired and an open picker
kept serving the old catalog. A change to an exposed provider namespace now
emits `host/models-changed` too — that namespace holds the catalog.

Docs: both sides of the five touched README pairs, a type-equiv block for
`SettingsPathOp`, and an Agent Note recording what the plane exposes and who
may overwrite what. The deferred wire-redaction gaps (secrets behind
union/intersection/transform, `.default(...)` in the served envelope, schema
text in rejection messages, `new Function` rehydration, pi-ai's `headers`) are
recorded as TODO(settings-wire-redaction) and in Known Limitations rather than
half-fixed.
2026-07-30 19:24:21 +08:00

18 KiB

Event Producer And Consumer Matrix

This matrix shows which packages dispatch each harness-owned event and which packages listen to it. It is intentionally a table rather than one large graph: events are many-to-many, and dense relation data is easier to review in rows. Receiver and event-name types also cover contained dispatch sites that deliberately bypass ctx.emit, such as subagent lifecycle containment.

Event Mode Declared in Dispatchers Listeners
agent-loop/config-start-failed emit packages/core/agent-loop/src/index.ts:148 agent-loop (events.dispatch) tui
agent/cancel-requested emit packages/core/agent/src/types.ts:319 agent-loop (emitAgentEvent) goal-session
agent/created emit packages/core/agent/src/types.ts:250 agent (events.dispatch) goal-session, tui
agent/disposed emit packages/core/agent/src/types.ts:259 agent (events.dispatch) agent-loop, goal-session, tui
agent/error emit packages/core/agent/src/types.ts:433 agent-loop (emitAgentEvent) apiproxy, goal-session, session-telemetry, tui
agent/inbox/dequeue emit packages/core/agent/src/types.ts:297 agent-loop (emitAgentEvent) agent, apiproxy, tui
agent/inbox/discard emit packages/core/agent/src/types.ts:309 agent-loop (emitAgentEvent) agent, apiproxy, tui
agent/inbox/enqueue emit packages/core/agent/src/types.ts:278 agent-loop (emitAgentEvent) agent, apiproxy, goal-session
agent/inbox/update emit packages/core/agent/src/types.ts:287 agent-loop (emitAgentEvent) apiproxy
agent/prompt-submit waterfall packages/core/agent/src/types.ts:346 agent-loop (waterfall) goal-session, hooks-claude, hooks-codex, repeat-tool-guard, tui
agent/request waterfall packages/core/agent/src/types.ts:372 agent-loop (waterfall) agent
agent/request-error waterfall packages/core/agent/src/types.ts:391 agent-loop (waterfall) compact-basic, llm-retry
agent/session-start emit packages/core/agent/src/types.ts:332 agent-loop (emitAgentEvent) goal, goal-session, hooks-claude, hooks-codex, workspace-context
agent/settled emit packages/core/agent/src/types.ts:420 agent-loop (emitAgentEvent) compact-basic
agent/status emit packages/core/agent/src/types.ts:268 agent-loop (emitAgentEvent) agent, apiproxy, goal-session, tui
agent/step serial packages/core/agent/src/types.ts:359 agent-loop (serial) compact-basic, plan-mode, session-checkpoint-policy, time-context, tmux-context, tool-skill, user-approval, workspace-context
agent/turn-stopping serial packages/core/agent/src/types.ts:406 agent-loop (serial) hooks-claude, hooks-codex
approval/request waterfall packages/ui/user-approval/src/index.ts:30 user-approval (waterfall) acp, apiproxy
commands/change emit packages/ui/commands/src/index.ts:154 commands (events.dispatch) apiproxy, tui
credentials/updated emit packages/credentials/credentials/src/index.ts:67 credentials (events.dispatch) apiproxy, credentials
domain/changed emit packages/storage/storage-domain/src/events.ts:46 storage-domain (emit) apiproxy, storage-domain, workspace
fs/edit-intent waterfall packages/fs/fs/src/index.ts:62 tool-fs (waterfall) fs-policy
fs/observed emit packages/fs/fs/src/index.ts:71 tool-fs (emit) fs-policy, skill-local
fs/write-intent waterfall packages/fs/fs/src/index.ts:54 tool-fs (waterfall) fs-policy
goal/changed emit packages/goal/goal/src/domain.ts:135 goal (emit) goal-session
llm/adapters-updated emit packages/llm/llm/src/index.ts:70 llm (events.dispatch) apiproxy, llm
llm/stream waterfall packages/llm/llm/src/index.ts:59 llm (waterfall) agent-loop, llm, llm-replay, session-checkpoint-policy, session-title
session/created emit packages/core/session/src/index.ts:71 session (events.dispatch) apiproxy, compact, goal, hook-protocol, jsonrpc, llm-retry, plan-mode, session, session-persistence, session-telemetry, tools, user-approval
session/disposed emit packages/core/session/src/index.ts:81 session (events.dispatch) agent-loop, apiproxy, session-persistence, session-projection-cache, session-telemetry, session-title
session/event emit packages/core/session/src/index.ts:93 session (events.dispatch) acp, apiproxy, cli-demo, compact, compact-basic, goal, goal-session, hook-protocol, jsonrpc, session, session-persistence, session-projection, session-projection-cache, session-telemetry, session-title, token-meter, tools, tui, user-approval, workspace-context
session/flush parallel packages/core/session/src/index.ts:103 session (events.dispatch) session-persistence, session-telemetry
settings/document-updated emit packages/settings/settings/src/index.ts:150 settings (events.dispatch) apiproxy
settings/updated emit packages/settings/settings/src/index.ts:137 settings (events.dispatch) settings
skills/change emit packages/skill/skill/src/index.ts:188 skill (events.dispatch) tui
subagent/end emit packages/subagent/subagent/src/index.ts:140 subagent (events.dispatch) hooks-claude, jsonrpc, subagent
subagent/provider-added emit packages/subagent/subagent/src/index.ts:114 subagent (emit) subagent, tool-subagent
subagent/provider-removed emit packages/subagent/subagent/src/index.ts:120 subagent (events.dispatch) subagent, tool-subagent
subagent/start emit packages/subagent/subagent/src/index.ts:131 subagent (events.dispatch) hooks-claude, subagent
system-prompt/assemble waterfall packages/core/system-prompt/src/index.ts:29 system-prompt (waterfall) agent, system-prompt
system-prompt/change emit packages/core/system-prompt/src/index.ts:35 system-prompt (emit) -
telemetry/record waterfall packages/telemetry/session-telemetry/src/index.ts:41 session-telemetry (waterfall) -
tools/change emit packages/core/tools/src/index.ts:156 tools (emit) -
tools/code-dispatch-log waterfall packages/core/tools/src/index.ts:138 tools (waterfall) spill-policy
tools/execute waterfall packages/core/tools/src/index.ts:113 tools (waterfall) session-checkpoint-policy, timeout-policy
tools/post-execute waterfall packages/core/tools/src/index.ts:125 tools (waterfall) hooks-claude, hooks-codex, repeat-tool-guard, spill-policy, tool-fs-search, workspace-context
tools/pre-execute waterfall packages/core/tools/src/index.ts:102 tools (waterfall) hooks-claude, hooks-codex, tool-tasks
tools/result emit packages/core/tools/src/index.ts:146 tools (events.dispatch) subagent-inprocess, workspace-context
workflow/agent-end emit packages/workflow/workflow/src/index.ts:81 workflow (events.dispatch) workflow
workflow/agent-start emit packages/workflow/workflow/src/index.ts:70 workflow (events.dispatch) workflow
workflow/end emit packages/workflow/workflow/src/index.ts:91 workflow (events.dispatch) workflow
workflow/log emit packages/workflow/workflow/src/index.ts:60 workflow (events.dispatch) -
workflow/phase emit packages/workflow/workflow/src/index.ts:53 workflow (events.dispatch) -
workflow/start emit packages/workflow/workflow/src/index.ts:45 workflow (events.dispatch) workflow

Non-harness or undeclared event strings seen in package source

Event string Dispatchers Listeners
commands/changed runtime (emit) ui-command
connection/reset runtime (emit) ui-command, ui-models
credentials/changed runtime (emit) ui-models
internal/dispatch - commands, compact, fs, goal, goal-session, hook-protocol, llm-retry, permission, plan-mode, pty-local, runtime, sandbox-policy, scope, session, session-title, subagent, time-context, tool-todo, tools, user-approval, workflow
internal/plugin - hmr, loader, modules, webserver
internal/status - agent
locale/change locale (emit) locale, ui-models, ui-settings-general
models/changed runtime (emit) ui-models
settings/changed runtime (emit) ui-models
slash/input-begin-command - ui-conversation
slash/input-consume-token - ui-conversation
slash/input-insert-reference - ui-conversation
slash/input-insert-text - ui-conversation
slots/changed runtime (emit) -
theme/change ui-theme (emit) ui-layout, ui-theme

Maintenance mode: generated: Cordis event declarations and producer/listener edges are resolved from the repository TypeScript Program.