Commit Graph
400 Commits
Author SHA1 Message Date
Tianyi Cui c073a3bd61 Merge remote-tracking branch 'origin/master' into worktree-docs-overhaul-b-agents 2026-07-04 17:57:16 +08:00
Tianyi Cui b3e3157ccb Merge pull request #142 from deepseek-harness/worktree-docs-overhaul-a-standard
Documentation tiers, budgets, and the ceiling gate
2026-07-04 17:56:56 +08:00
Tianyi Cui d6f280c19b Merge branch 'worktree-docs-overhaul-a-standard' into worktree-docs-overhaul-b-agents
# Conflicts:
#	docs/AGENTS.md
#	docs/rfc/implemented/process/2026-07-04-doc-tiers-and-budgets.md
#	scripts/doc-budgets.manifest.json
2026-07-04 17:23:16 +08:00
Tianyi Cui cada16c701 docs(budgets): ceilings carry at least 5% working headroom
Exact-size ceilings turned every two-word wording fix into a gate
event. The policy amends to: a ceiling sits at least 5% above the
doc's current size (pre-rewrite) and keeps that margin when ratcheted
to target — routine edits pass, real growth still trips the gate.
Amended together in all four policy homes (docs/AGENTS.md § Budgets,
the doc-tiers RFC, the gate script's module comment, the skill's
ratchet rule) plus the manifest values, so prose and mechanics stay
consistent.
2026-07-04 17:20:18 +08:00
Tianyi Cui 64ba09fda6 fix(docs): address ds-review-bot — the e2e tier is not DeepSeek-only
docs/testing.md's real-API tier bullet now names the provider-specific
key gating (EXA_API_KEY, PERPLEXITY_API_KEY, ...): each suite
self-skips on its own key, so a DEEPSEEK_API_KEY-only run has not
exercised the provider smokes.
2026-07-04 16:43:23 +08:00
Tianyi Cui e5120d2193 fix(docs): address Codex review round 3 — last three moved-policy citations
vitest.config.ts coverage comments (excessive-tests welcome -> docs/testing.md;
v8-ignore reason rule -> the quality-gates RFC) and the acp bridge.spec
resource-ownership comment -> docs/testing.md. Postmortem 0001's summary now
names packages/AGENTS.md as the export-shape rule's home. Repo-wide sweep from
the root (all file types, vendor/lib excluded) shows every remaining AGENTS.md
citation resolves to a rule that exists where cited.
2026-07-04 16:02:39 +08:00
Tianyi Cui 26339144e3 fix(docs): address Codex review round 2 — repoint every remaining moved-policy citation
The definitive sweep (audit every AGENTS.md mention in packages/, docs/,
examples/, scripts/) found thirteen more citations of relocated policy
and two citations of rules that never existed as quoted:

- with-key policy comments (web deepseek/perplexity e2e headers) ->
  docs/testing.md; real-impl-over-mock comments (acp harness, load,
  stream-update specs) -> docs/testing.md; defensive-pattern quotes
  (acp index.ts x3, stream-update) -> docs/defensive-patterns.md.
- md-tier repoints: real-api-e2e RFC, tool-schema-catalog RFC,
  postmortem 0001 guardrail row, adding-a-package cookbook,
  drop-bash-output-spill-files RFC, acp-subagent-backend RFC phrasing.
- Two false attributions dropped in favor of self-contained reasoning:
  tool-todo's 'don't validate scenarios that can't happen' and the
  bash-stdin-env RFC's 'Don't add features beyond what the task
  requires' (neither rule ever existed under those names).
- Citations of the two 'not golden truth' doctrines stay: those bullets
  survive verbatim in the root conventions.

