Commit Graph

928 Commits

Author SHA1 Message Date
Tianyi Cui
7c400e9c02 docs: unify ADR/RFC trees into one lifecycle-organized RFC tree
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.
2026-06-18 02:18:24 +08:00
Tianyi Cui
9a30c46d63 Merge pull request #51 from deepseek-ai/worktree-improve-dsh-code-review-skill
docs(dsh-code-review): frame skill as guidance, not authority
2026-06-18 01:30:49 +08:00
Tianyi Cui
c58bbf22eb docs(dsh-code-review): add doc-sync + module-graph to hard-blocker gate list
Codex round 2 caught that the quality-gates hard blocker omitted the
documented doc-sync gate (and module-graph freshness), so a docs-specific
gate failure could be read as outside the blocking checklist. Add both, and
note doc-sync's coverage so the manual prose-drift check (#1) reads as
additional to it, not a duplicate.
2026-06-18 01:14:10 +08:00
Tianyi Cui
5f6ccf91ec docs(dsh-code-review): scope judgment so documented blockers stay authoritative
Codex adversarial review flagged that "guidance not authority" over-rotated:
it could be read as licensing a reviewer to waive genuinely-blocking checks
(HMR-safety test, doc-sync, ADR 0007 gates), and the "Where to look first"
section claimed to list things "not in the docs" while its first two items
ARE documented requirements.

Fix both: scope independent judgment to *what to look at* and *how to apply a
rule*, not whether documented requirements hold; state AGENTS.md /
packages/AGENTS.md / ADR 0007 stay authoritative. Split the checks into "Hard
blockers (documented requirements)" and "Reviewer-only checks (judgment
required)", so doc-sync/HMR-safety/gates aren't mixed with reviewer-only
heuristics. Keep the independent/broad-reasoning intent.
2026-06-18 01:09:58 +08:00
Tianyi Cui
5c0f24d59a Merge pull request #37 from deepseek-ai/feat/acp-1-max-tokens-turn-end
feat(agent-loop): surface max-tokens as a distinct turn-end reason
2026-06-18 01:02:55 +08:00
Tianyi Cui
1ad4615fab docs(dsh-code-review): frame skill as guidance, emphasize independent broad reasoning
The skill read like an authoritative checklist; clearing its items could be
mistaken for a complete review. Reframe it explicitly as guidance — a
where-to-look map that lowers startup cost, not a definition of a sufficient
review. Add a "How to think about a review" section drawing on the patterns
from the /code-review, /review, requesting-code-review, and
receiving-code-review skills: reason from the code independently, sweep all
aspects (correctness, concurrency, security, design/approach, tests, docs,
…), verify before flagging, calibrate confidence and suppress noise, and lead
with severity. Add a receiving-review note so authors evaluate findings on
merit rather than following them blindly.
2026-06-18 00:56:06 +08:00
Tianyi Cui
0b036d808c test: cover new defensive branches 2026-06-17 21:31:54 +08:00
Tianyi Cui
7a5886da2d docs(rfc): record follow-up cleanup seams 2026-06-17 21:26:57 +08:00
Tianyi Cui
513e16f9dc fix(dev): make hooks and bash seams safer 2026-06-17 21:26:44 +08:00
Tianyi Cui
b920239389 fix(acp): align prompt and workspace contracts 2026-06-17 21:26:31 +08:00
Tianyi Cui
2b36620e55 fix(persistence): tighten crash repair and dispose semantics 2026-06-17 21:26:21 +08:00
Tianyi Cui
87df09e3c3 fix(tools): isolate tool schemas and waterfall failures 2026-06-17 21:26:12 +08:00
Tianyi Cui
922e2f913e fix(llm-pi-ai): preserve harness adapter contract 2026-06-17 21:25:56 +08:00
Tianyi Cui
6fdd048123 fix(agent-loop): harden lifecycle edge cases 2026-06-17 21:25:47 +08:00
Hypatia May
c5a1c494e7 feature(session): session surface 2026-06-17 19:25:29 +08:00
Tianyi Cui
f860474f8b Merge branch 'feat/acp-3-multi-session' into feat/acp-4-session-cwd 2026-06-17 15:27:16 +08:00
Tianyi Cui
ff82254fca Merge branch 'feat/acp-2-bridge' into feat/acp-3-multi-session 2026-06-17 15:24:09 +08:00
Tianyi Cui
a9d5a5ba68 Merge branch 'feat/acp-1-max-tokens-turn-end' into feat/acp-2-bridge 2026-06-17 15:20:36 +08:00
Tianyi Cui
977c23d31f Merge remote-tracking branch 'origin/master' into feat/acp-1-max-tokens-turn-end
# Conflicts:
#	AGENTS.md
2026-06-17 15:16:26 +08:00
Tianyi Cui
df8db218a9 Merge pull request #35 from deepseek-ai/split/session-persistence-sqlite
feat(session-persistence-sqlite): second backend validating the abstraction (split 5/5)
2026-06-17 15:11:57 +08:00
Tianyi Cui
d8e009d63e Merge remote-tracking branch 'origin/master' into split/session-persistence-sqlite 2026-06-17 15:08:54 +08:00
Tianyi Cui
1d1ce8143c Merge pull request #34 from deepseek-ai/split/agent-factory
feat(agent): create/resume factory seam (split 4/5)
2026-06-17 15:07:14 +08:00
Tianyi Cui
c870c8fcb1 Merge remote-tracking branch 'origin/split/agent-factory' into split/session-persistence-sqlite 2026-06-17 15:05:30 +08:00
Tianyi Cui
cae1517407 Merge remote-tracking branch 'origin/master' into split/agent-factory 2026-06-17 15:03:51 +08:00
Tianyi Cui
edd6eb28dd Merge pull request #33 from deepseek-ai/split/session-persistence
feat(session-persistence): abstract seam + JSONL backend + wiring (split 3/5)
2026-06-17 15:01:52 +08:00
Tianyi Cui
36d3e1def4 Merge pull request #44 from deepseek-ai/worktree-md-wrap-guard
feat: merge-commit policy + markdown hard-wrap gate
2026-06-17 11:00:14 +08:00
Tianyi Cui
f3906af225 feat(acp): honor per-session cwd — run each ACP session in its own workspace
Lifts the RFC 010 § Deferred restriction that the server had to launch in the
workspace ("cwd must equal the launch directory"). An editor can now open any
project folder, and N concurrent sessions over one connection can each target a
different directory.

