Commit Graph

928 Commits

Author SHA1 Message Date
Tianyi Cui
800e08e930 docs: refine package hierarchy RFC 2026-06-20 21:28:02 +08:00
Tianyi Cui
7f2769c529 docs: address latest simplification review 2026-06-20 21:07:25 +08:00
Tianyi Cui
80179a5ed0 docs: address simplification review feedback 2026-06-20 20:34:56 +08:00
Tianyi Cui
99a203f445 docs: add simplification discovery skill 2026-06-20 20:09:26 +08:00
Tianyi Cui
d324b06e74 docs: fix Codex review findings on the cordis catalog
- Exclude protected methods from the generated service interface: a protected
  member (e.g. BashExecutor.notifyTaskDone) is a subclass hook, not part of the
  public ctx.<key> surface a plugin author calls. The method filter now drops
  private, protected, and static.
- Add BashTaskRead to the type cross-link map so readOutput()'s return type
  links to its core-data-structures page.
- Reword the generator module comment and the AGENTS.md @mode rule to state the
  current capability without narrating the retired event-taxonomy verifier
  (that history lives in the RFC).
2026-06-20 20:04:39 +08:00
Tianyi Cui
4e5c08ef82 docs: generated cordis events + services catalog
Add scripts/gen-cordis-catalog.ts: a fully-generated docs/cordis-catalog/
events-and-services.md cataloging every cordis event (exact signature + @mode)
and ctx.<key> service (exact interface), modeled on gen-module-graph's
--write/--check freshness gate. The harness tier renders in full from the
interface Events / interface Context declarations and their JSDoc; the inherited
cordis-core/loader/hmr/timer surface renders tersely from a curated table.

The generator hard-errors on a missing @mode tag and on a tag that contradicts
a conclusive signature shape (a trailing next param is structurally a
waterfall). Signature blocks use a ts cordis-catalog fence that doc-typecheck
skips. Type tokens cross-link to the core-data-structures catalog.

This supersedes the hand-maintained event-taxonomy table: verify-event-taxonomy
is deleted and verify-cordis-catalog joins doc-sync. architecture.md keeps the
Event taxonomy heading (TOC anchor) but points at the catalog; the Service-map
role table stays. RFC, AGENTS.md @mode authoring rule, and dependent doc/skill
references updated. Negative gate tests cover the missing-tag and
tag/shape-contradiction paths.
2026-06-20 19:47:09 +08:00
Tianyi Cui
552612622c docs: fold useful simplification RFCs from pr 74 2026-06-20 19:23:05 +08:00
Tianyi Cui
ee494969af docs: add @mode tags + enrich JSDoc on harness event declarations
Annotate all 24 harness events across the 5 event-declaring packages with
an explicit `@mode emit|waterfall|parallel` tag and self-contained JSDoc, so
the generated cordis catalog can render each entry's mode and prose from
source alone.
2026-06-20 19:21:42 +08:00
Tianyi Cui
9949f4f2ea Merge pull request #73 from deepseek-ai/worktree-acp-feature-checklist
docs: ACP feature support checklist
2026-06-20 18:14:08 +08:00
Tianyi Cui
0e73a45dc9 Merge remote-tracking branch 'origin/master' into worktree-acp-feature-checklist
# Conflicts:
#	AGENTS.md
2026-06-20 18:12:55 +08:00
Tianyi Cui
f5e61417ee docs: move ACP checklist into packages/acp
Co-locate the ACP feature support checklist with the bridge package
(packages/acp/acp-feature-support.md) and rewrite its relative links for
the new depth. Broaden the doc-sync globs (doc-typecheck, verify-md-wrap,
verify-md-links) from packages/*/README.md to packages/*/*.md so a
package-level doc beyond the README stays under the drift gates, and
update the AGENTS.md prose describing that scope.
2026-06-20 18:08:17 +08:00
Tianyi Cui
bcf255fc57 docs: fix review findings in ACP checklist
- session/close: ⚠️ (no handler; SDK dispatch returns method_not_found —
  disconnect/disposal teardown is not the per-session method)