Note: packages/support/ui-stdio readline TTY spec flakes under full
coverage on a heavily loaded box (passes standalone and passed the
same tree's coverage run minutes earlier); untouched by this stack.
2026-07-04 15:43:51 +08:00
Tianyi Cui c3424e5487 fix(docs): address Codex review round 1 on the AGENTS.md rewrite
- Restore the universal JSDoc rule the rewrite dropped (module doc
  comment + semantic JSDoc on every export), in root AGENTS.md § Type
  safety and documentation — the generated-catalog RFC cites it as the
  rule the generator enforces at the source.
- Repoint the six remaining citations of moved content that the
  section-name grep missed (rule-title quotes and prose references):
  agent-loop agent.ts, acp index.ts, acp turns.spec.ts, the Exa e2e
  header, the real-api-e2e RFC, the doc-sync-enforcement RFC amendment,
  and rfc/implemented/AGENTS.md's section-name casing.
- Fix two docs/testing.md overstatements: the unit tier also runs
  examples/*/tests specs, and keyless-by-nature examples have no
  with-key smoke.
- Displacement trims keep root AGENTS.md at 1,498/1,500.
2026-07-04 15:11:49 +08:00
Tianyi Cui 7702a33531 docs(AGENTS): rewrite the root standing orders to the 1,500-word budget
Applies the documentation standard to its biggest offender. Every rule
survives as one to three lines plus a link to its durable home; the
stories, duplicate statements, and re-narrations go:

- Situational clusters evict to new homes: docs/testing.md (tiers,
  with-key policy, real-over-mock, world-verification, real-entry-path
  guards), docs/defensive-patterns.md (the bug-class rules), and
  docs/cookbook/responding-to-pr-review-on-a-stack.md (the stacked-PR
  review procedure).
- Doc-authoring rules consolidate into docs/AGENTS.md § Writing rules
  (current-state-never-history, md-wrap, ts-block compilation, @mode,
  catalog same-change, pair same-change).
- packages/README.md drops to the group table + the extension-vs-bundle
  dependency rule; the hand ASCII graph yields to the generated
  module-graph.md; group READMEs are the canonical per-package map.
- packages/AGENTS.md keeps only its packages-specific rules (export
  shape, ctx.get, real-Loader coverage); examples/AGENTS.md repoints
  its with-key-policy link; rfc/README.md loses a narrated-history
  aside; dsh-code-review / dsh-find-simplifications / verify-md-wrap
  references follow the moved content.
- Budget manifest ratchets: AGENTS.md 8200 -> 1500 (now 1,495 words),
  packages/README.md 1900 -> 600, packages/AGENTS.md 600 -> 450; the
  two new eviction docs join the budget set (testing 800, defensive
  550); docs/AGENTS.md raises 1000 -> 1250 for the absorbed writing
  rules (the one justified increase). The doc-tiers RFC's deferred list
  prunes the two items this change ships.
2026-07-04 14:22:47 +08:00
Tianyi Cui fa139c88b7 docs(rfc): reject prune-unimplemented-subagent-vocabulary — reserved surface
Maintainer decision: the subagent seam's deferred capability vocabulary
(outputSchema/structured, toolFilter, sendMessage/resume) is
intentionally reserved — the seam advertises the full intended contract
ahead of its implementations so providers and consumers grow into a
stable shape. Moved to rejected/ with the rationale on the status line;
the consumer-evidence analysis stays as the record of what is currently
unimplemented.
2026-07-04 14:06:26 +08:00
Tianyi Cui aa36b3b36b feat(doc-standards): documentation tiers, budgets, and the ceiling gate
Standing docs accrete a paragraph per PR with nothing pushing back; the
root AGENTS.md reached 8,130 words in 50 commits with the same rule
stated two and three times. This encodes the counter-pressure:

- docs/AGENTS.md becomes the documentation standard: the tier taxonomy
  (one home per fact), target word budgets, and the slop checklist.
- verify-doc-budgets joins doc-sync: word ceilings for the six
  accretion-prone standing docs, manifest-driven, frozen at current
  sizes and ratcheted down as each doc is brought to target.
- .agents/skills/dsh-doc-standards: the thin placement/audit/red-gate
  workflow over the standard, mirroring the dsh-translate-docs split.
- RFC (implemented/process) records the decision, alternatives, and
  the first audit cycle's deferred work list.

The gate's first catch was the standard itself (1,057 > 1,000); it
ships condensed to 984 words rather than with a raised ceiling.
2026-07-04 13:53:43 +08:00
Tianyi Cui 3395d463fd docs(rfc): fix fold-round review findings — reference census scope, test-caller wording
The fold-stdio RFC claimed the two e2e doc comments and packages/README
were the only non-runtime references; the package name also appears in
the generated module graph, sibling READMEs, and tsconfig references —
rescope the sentence to the runtime-importer census (the load-bearing
claim) and fold the mechanical references into the update list. The web
RFC's status-caller census now says 'the web packages' own tests'
(the seam's tests use the methods too, not only provider tests).
2026-07-04 13:13:03 +08:00
Tianyi Cui 09f131f78e docs(rfc): fold PR #139's simplification sweep into this set
Deduplicate the parallel sweep from codex/exhaustive-simplification-rfcs
(merged in the parent commit) against the twelve RFCs already here, on
the merits per item:

Ported (rewritten to this set's evidence standard):
- fold-stdio-ui-helper — verified: dsh-stdio-agent is the only runtime
  importer; the fold resolves the documented product-app-depends-on-
  support-package tension. The false acp-agent analogy is replaced with
  the real distinction (protocol product surface vs one app's front-door
  scaffolding).
- generate-rfc-index-tables — verified: the classification RFC records
  rejecting generation; the index tables are the repo's only
  systematically conflicting docs region. Process framing made timeless.

Consolidated into existing owners:
- web searchStatus()/fetchStatus()/WebCapabilityStatus (verified: zero
  production callers; the tool-web README and architecture.md claims are
  drift) → drop-web-providers-change-event, renamed
  drop-unconsumed-web-observation-surface.
- hook/result.durationMs (unread, nondeterministic, normalizer-scrubbed)
  and the double-defaulted defaultTimeoutMs knob →
  tighten-hook-protocol-contract.
- the exercised-but-unadvertised exec.arguments mutation path (a
  tool-bash integration shim rewrites through it) → a sanction-or-seal
  note in the pre-tool-input-rewrite proposal.
- the dormant-guard critique of subagent depth machinery → recorded in
  prune-unimplemented-subagent-vocabulary as the considered-and-rejected
  alternative, with the keep sharpened (uncapped-today acknowledged;
  wiring the cap is the completion, not deletion). getProvider()/list()
  and lastAssistantMessage recorded as examined-and-kept (bash-revert
  precedent; observe-enrich recorded keep).

Not ported (with reasons):
- tools/change + system-prompt/change removal — recorded keeps in the
  adapter-change RFC, unengaged by the sweep; no new facts.
- LlmService.models() — flagged by both surveys, but two lines with a
  plausible consumer: TODO-or-drive-by territory per the RFC bar, not
  a proposal.
- SchemaProp.default RFC — already XXX(unused-default)-tagged; the RFC
  bar excludes TODO-tracked provisional cleanups.
- PreToolDecision 'ask' removal — FIXME(permissions)-anchored deferral
  with the permission system as its named consumer.
- Codex bridge Config.model, merged systemMessages — wire-faithful
  tested surface / README-documented deferral.

Their in-code TODO notes (acp-test-harness, hook-snapshot-noise,
catalog-type-links) and the stale hook-prompt-block name fixes ride the
merge unchanged.
2026-07-04 12:53:21 +08:00
Tianyi Cui 768876284c Merge remote-tracking branch 'origin/codex/exhaustive-simplification-rfcs' into worktree-simplification-rfcs-0704
# Conflicts:
#	docs/rfc/README.md
2026-07-04 12:43:12 +08:00
Tianyi Cui e6418398ff docs(rfc): address Codex round findings — timeless framing + narrowed fs acceptance
Rewrite the hook-protocol RFC's process-relative wording (freshly-landed
/ days-old / week-old) as timeless evidence anchored to the recorded
RFCs, and sweep the same class from the steering, replay-config,
subagent-vocabulary, and vocabulary RFCs. Narrow the fs RFC's acceptance
criterion: replaceAll survives on the request spec and version on other
outcome types by design — name the exact removed surfaces instead of
claiming the spellings vanish.
2026-07-04 11:47:12 +08:00
Tianyi Cui 9ebc38badf docs(rfc): revise the batch for the hooks-stack base; add three post-stack RFCs
The branch now bases on the hooks stack (PR #138's head), so every
'in-flight' reference to stack content became a current-state fact.
Audited all nine RFCs + three supplements claim-by-claim against the
merged tree (none invalidated; several strengthened):

- prune-dead-core-spine-surface: describe the landed tools/pre-execute →
  dispatch → tools/post-execute pipeline — listeners return Decisions,
  the registry builds every result and snapshots it to protect callId,
  and a second (mutation-guard) test pins the field; drop the resolved
  wait-for-interception hedge; scope the additionalContext ferry out.
- prune-producerless-vocabulary-variants: the ui-stdio fixture migrated
  off the continuation trigger (llm-replay is the sole writer now); the
  stack's own additions (rejected, prompt/blocked, hook/invoked+result)
  all arrived with producers — the admission policy demonstrated live.
- prune-unimplemented-subagent-vocabulary: enrichment landed as
  lastAssistantMessage only (agentType was dropped in the stack's own
  review — the same judgment this RFC extends); the seam RFC now names
  tools/pre-execute deny, which exists, sharpening the re-add path.
- drop-inert-request-knobs / drop-image-content-block /
  trim-acp-bridge-unreachable-surface: current-state rewordings (shipped
  bridges set no request fields; only compact-basic has explicit image
  arms; 13 hook goldens also pin agentInfo).
- generic-long-running-tool-runtime census: second production seam
  consumer (hook-protocol runHook: resolve+run, stdin/env, foreground
  only — background machinery stays single-consumer); scrub-duplication
  blast radius.
- discover-package-inventory: identical 54-entry tsconfig reference
  sets; the comparesLog scenario knob (fixture-derivable, like recorded).
- unify-agent-and-session-id: third divergence site (in-process subagent
  children mint two UUIDs), the hooks bridge id-lookups, and ui-stdio's
  labelBySession map as a consumer that deletes under unification.

New RFCs from the post-stack survey:
- remove-agent-steering-mirror: the last mirror-of-durable event; zero
  production listeners; both retention RFCs deferred its fate, and the
  'no durable twin' rationale is contradicted by the adjacent append.
- tighten-hook-protocol-contract: producer-less 'native' dialect,
  parsed-and-discarded suppressOutput, and hook/result semantics
  (truncation + decision-string) defined twice in the bridges instead
  of the lib that owns the event.
- single-source-acp-replay-config: cordis.yml/cordis.snapshot.yml differ
  by exactly one plugin entry, with no gate on the forced symmetry.
2026-07-04 11:24:44 +08:00
Tianyi Cui 95b9ac0d3e docs: refresh simplification RFC sweep 2026-07-04 11:04:49 +08:00
Tianyi Cui 7774d427de Merge remote-tracking branch 'origin/worktree-hooks-i-snapshots' into worktree-simplification-rfcs-0704
# Conflicts:
#	docs/rfc/README.md
2026-07-04 10:50:58 +08:00
Tianyi Cui cf550f3feb Merge PR #138 into simplification RFC sweep
# Conflicts:
#	docs/rfc/README.md
2026-07-04 10:49:33 +08:00
Tianyi Cui f04b25478e docs(rfc): align acceptance criterion with corrected runLoop scope; two more image doc sites
The core-spine RFC's acceptance criterion still asserted all three
surfaces 'appear only in this RFC', contradicting the corrected scope
(runLoop/Inbox stay as package-internal symbols; only the public
re-exports go). Also add the deepseek README image-skip row and the
compact-basic [image]-placeholder row to the image RFC's removal set.
2026-07-04 04:33:06 +08:00
Tianyi Cui 9389c5df19 docs(rfc): address Codex review findings on the RFC batch
Two overstated evidence claims, reworded to the precise fact:
- prune-dead-core-spine-surface: runLoop has no importer OUTSIDE the
  package (its own agent.ts drives the loop with it); the dead surface
  is the public re-export, not the function.
- generic-long-running-tool-runtime census: BashTask.done has no
  consumer through the public seam, but is production-load-bearing
  inside dsh-bash-local (disposal awaits it); only the public
  completion surface is single-consumer.

Also fold the reviewer-located doc sites into the removal sets so the
implementing PRs need no re-discovery: the llm/pi-ai/compact-basic
README rows and the adding-an-llm-adapter cookbook line (prefill/image),
the content-block-vocabulary RFC's has-a-home consequence lines
(cache/prefill/image), the tools.md paste + type-equiv manifest row +
tools README row (callId), and the session-surface RFC's
full-rebuild-after-replacement sentence (invalidate).
2026-07-04 04:21:38 +08:00
Tianyi Cui 1546c6060a Merge branch 'worktree-hooks-h-retro' into worktree-hooks-i-snapshots 2026-07-04 03:31:31 +08:00
Tianyi Cui 81c27bed36 Merge branch 'worktree-hooks-f-bridges' into worktree-hooks-g-stream-chunk
# Conflicts:
#	docs/rfc/README.md
2026-07-04 03:21:00 +08:00
Tianyi Cui 38cd1a150c Merge branch 'worktree-hooks-e-protocol' into worktree-hooks-f-bridges
# Conflicts:
#	examples/acp-agent/cordis.snapshot.yml
#	examples/acp-agent/cordis.yml
2026-07-04 03:09:37 +08:00
Tianyi Cui 7d69d759f6 Merge branch 'worktree-hooks-d-subagent' into worktree-hooks-e-protocol
# Conflicts:
#	docs/module-graph.md
#	pnpm-lock.yaml
2026-07-04 03:01:22 +08:00
Tianyi Cui e13bbcb5d5 docs(rfc): propose nine simplification RFCs from a five-domain survey
Survey of master for surface area whose consumers are tests/docs only,
classified per candidate (production vs non-production corpus, rg + call-site
reads). New proposed/simplification RFCs:

- prune-producerless-vocabulary-variants: CacheHint/cache? fields,
  MessageSource 'agent', TurnTrigger 'continuation' (the TurnEndReasonMap
  omitted-until-emitted policy, applied)
- drop-inert-request-knobs: GenerateOptions.prefill (both adapters throw
  UNSUPPORTED), ToolSchema.strict (zero setters; beta-URL-only feature)
- drop-web-providers-change-event: the llm/adapter-change precedent replayed
- drop-image-content-block: no producer; every consumer silently drops it
- prune-write-only-fs-surface: fs-local STREAM_MIN_SIZE/streamMinSize,
  FsTarget.inputPath, FsEditOutcome.replacements/replaceAll,
  FileReadOutcome.limit/version
- prune-unimplemented-subagent-vocabulary: outputSchema/structured,
  toolFilter, sendMessage/resume (depthLimit stays)
- trim-acp-bridge-unreachable-surface: agentName/agentVersion knobs
  (resolves TODO(double-default)), toolKindFor name-sniffing
- prune-dead-core-spine-surface: SurfaceManager.invalidate(), runLoop/Inbox
  exports, ToolExecutionResult.callId
- share-app-bin-boot-glue: the twin coverage-exempt bin helpers

Also supplements three existing proposed RFCs with survey evidence: the bash
seam consumption census (generic-long-running-tool-runtime), three more
static inventories (discover-package-inventory), and the bridge's already-1:1
id usage (unify-agent-and-session-id).
2026-07-04 03:00:25 +08:00
Tianyi Cui 92be2724bd Merge branch 'worktree-hooks-c-interception' into worktree-hooks-d-subagent 2026-07-04 02:48:41 +08:00
Tianyi Cui 9033837081 Merge branch 'worktree-hooks-b-bash-seam' into worktree-hooks-c-interception
# Conflicts:
#	docs/architecture.md
#	docs/cordis-catalog/events-and-services.md
#	docs/core-data-structures/tools.md
#	packages/core/tools/README.md
#	packages/core/tools/src/index.ts
2026-07-04 02:44:26 +08:00
Tianyi Cui 955e8d2913 docs: propose simplification RFCs 2026-07-04 02:39:50 +08:00
Tianyi Cui 89f3c484c1 Merge branch 'worktree-hooks-a-taxonomy' into worktree-hooks-b-bash-seam
# Conflicts:
#	docs/rfc/README.md
2026-07-04 02:26:19 +08:00
Tianyi Cui c5ed5ff490 Merge remote-tracking branch 'origin/master' into worktree-hooks-a-taxonomy
# Conflicts:
#	docs/rfc/README.md
2026-07-04 02:15:52 +08:00
Tianyi Cui ecd5ca6ce6 Merge branch 'master' into codex/fs-directory-listing 2026-07-04 01:27:42 +08:00
Tianyi Cui 571f5b383a Merge branch 'master' into docs/update-readme-for-sdk 2026-07-04 01:20:27 +08:00
Tianyi Cui 51640362b5 docs: rename coding demo to repl 2026-07-04 01:07:26 +08:00
Tianyi Cui bf1966326e Merge remote-tracking branch 'origin/master' into codex/fs-directory-listing
# Conflicts:
#	docs/rfc/README.md
#	packages/fs/fs-local/src/index.ts
2026-07-04 00:56:17 +08:00
Tianyi Cui 74f61c89e3 test(hooks): snapshot the CC + Codex hook matrix end-to-end
Load both hook bridges in the ACP example (dsh-hooks-claude → ./hooks.json,
dsh-hooks-codex → ./codex-hooks.json) so the full-transcript snapshot tier can
exercise each dialect against the real app. An absent config file is a silent
no-op, so a scenario carries only the file it needs and the other bridge
vanishes — verified byte-identical against every pre-existing snapshot.

Add a scenario per hook point × its headline Decision outcome, both dialects:
UserPromptSubmit block (authored, keyless) + context-fold, PreToolUse deny/ask,
PostToolUse block/context, Stop force-continue. The mid-turn scenarios are
recorded against the real API with the hook active, so the model's reaction to
a denied/blocked/force-continued turn is part of the replayed transcript.

SessionStart and SubagentStart are deliberately excluded (detached best-effort
inject races the log position — a recorded golden fails 10/10 on its own
replay), as is SubagentStop (observe-only, zero transcript footprint — a golden
could never be proven to fail). Both stay on the bridges' unit coverage. See
docs/rfc/implemented/testing/2026-07-04-hook-snapshot-matrix.md.
2026-07-04 00:40:35 +08:00
Tianyi Cui fb78a844af docs(tools): fix cross-module JSDoc links and the catalog source list
Codex review of the vocabulary relocation found two doc-accuracy issues:

- presentation.ts's JSDoc used {@link ToolDefinition...}, which the
  TypeScript language service cannot resolve because presentation.ts
  deliberately does not import index.ts (that would create the cycle the
  split avoids). Demote those three to plain `ToolDefinition` code text;
  same-file and imported @links (TerminalResultView, ContentBlock) stay.
- docs/core-data-structures/tools.md's source header listed only index.ts
  and schema.ts; add presentation.ts, which now owns the presentation
  vocabulary the page documents.
2026-07-04 00:39:09 +08:00
Tianyi Cui 539051b2c9 refactor(tools): move render-intent vocabulary to presentation.ts
The tool render-intent vocabulary (ToolCallView/ToolResultView + members,
FileLocation, FileDiff, ToolCallKind) is the UI-facing surface of
dsh-tools; it lived inline in index.ts alongside the registry and
execution core. Move it to its own presentation.ts module so index.ts is
the registry + execute waterfall and the presentation vocabulary is a
separate, one-directional dependency.

presentation.ts owns ONLY render-intent types and references none of the
execution types; index.ts imports the view types for ToolDefinition's
presentCall/presentResult signatures (clean acyclic index -> presentation).
The opaque `meta` presentation channel (ToolExecuteReturn, ToolResult,
ToolExecutionResult) is execution plumbing and stays in index.ts.

Public surface unchanged: index.ts re-exports the vocabulary, so consumers
(tool-fs/tool-bash/tool-web/tool-todo, the ACP bridge) keep importing from
@deepseek-ai/dsh-tools with zero churn. No producer/bridge/test edits; a
pure internal relocation with no observable-output change (snapshot goldens
untouched).
2026-07-04 00:20:06 +08:00
Tianyi Cui 19db3aa28a Merge branch 'master' into docs/i18n-translate-skill 2026-07-03 23:50:53 +08:00
Tianyi Cui 497ea15bdf fix(acp): relativize the completed diff card title
The result-time diff card sent view.title raw, so a completed edit/write
of an absolute in-workspace path flipped the card header back from the
relativized `Edit src/b.ts` to the absolute path — the pending card
relativizes, the result did not, and tool_call_update.title replaces the
header. Apply displayTitle to the result diff arm using the diff path,
mirroring the call-side card. Regression test proven red on the unfixed
arm.

Also record the overwrite diff-basis pre-read as a bounded follow-up
(TODO(overwrite-diff-bound) + RFC non-goal): overwriting a large file
reads the whole prior text into memory for a UI-only diff.
2026-07-03 23:14:22 +08:00
Tianyi Cui 9c6e09c0d8 Merge remote-tracking branch 'origin/master' into fs-acp-applied-hunk-diffs 2026-07-03 22:57:09 +08:00
Ziya ec05295a0c docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).

- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
  remnants) so half-deleted pairs are caught from either side; red/green
  proven for en-only edit, zh-only edit, missing record, and a record
  for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
  indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
  (terminology table binds both directions; typography section governs
  the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
  in-file-fingerprint model as considered-and-revised; RFC translated
  (docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
  added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
  generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
Tianyi Cui 53ebf6fc54 Merge remote-tracking branch 'origin/master' into fs-acp-render-intent-union 2026-07-03 22:41:10 +08:00
Tianyi Cui e07886599c docs: finish the whole-file-diff sweep across comments and RFCs
Codex's stale-prose pass found seven more spots still describing the
result diff as ALWAYS an applied contextual hunk, or a create/binary
overwrite as rendering "only the call-time card": the DiffCallView JSDoc
and the acp bridge diff-arm comment, the FsWriteOutcome.before and
readTextForDiff JSDoc, and three RFC lines. All now say: the result diff
is the applied change — a contextual hunk when there is a before-image,
else a whole-file diff (create / undiffable binary) — and a successful
mutation always returns the result diff so the model-facing text can't
clobber it. Regenerate the cordis catalog (source line shift).
2026-07-03 21:50:52 +08:00
Tianyi Cui da1d7f281d docs(tools): DiffResultView.diffs may be a whole-file diff, not only hunks
The write-diff-card fix made write's presentResult return an args-derived
whole-file diff (oldText:null) for a create / unchanged overwrite, but the
DiffResultView contract and its mirrored docs still said `diffs` is ALWAYS
the applied contextual hunks computed from before/after. Correct the type
JSDoc, the write execute-side comment, and the four mirrored surfaces
(tools.md, tools README, acp-feature-support, adding-a-tool cookbook) to
say: typically the applied hunks, or a whole-file diff when there is no
before-image (a create) — and that a mutation returns the diff result even
when it duplicates the call-time card, since a tool_call_update.content
replace would otherwise clobber the diff with the model-facing text.
Regenerate the cordis catalog (source line shift).
2026-07-03 21:26:50 +08:00
Tianyi Cui 53b215c646 fix(tool-fs): write always renders a diff card on the completed update
A Write CREATE rendered its completed tool_call_update as the model-facing
result TEXT (`<path>…</path>…Created file`), which — because an ACP
tool_call_update.content REPLACES the call's content — clobbered the
new-file diff the pending call installed. So Zed showed the diff, then
replaced it with raw XML-ish text; only overwrite/edit looked right
(their result re-sends a diff).

write's presentResult now ALWAYS returns a diff card for a successful
write: the applied contextual hunk from `meta` when there is one
(overwrite), else an args-derived whole-file diff (`oldText: null`) for a
create or an unchanged-content overwrite. This matches claude-agent-acp,
where the create diff rides on the update and no result text replaces it.
An error still falls through to generic rendering so its message shows.
edit is unchanged (it always has a hunk; no whole-file fallback).

Re-recorded fs-write / fs-write-overwrite goldens; the create's completed
update is now a {type:'diff'} block, not the XML result text.
2026-07-03 20:52:36 +08:00
Tianyi Cui f0ae253670 Merge branch 'master' into codex/fs-directory-listing 2026-07-03 20:49:10 +08:00
Tianyi Cui f86e0bedec docs(tools): sync ToolExecutionResult.meta comment to unknown
The pasted type-equiv block's JSDoc still said the meta payload is
`{@link JsonValue}`; the source comment is `unknown` (the meta channel is
opaque at the seam). verify-type-equiv compares type structure, not the
comment, so the drift slipped through — align the doc comment.
2026-07-03 19:05:46 +08:00
Tianyi Cui dee2dee402 fix(tool-fs): CRLF-safe write diff, opaque meta, doc sync
Address the applied-hunk-diffs review:

- CRLF write overwrite emitted bogus every-line-changed hunks: write's
  `before` was LF-normalized but `after` kept the raw model content, so a
  CRLF rewrite of an LF file diffed every line. Normalize write's `after`
  to LF so both sides share the diff basis (edit already did). Regression
  test proves it fails on the raw-after path.
- The tool-private `meta` payload is now typed `unknown` (opaque) at every
  seam instead of `JsonValue`. This drops the `dsh-tools -> dsh-session`
  package edge that existed only to name the type, and removes the
  `FileDiff` index signature that had been widening the type solely for
  JsonValue-assignability. Serializability is still enforced at runtime by
  `Session.append`'s isJsonValue check, which was always the real guard.
- Sync the docs the new result/meta surface left stale: ToolResultView's
  diff card + ToolExecutionResult.meta in tools.md/session.md type-equiv
  blocks, the acp/tools READMEs, and the adding-a-tool cookbook; regenerate
  the cordis catalog and module graph.
2026-07-03 18:00:16 +08:00
Ziya bb10931478 docs: apply translation-review findings across the four zh files
A four-way parallel review of every EN<->ZH pair (one reviewer per pair,
findings verified before applying) surfaced:

- terminology: stale-sense 过期 -> 陈旧 in development.zh.md (the table
  reserves 过期 for expired); GitHub workflow -> GitHub 工作流 per the
  table; dropped the invented 质量 in 'CI gates' -> CI 门禁; taxonomy ->
  分类体系 in translation-rules.zh.md; skill first-occurrence annotation
  added in the i18n README
- verbatim spans: <current-blob> restored inside an inline code span the
  translation had localized
- typography: full-width dashes normalized to no surrounding spaces
  across all four files (the rules' own MUST); one 顿号 between clauses
  -> comma; 顿号 before 以及 dropped
- fidelity/wording: must-not rendered 不得 (not 不应); local setup ->
  本地环境搭建; enforce -> 强制执行; verified surface -> 受验证的范围;
  batch-lands-before-neighbors nuance restored; 更新粘贴内容
2026-07-03 02:53:08 -07:00