Collapse docs/adr/ and docs/rfc/ into a single docs/rfc/ with proposed/,
implemented/, and rejected/ subfolders. Every file is renamed to
yyyy-mm-dd-topic-title.md, where the date is when the topic was first
proposed (from git history). ADRs and RFCs that covered exactly the same
topic are merged (property-based testing, session persistence); the
umbrella RFC 005 stays split across its three implemented decisions, and
RFC 006's deferred part-3 (API extractor reports) splits into its own
proposed RFC. All cross-references become machine-checkable relative
links instead of bare "ADR NNNN" / "RFC NNN" prose.
Add a verify-md-links doc-sync gate (scripts/verify-md-links.ts) that
checks every relative Markdown cross-link resolves, wired into doc-sync
alongside verify-md-wrap. This makes the reorganization self-verifying:
the same change that rewrote ~forty inter-doc links adds the check that
proves none dangle. Document the cross-link convention in a new
docs/AGENTS.md and record the gate as an implemented RFC.
doc-sync, typecheck, lint, and the full test suite (667) all pass.
Per review feedback (use a real markdown parser with an AST linked to
source positions), rewrite verify-md-wrap to parse each file with
mdast-util-from-markdown (the CommonMark parser behind remark) + the GFM
extension, then flag any `paragraph` node whose source span covers more
than one line.
Why a parser over the hand-rolled line scanner:
- It is a checker, not a formatter — it reports and never rewrites, so
zero cosmetic churn (no emphasis-marker or table-delimiter
normalization, which is why Prettier was rejected for this).
- The AST owns every structural exemption (fenced code of any fence
length, tables, lists, blockquotes, HTML, headings, reference defs),
fixing both bugs the regex version had: it now catches wrapped
list-item / blockquote prose (a `paragraph` inside those nodes) and no
longer false-positives on a longer ```` fence wrapping an inner ```.
Also unwrap two pre-existing hard-wrapped blockquotes (architecture.md,
adding-a-tool.md) that the stricter AST check correctly surfaced.
Implements the RFC 010 MVP: a new `@deepseek-ai/dsh-acp` package bridges the
harness agent to the Agent Client Protocol (JSON-RPC 2.0 over newline-delimited
stdio), so Zed and other ACP editors can drive the coding agent — streaming
render, tool-call display, and resumable sessions via `session/load`.
- packages/acp: AgentSideConnection wiring; initialize/newSession/loadSession/
prompt/cancel; a total TurnEndReason→StopReason codec; settle-once with a
fallback chain (agent/turn-end → logged turn/end → idle); single-session
guard; cwd-must-equal-launch-dir validation; load replays from the persisted
event log (assistant/chunk→agent_message_chunk, tool/call/result→tool_call*).
- agent: add Agent.whenIdle() quiescence signal to the interface; LoopAgent
implements it (resolves on the first running→idle/disposed transition). The
bridge awaits it on disposal so teardown reaches quiescence, not just abort.
- examples: extract the shared provider/tool core into examples/base.yml;
coding-agent nest-includes it; new examples/acp-agent serves the agent over
ACP with JSONL persistence and no stdout logger (stdout is the protocol).
- Permission gate deferred (TODO(rfc010-permission-gate)): tools run with the
executor's full authority; only the Agent→sessionId ownership seam is laid
down. Cancel is best-effort for a not-yet-started queued turn
(TODO(rfc010-cancel-prestep)). RFC 010 stays `proposed`.
- Docs: package README + Zed snippet; client-driver cookbook section; root and
packages layout/commands; RFC 010 implementation-status note.
48 bridge tests + whenIdle coverage; 100% per-file coverage; e2e boots the
example as a subprocess and verifies a written file on disk (key-gated, with a
no-key stdout-purity check).
Two tsx CI gates make doc/code drift fail fast:
- doc-typecheck extracts every fenced ts block from README/docs/package READMEs,
compiles them with tsc --noEmit against a temp project (vendor->lib, harness->src
paths from tsconfig.typecheck.json), and fails on errors. Deliberate sketches opt
out with ```ts ignore-check; the opt-out ratio is reported and capped.
- verify-event-taxonomy asserts the docs/architecture.md taxonomy table names
exactly the events declared in the interface Events blocks. This surfaced three
events the table had been missing (tools/change, llm/adapter-change,
system-prompt/change), now added.
Doc snippets made compilable with stub imports/declares (1 genuine sketch ignored).
Wired into CI after typecheck. API reports (RFC 006 pt 3) deferred. Graduates RFC
006 pts 1-2 -> ADR 0014.
- enum membership now checked uniformly for all SchemaTypes, mirroring the
converter which emits `enum` regardless of type (was string-only)
- checkValue switch ends in assertNever per the closed-union convention
- sync the adding-a-tool cookbook to the validate-for-you behavior
- soften ADR 0011's property-test claim (RFC 001 not yet landed)
- AGENTS.md Commands: fix typecheck/build descriptions; add lint, lint:fix,
test:coverage, knip, publint, hygiene (were undocumented).
- Drop the bare `yarn demo` for explicit `demo:echo` + `demo:coding`; update
README, examples READMEs (and document coding-agent in examples/README).
- New cookbook guide: adding-a-vendored-package.md (the missing "add" half of
vendor/README's update-only procedure).
- architecture.md: add a table-of-contents and extract the Extension cookbook
to docs/cookbook/extension-cookbook.md (link-preserving); drop the completed
"restructure this document" TODO.
- ADR 0009 (capability seams) + 0010 (twin LLM adapters), and a "when to write
an ADR" standard in adr/README.
- Add a committed dsh-code-review skill under .agents/skills, exposed to Claude
Code via a tracked .claude/skills symlink (gitignore carve-out).
Hard line breaks mid-paragraph make docs harder to edit and diff — a
one-word change reflows and re-diffs the whole paragraph. Reflow all
tracked non-vendor Markdown (plus vendor/AGENTS.md) so each prose
paragraph is a single line; soft-wrapping is the editor's job. Fenced
code, tables, and list structure are preserved (wrapped list items fold
to one line per bullet). Documents the convention in AGENTS.md.
The first real agent wiring: DeepSeek V4 + the bash tool suite + stdio
chat + JSONL persistence, runnable via yarn demo:coding (reads the
gitignored repo-root .env through process.loadEnvFile).
- examples/coding-agent: cordis.yml wiring both real plugin families
(llm-deepseek with !!js env secrets; bash-local + tool-bash), a
bash-only coding system prompt, a max-steps-guard plugin (bounds
runaway turns via the agent/turn-continuation waterfall — abort()
from step-end is a no-op by then), and a stdio UI with dimmed
reasoning and exit-on-idle for piped stdin.
- e2e (yarn test:e2e, key-gated): full-loop.e2e.ts runs a real model
against the real bash tool; coding-task.e2e.ts is the swebench-style
smoke — the model fixes a buggy add.js in a temp dir and the test
re-runs node add.test.js itself rather than trusting the agent.
- docs/cookbook: adding-a-package (the verified checklist),
adding-a-tool (execute() contract, background pattern, seams),
adding-an-llm-adapter (protocol obligations, mock-server testing,
e2e policy). AGENTS.md layout/commands/secrets sections updated;
architecture.md points at both examples and the cookbook.
- vitest.e2e.config.ts: serialize test files + retry twice — parallel
e2e files trip the shared internal key's concurrency quota.
- fix: the !js YAML tag spelling in docs/JSDoc is actually !!js
(js-yaml resolves custom tags under tag:yaml.org,2002:js).