- Codex plan: ⚠️ (CodexEventHandler.updatePlan emits the stable `plan`
  update; the plan-as-text note was stale)
- Codex elicitation: ⚠️ (maps onto session/request_permission; does not
  call elicitation/create|complete)
- Overview: qualify the "both adapters ship" clause — neither drives the
  client terminal/* family and only Claude uses fs/*
- Remove a stray </content> sentinel that rendered literally at EOF
2026-06-20 17:50:58 +08:00
Tianyi Cui
2d6bb4c8ce Merge pull request #71 from deepseek-ai/worktree-core-data-structures-doc
docs: core data structures catalog + verify-type-equiv gate
2026-06-20 17:36:20 +08:00
Tianyi Cui
5a6243900d fix(doc-sync): close verify-type-equiv scan gap; correct persistence prose
Review found verify-type-equiv only scanned docs the manifest already named, so
a type-equiv block in an unmanifested doc was silently skipped — defeating the
1:1 guarantee. Scan all docs in the markdown glob scope instead, so an orphan
block in any doc is caught. Also parse `abstract class` in blockSymbol (matches
sourceDeclaration's class support).

persistence.md listed the SessionPersistence surface as create/append/load/list;
the abstract service also exposes has/delete. AGENTS.md's doc-sync command
summary omitted verify-md-links and verify-type-equiv.
2026-06-20 17:29:42 +08:00
Tianyi Cui
ea3f138ae9 docs: address simplification RFC review 2026-06-20 17:26:23 +08:00
Tianyi Cui
c3278e9660 docs: add ACP feature support checklist
Inventory the ACP v1 surface (stable schema 1.14.0 plus the unstable
features the claude-agent-acp and codex-acp reference adapters ship) and
mark where the dsh-acp bridge stands on each: agent methods, client
methods, capabilities, session/update variants, tool-call rendering,
content blocks, and a ranked gap summary.
2026-06-20 16:57:22 +08:00
Tianyi Cui
cc47f76cea docs: propose simplification RFCs 2026-06-20 16:33:03 +08:00
Tianyi Cui
ea5697e354 docs(review): require keeping the core-data-structures catalog in sync
Add a standing instruction in AGENTS.md and a hard-blocker check in the
dsh-code-review skill: a change that adds/removes/reshapes a type the catalog
documents must update the catalog (prose + verbatim block + manifest) in the
same diff. verify-type-equiv catches a drifted paste but cannot flag a new core
type that went undocumented — that judgment is on author and reviewer.
2026-06-20 16:25:08 +08:00
Tianyi Cui
0f7abc9808 docs(core-data-structures): catalog the core data structures
A new docs/core-data-structures/ folder: a self-contained core.md defining what
counts as a "core" data structure (the agent-loop spine) and covering the spine
vocabulary, plus per-seam sub-pages (llm-streaming, session, persistence, tools,
bash). Type definitions are pasted verbatim via `ts type-equiv` blocks and
drift-checked by verify-type-equiv. Cross-linked from architecture.md; the
`ts type-equiv` mechanics are documented in development.md.
2026-06-20 16:24:56 +08:00
Tianyi Cui
07048983e0 build(doc-sync): add verify-type-equiv gate for verbatim type pastes
Introduce a `ts type-equiv` Markdown fence: a verbatim paste of a source type
definition that `scripts/verify-type-equiv.ts` drift-checks against the source
symbol via the TypeScript parser, with provenance in a central
`scripts/type-equiv.manifest.json` kept 1:1 with the blocks. doc-typecheck
recognizes the same fence, skips compiling it (not standalone-compilable), and
excludes it from the opt-out ratio. Wired into the `doc-sync` chain.
2026-06-20 16:24:37 +08:00
Tianyi Cui
0b0486796b Merge pull request #70 from deepseek-ai/worktree-bash-owner-token
feat(bash): owner token in the executor seam
2026-06-20 14:23:37 +08:00
Tianyi Cui
5314f7cbda Merge remote-tracking branch 'origin/master' into worktree-bash-owner-token 2026-06-20 14:21:34 +08:00
Tianyi Cui
5e3f0f6d18 Merge pull request #69 from deepseek-ai/worktree-agent-handle
feat(agent): AgentHandle async per-agent disposer
2026-06-20 14:21:08 +08:00
Tianyi Cui
5f355fbc7c Merge remote-tracking branch 'origin/master' into worktree-agent-handle 2026-06-20 14:18:42 +08:00
Tianyi Cui
3556f3bb4f Merge pull request #68 from deepseek-ai/worktree-cancel-primitive
feat(agent): add queue-aware Agent.cancel() primitive
2026-06-20 14:18:03 +08:00
Tianyi Cui
05ef69f253 Merge remote-tracking branch 'origin/master' into worktree-cancel-primitive 2026-06-20 14:15:35 +08:00
Tianyi Cui
265b6ceb19 Merge pull request #67 from deepseek-ai/worktree-persistence-coordinator
refactor(session-persistence): extract a shared write coordinator
2026-06-20 14:14:59 +08:00
Tianyi Cui
8927691eb8 Merge remote-tracking branch 'origin/master' into worktree-persistence-coordinator 2026-06-20 14:12:18 +08:00
Tianyi Cui
1017ebbc74 Merge pull request #66 from deepseek-ai/worktree-drop-session-summary
refactor(session): drop the dead mutable SessionSummary
2026-06-20 14:11:37 +08:00
Tianyi Cui
fd9ecdce40 Merge remote-tracking branch 'origin/worktree-agent-handle' into worktree-bash-owner-token 2026-06-20 13:57:14 +08:00
Tianyi Cui
29ce64b8bd Merge remote-tracking branch 'origin/worktree-cancel-primitive' into worktree-agent-handle 2026-06-20 13:56:35 +08:00
Tianyi Cui
d2b26325e2 Merge remote-tracking branch 'origin/worktree-persistence-coordinator' into worktree-cancel-primitive 2026-06-20 13:55:58 +08:00
Tianyi Cui
d06c75d68f Merge remote-tracking branch 'origin/worktree-drop-session-summary' into worktree-persistence-coordinator 2026-06-20 13:54:59 +08:00
Tianyi Cui
38cc62b644 docs(AGENTS): forbid naming the change unit (PR/commit) in comments & test names (review)
The doc-current-state convention already forbade process-narration phrasing, but
review caught a subtler slip it did not name explicitly: comments and test
descriptions that reference the PR / stack position that introduced the code
("(PR D's teardown)", "Tests for … (PR C)", "identity no longer matters"). The
reader of the current tree has no PR D or prior design to anchor against. Add an
explicit clause: never name the unseeable change unit in a comment, JSDoc, or
test name — state the mechanism instead.
2026-06-20 13:53:56 +08:00
Tianyi Cui
8597cc2c58 docs(tool-bash): state ownership tests as current fact (review)
Two ownership tests narrated the change's history — "the old design fenced by
Agent object identity", "closing the old XXX(tool-bash-owner-hmr) gap". Reword
to state the current contract (ownership fences by session.header.id; the token
lives on the executor task, so a tool-bash reload preserves it) without
referencing the prior design. Per the repo doc-current-state convention.
2026-06-20 13:52:02 +08:00
Tianyi Cui
44762efbd7 docs(acp): drop PR-letter ref from dispose test comment (review)
The disconnect-mid-prompt test comment said "PR D's per-agent AgentHandle
teardown", narrating the change's origin. Per the repo doc-current-state
convention, state the mechanism (the session's AgentHandle teardown) without
naming the PR that introduced it.
2026-06-20 13:51:42 +08:00
Tianyi Cui
16304872e1 docs(agent-loop): drop PR-letter ref from cancel test header (review)
The cancel.spec.ts module doc named "PR C", narrating the change's origin —
process/history a reader of the current test does not need. Per the repo
doc-current-state convention, describe only what the suite tests.
2026-06-20 13:51:30 +08:00
Tianyi Cui
329e5c3e2e docs(session-persistence): state coordinator-contract role as current fact (review)
Reword the suite's module doc to describe what it IS — each scenario lives
here once and runs per backend through the fixture — rather than narrating
that the scenarios were previously duplicated in the per-backend specs. Per
the repo doc-current-state convention (no process/history in comments).
2026-06-20 13:51:09 +08:00
Tianyi Cui
90a19f072d docs(acp,rfc): fix stale ownership wording + propose unifying agent/session id (review)
Review follow-ups on the bash owner-token PR:

- packages/acp/README.md still described task isolation in object-identity terms
  ("records each background task's owning agent", "a different agent"). Rewrite
  to the session-token model: ownership is by `session.header.id`, stored on the
  executor's task, so a different Agent object on the same session may access it
  and ownership survives a tool-bash HMR reload.

- The reviewer flagged that the notice routes by `session.header.id` while the
  registry only enforces unique `agent.id`, so a programmatic caller could
  register two agents sharing a session token and mis-route a notice (not
  reachable via ACP). Rather than bolt a session-id invariant onto the generic
  registry, add a proposed RFC (2026-06-20-unify-agent-and-session-id) to remove
  the precondition by construction — an agent IS its session, one id — with a
  full risks discussion (forecloses multi-session-actor / fork futures, makes the
  config resume-or-create policy load-bearing, migration churn). The actual
  unification ships as its own Codex-converged PR. Cross-linked from the
  agent-lifecycle RFC's seam-precondition note.

- Reframe the tool-bash module-doc ownership paragraph to current-state (per the
  new AGENTS.md doc convention): contrast storing the token on the executor vs
  in the plugin as a standing rationale, not as "closing the old gap".
2026-06-20 13:38:48 +08:00
Tianyi Cui
b9725e8602 Merge remote-tracking branch 'origin/worktree-agent-handle' into worktree-bash-owner-token 2026-06-20 13:07:44 +08:00
Tianyi Cui
083a6fc990 fix(agent): re-check id in enter() + memoize AgentHandle.dispose() (review)
Two blocking lifecycle findings from the deep review:

- `SessionStore.enter()` is a public cross-package primitive that a caller can
  separate from `prepare()` by arbitrary work, so it must re-check the id: a
  stale prepared session could otherwise overwrite a live store entry of the
  same id, and the stale session's detach disposer would later delete the REAL
  session. Re-add the duplicate-id throw (removed earlier on a coverage
  rationale that only held for the back-to-back internal caller). Tests cover
  the stale-overwrite rejection and the prepare/enter/announce lifecycle (which
  also covers the throw branch).

- `AgentHandle.dispose()` exposed the raw single-shot cordis effect disposer, so
  a concurrent/second dispose() returned immediately (effect epoch already
  cleared) instead of awaiting the in-flight teardown — violating the
  dispose(): Promise<void> contract that every caller observes the same
  quiescence boundary. Memoize the disposal promise in startOwned. Regression
  test gates the loop's final flush, fires two dispose() calls, and asserts the
  second stays pending until the first's teardown completes (fails without the
  memo).
2026-06-20 13:06:28 +08:00
Tianyi Cui
3814ffc5b0 Merge remote-tracking branch 'origin/worktree-cancel-primitive' into worktree-agent-handle 2026-06-20 12:58:45 +08:00
Tianyi Cui
f58b031465 fix(agent): close the window-2 early-whenIdle race + sync cancellation RFC docs (review)
A reviewer found that window 2 (a cancel from a synchronous agent/status('running')
listener) had the same early-whenIdle() race that window 1 already guards: it
unconditionally `setStatus('idle')` + continue, which settles `whenIdle()`
waiters — so if the running listener cancels AND queues replacement work, the
waiter resolves while the replacement is still queued-and-unrun (the next
iteration runs it later, but the caller already observed quiescence).

Mirror window 1: after clearing the marker, only `setStatus('idle')` when
nothing new is queued; otherwise fall through to run the queued replacement
(status is already `running`), so `whenIdle()` resolves on that turn's
running→idle. Regression test reproduces the reviewer's interleaving (running
listener cancels A, sends B; whenIdle() resolves only after B ran).

Also syncs the cancellation contract in the two ACP RFCs that describe the live
behavior: `session/cancel` is the queue-aware `agent.cancel()` (drops an
about-to-start turn), not the old best-effort `agent.abort()` pre-step
limitation.
2026-06-20 12:57:32 +08:00
Tianyi Cui
7507ca0c70 Merge remote-tracking branch 'origin/worktree-persistence-coordinator' into worktree-cancel-primitive 2026-06-20 12:52:18 +08:00
Tianyi Cui
301a3d1233 fix(session-persistence): scope the ownerless-state claim to the cwd (review)
A reviewer found a cross-cwd hole: the ownerless-state claim path validated only
the seed prefix (via loadStored, any scope) and never compared the tracked
header's cwd to the live session's. So an ownerless `create(meta(id, "/a"))`
with cursor 0 (seed matches trivially) was claimed by a live session with the
same id at cwd "/b", and the "/b" events then appended under the "/a" header —
bypassing the cwd-scoped loadLive() guard that the HMR-adopt path (case 2) uses.

Add a cwd equality check before the seed check in the ownerless-claim branch: a
same-id ownerless artifact at a different cwd is a collision, not a claim. This
is a coordinator-level invariant (the live session's cwd must match the tracked
meta's cwd) and applies to both backends.

Tests (shared coordinator contract, run per backend): a live session at a
different cwd cannot claim cursor-0 ownerless state, cannot claim a
loaded-prefix even when the seed matches, and a no-cwd state cannot be claimed
by a cwd'd session. All fail without the guard.

Also documents WHY the `materialized` flag is needed (lazy create leaves no
artifact; it distinguishes registered-but-unwritten from durably-present for
has()/reclaim) and reframes the module doc to current-state, not the refactor
history (per the new AGENTS.md doc convention).
2026-06-20 12:50:55 +08:00
Tianyi Cui
a3e90bb31c Merge remote-tracking branch 'origin/worktree-drop-session-summary' into worktree-persistence-coordinator 2026-06-20 12:43:44 +08:00
Tianyi Cui
1bb201365d docs(agents): add doc-current-state convention + sharpen the summary worked example (review)
Two review findings on the AGENTS.md additions:

- Add a convention to § Type Safety and Documentation: document the CURRENT
  state (what + why), never the PROCESS/HISTORY of how the code got there. No
  "previously/now/used-to/replaces/the old X" in comments or JSDoc — that rots
  on the next change and belongs in the commit message / PR / RFC. A standing
  contrast against a live alternative is fine; a contrast against the codebase's
  past is not.

- The "tests document behavior" worked example overstated the audit as "nothing
  in production read or wrote" the summary. The backends DID write it (JSONL
  sidecar, SQLite updated_at); what made it dead was no CONSUMER and no
  update() caller. Corrected so a future reader does not infer the write path
  never existed.
2026-06-20 12:42:53 +08:00
Tianyi Cui
e8634a0495 Merge remote-tracking branch 'origin/worktree-agent-handle' into worktree-bash-owner-token 2026-06-20 11:57:15 +08:00
Tianyi Cui
de0c4605bd docs(acp): correct teardown wording — dispose uses the disposed path, not cancel() (review)
A reviewer noted the quiesce() comment + ACP README said `AgentHandle.dispose()`
stops the loop "with the queue-aware cancel", but the handle delegates to the
start-disposer's `stop(); await agent.done`, where `stop()` sets `disposed` and
aborts the current controller — it does NOT call `agent.cancel()`. The pre-step
teardown window is still closed (the disposed promise wakes the parked loop and
`isDisposed()` breaks before a turn starts), but the mechanism is the DISPOSED
path and a mid-flight turn ends with reason `disposed`, not `aborted`. Corrected
the comment and the README to describe the actual path.

(This commit follows the merge of PR C's `cancel(reason)` fix up into this branch.)
2026-06-20 11:55:56 +08:00
Tianyi Cui
15335f74ba Merge remote-tracking branch 'origin/worktree-cancel-primitive' into worktree-agent-handle 2026-06-20 11:52:45 +08:00