Review follow-ups on b9b2e593f, all documentation precision. The redundancy note on `isCompactCheckpoint` leaned on a reading its call site does not state: `index.ts` reaches it for surface-eligible non-append events, which is the same set as replacements only because the marker is mandatory. Say that instead. The Agent Note now owns three facts it was leaving to a future reader. `rebuildTranscript` materializes a component per append-origin event and runs on mount, color-scheme change, and every reasoning toggle — work compaction used to bound for exactly the long sessions it serves, so the cost now tracks session length rather than the surface. `Consequences` names `surface-replayed-compaction` as the durable evidence for the live/replay equivalence claim, so the two fixtures that must move together are findable from the Note rather than the PR thread. `Deferred` records that a page can now carry a checkpoint whose `surfaceOp.start` fell out of the window: pagination no longer cuts on the checkpoint's provenance group, `FoldAdapter` pads with a non-surface sentinel, and `nodes()` degrades to `degradedSeqs()` — which is already close to the transcript projection A2 should build deliberately. Also corrects the definite-assignment comment in the snapshot scenario: the assertion rests on the awaited setup invoking `beforeMount`, not on that call being synchronous.
ui/ — human and SDK-client integration surfaces
English | 中文
Human-facing channels and the out-of-process SDK server. These are product packages: real interfaces that a person or SDK client drives.
| Package | Role | ctx key |
|---|---|---|
commands/ |
Human-command registry: shared discovery metadata, scoped shadowing, cancellation, and direct UI dispatch | ctx.commands |
user-approval/ |
One-shot user-approval mechanism, closed outcome vocabulary, audit events, and per-session approval policy | ctx.approval |
permission/ |
User-facing permission presets (workspace-write/danger-full-access): one product-level select bundling the sandbox-mode and approval-policy knobs, written through to their session events |
ctx.permission |
user-interaction/ |
Abstract human question/answer seam used by UI-backed confirmation tools | ctx.userInteraction |
tool-ask-user/ |
Model-facing ask_user_question tool over ctx.userInteraction |
(registers on ctx.tools) |
tui/ |
Interactive pi-tui terminal channel; renders session titles/events and tool intents, answers ctx.userInteraction, and hosts effect-owned plugin overlays |
ctx.tui (drives ctx.agents) |
jsonrpc/ |
Stdio JSON-RPC server for out-of-process SDK clients | (drives ctx.agents) |
app-boot/ |
Shared boot glue for the app bins: .env loading, fail-loud Loader guards, snapshot-aware config resolution, the settle-the-tree boot sequence |
(library for the bins) |
A UI integration is a client-driver plugin, not a loop change: it consumes the existing agent/* event taxonomy and the dsh-agent factory. tui is the interactive terminal front door and supplies the terminal-local ctx.tui extension service; jsonrpc serves out-of-process SDK clients, while non-interactive one-shot tasks use cli-demo. commands is the human-only discovery and dispatch plane consumed by TUI; command input and output do not become model messages.
user-approval, user-interaction, and tool-ask-user live here because asking a human is a UI-backed product affordance, not part of the providerless core spine. user-approval owns the one-shot ctx.approval decision mechanism and its policy tier; answerers remain with the channel or automation transport that owns the agent. user-interaction remains provider-neutral (ctx.userInteraction), while tool-ask-user is its model-facing consumer and interactive app packages provide concrete providers.
The runnable app bundles composed over agent-spine-demo live in examples/ (tui-demo, acp-demo, jsonrpc-demo). acp-demo and jsonrpc-demo own boot bins; the tui-demo bundle is booted by the product dsh CLI. ui/ keeps the reusable human/SDK channel plugins and shared app-boot glue; the automation-only ACP transport lives in acp/. Each front door owns its stdout policy, and a leaf cordis.yml supplies backends and optional tools.