- packages/acp: drop the `cwd === process.cwd()` guard in validateWorkspaceParams
  (keep "must be absolute" — the cwd becomes the session header / bash workdir),
  and drop the persisted-cwd-vs-launch-dir check in session/load (a resumed
  session keeps its original header.cwd, so its bash tools run in its workspace).
- packages/tool-bash: the missing link — default the bash workdir to the calling
  agent's session cwd (`exec.agent.session.header.cwd`) via a new resolveWorkdir
  helper. An explicit model `workdir` still wins; a relative one resolves against
  the session cwd. This is the only correct spot for multi-session: N sessions
  share one ctx.bash executor, so the workdir must come per-call from exec.agent,
  not executor config. Falls back to the executor default when no session cwd is
  available (preserves non-ACP behavior).
- Trust: the cwd originates from the ACP client (the user's editor) at
  session/new — same trust level as the old launch dir; no new untrusted-input
  path. `additionalDirectories` (scope widening / sandbox) stays rejected.
- Tests: bridge accepts any absolute cwd + records it on the header; session/load
  honors the persisted cwd; bash defaults to / resolves relative against the
  session cwd; two sessions with different cwds each run bash in their own dir;
  non-absolute cwd still rejected. 100% per-file coverage maintained.
- Docs: RFC 010 status + § Deferred cwd bullet marked RESOLVED; acp README adds a
  Per-session cwd section; tool-bash + example READMEs and e2e comments updated.
2026-06-17 10:53:40 +08:00
Tianyi Cui
ffc107aa57 docs: record verify-md-wrap in the doc-sync source-of-truth docs
Adding verify-md-wrap to the shared doc-sync gate left its defining docs
stale (Codex review):
- ADR 0014 described doc-sync as two gates; add a dated amendment for the
  third (verify-md-wrap) and drop the "two checkable classes" wording.
- CI step label/comment said "doc code blocks + event taxonomy"; include
  the markdown wrap check.
2026-06-17 10:50:58 +08:00
Tianyi Cui
e31e19d99b docs: remove duplicate AGENTS.md convention bullets
The origin/master merge resolution accidentally duplicated the
"Symmetry" and "Tests" Conventions bullets. Collapse each back to a
single copy.
2026-06-17 10:05:07 +08:00
Tianyi Cui
dbaef018cc Merge remote-tracking branch 'origin/split/agent-factory' into split/session-persistence-sqlite
# Conflicts:
#	docs/adr/0018-session-persistence.md
2026-06-16 23:53:54 +08:00
Tianyi Cui
d3c9f6ca1e Merge remote-tracking branch 'origin/split/session-persistence' into split/agent-factory 2026-06-16 23:51:16 +08:00
Tianyi Cui
2bae18f811 fix(session): synthesize tool results for interrupted tool calls on crash recovery (review #33)
The loop logs the assistant/message (carrying tool-call blocks) BEFORE running
the tools, so a crash mid-tool leaves durable tool calls with no matching
tool/result. interruptedTurnClosers only added step/end + turn/end, so a resumed
session's deriveMessages() replayed a dangling assistant tool-call — which every
provider rejects as an invalid transcript on the next request.

interruptedTurnClosers now scans the interrupted turn for tool-call blocks
without a matching tool/result and synthesizes an error tool/result for each
(before the step/end), so the rehydrated history is a valid transcript. Adds a
dedicated repair.spec.ts and a shared-contract case proving both backends pair
every orphaned call with a result. Docs (ADR 0018, both persistence READMEs,
load() JSDoc) updated.

Also fixes the echo-agent README session-cleanup path: demo:echo runs from the
repo root, so sessions land in <repo-root>/.sessions/_no-cwd/, not
examples/echo-agent/.sessions/ (review #33).
2026-06-16 23:50:52 +08:00
Tianyi Cui
5e3df1b2f5 Merge branch 'feat/acp-2-bridge' into feat/acp-3-multi-session 2026-06-16 23:44:27 +08:00
Tianyi Cui
c2f8af30da Merge branch 'feat/acp-1-max-tokens-turn-end' into feat/acp-2-bridge
# Conflicts:
#	AGENTS.md
#	docs/cookbook/extension-cookbook.md
#	yarn.lock
2026-06-16 23:40:23 +08:00
Tianyi Cui
840dfbab84 Merge remote-tracking branch 'origin/master' into worktree-md-wrap-guard
# Conflicts:
#	AGENTS.md
2026-06-16 23:38:58 +08:00
Tianyi Cui
63425a2b87 refactor: detect md hard-wraps via mdast AST, not regex
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.
2026-06-16 23:35:33 +08:00
Tianyi Cui
ddf121320b Merge remote-tracking branch 'origin/split/session-persistence-sqlite' into feat/acp-1-max-tokens-turn-end
# Conflicts:
#	packages/session/src/types.ts
2026-06-16 23:31:14 +08:00
Tianyi Cui
973399e03c Merge pull request #45 from deepseek-ai/worktree-docs+todo-markers
docs(development): document FIXME/TODO/XXX markers
2026-06-16 23:21:37 +08:00
Tianyi Cui
9fb12740c7 Merge remote-tracking branch 'origin/split/agent-factory' into split/session-persistence-sqlite 2026-06-16 23:20:29 +08:00
Tianyi Cui
16e7bbc7c6 Merge remote-tracking branch 'origin/split/session-persistence' into split/agent-factory 2026-06-16 23:19:34 +08:00
Tianyi Cui
16e75c2631 Merge remote-tracking branch 'origin/master' into split/session-persistence 2026-06-16 23:18:06 +08:00
Tianyi Cui
c2dc63f2ea Merge pull request #46 from deepseek-ai/split/turn-enclosure
feat(agent-loop): turn-enclosure invariant + post-turn error model (split 2/5, re-land)
2026-06-16 23:16:13 +08:00
Tianyi Cui
53b37b39c5 docs: point AGENTS.md to development.md for TODO marker semantics 2026-06-16 23:02:48 +08:00
Tianyi Cui
ce4b32ace9 feat(session-persistence-sqlite): preserve interrupted turns on load, don't truncate
Mirror the JSONL backend's crash-recovery contract change: load() now PRESERVES
the real events of an interrupted final turn (a turn can be huge — truncating it
would destroy work) and durably CLOSES the orphaned turn with synthetic boundary
events (step/end if open, then turn/end {interrupted}) inside one transaction
that also deletes any torn tail row. load() is therefore mutating; the deferred
truncation-repair on the next append is gone. Replaces cutAtLastTurnEnd with
scanRows (longest preserved prefix + torn-tail offset). Updates the sqlite tests
and README to the preserve-and-close semantics; the shared runPersistenceContract
suite now holds both backends to identical interrupted-turn behavior.
2026-06-16 22:56:17 +08:00
Tianyi Cui
326b026ab3 docs(development): document FIXME/TODO/XXX markers
Define the three issue-urgency tags so contributors can flag a release
blocker, a soon-to-fix item, and a someday-maybe consistently.
2026-06-16 22:45:19 +08:00
Tianyi Cui
f0d9383f49 Merge branch 'split/agent-factory' into split/session-persistence-sqlite
# Conflicts:
#	docs/adr/0018-session-persistence.md
#	docs/architecture.md
2026-06-16 22:32:49 +08:00
Tianyi Cui
0000cdb2c2 feat(agent-loop): config-driven session resume via RESUME_SESSION_ID
A config agent with `resumeSessionId` set continues a persisted session
instead of starting a fresh `${id}-session-<uuid>`. The id is sourced from
an env var in cordis.yml, so the coding-agent demo can resume a prior
conversation without code changes. The resume is deferred until the
`sessionPersistence` backend loads (via ctx.inject) and is contained: a
missing/unreadable id logs a warning and starts no agent. Adds a real-API
resume e2e proving cross-process continuity through the JSONL backend.
2026-06-16 22:28:01 +08:00
Tianyi Cui
8511b9639c Merge branch 'split/session-persistence' into split/agent-factory
# Conflicts:
#	docs/adr/0017-turn-enclosure-invariant.md
#	docs/architecture.md
2026-06-16 22:27:51 +08:00
Tianyi Cui
67447fcdc3 feat: enforce merge-commit policy and markdown wrap convention
- AGENTS.md: require merging PRs with a merge commit (gh pr merge
  --merge), never squash/rebase — the per-PR commit history (review-fix
  and regression-test commits) is intentional record.
- Add scripts/verify-md-wrap.ts: a doc-sync gate that fails on
  hard-wrapped prose paragraphs (one physical line per paragraph), with
  smart exemptions for fenced code, tables, lists, blockquotes, headings,
  HTML comments, hrs, and reference defs. Scope covers README.md,
  docs/**/*.md, packages/*/README.md, plus AGENTS.md / packages/AGENTS.md
  (the files doc-sync did not previously cover). Folded into doc-sync so
  it rides the existing pre-push and CI gates.
- Sync AGENTS.md and docs/development.md doc-sync descriptions and
  command lists to include verify-md-wrap.
2026-06-16 22:14:25 +08:00
Tianyi Cui
19518ebfd9 Merge pull request #43 from deepseek-ai/worktree-module-graph
feat: generated module dependency graph with freshness gate
2026-06-16 22:03:17 +08:00