Commit Graph

6049 Commits

Author SHA1 Message Date
Tianyi Cui
a52c27ee07 Merge remote-tracking branch 'origin/master' into persistence-log-catalog
# Conflicts:
#	packages/hooks/hook-protocol/README.md
#	packages/hooks/hook-protocol/src/types.ts
2026-07-05 00:06:47 +08:00
Tianyi Cui
021dae58e2 Merge remote-tracking branch 'origin/master' into simpl-e-acp-trim
# Conflicts:
#	docs/rfc/README.md
2026-07-04 23:43:20 +08:00
Tianyi Cui
a23982b30a Regenerate catalog for post-merge line shifts; drop pruned continuation trigger from turn/start JSDoc
Merging master brought the producerless-vocabulary prune that removed
TurnTriggerMap's continuation variant: the source pointers above
SessionEventMap shifted by one line (the staleness CI caught on the
merge tree), and the new turn/start JSDoc still named the pruned
variant.
2026-07-04 23:42:47 +08:00
Tianyi Cui
2c9e5ee756 Merge remote-tracking branch 'origin/master' into persistence-log-catalog 2026-07-04 23:41:57 +08:00
Tianyi Cui
9857bb0c07 Merge remote-tracking branch 'origin/master' into simpl-g-hook-contract
# Conflicts:
#	docs/rfc/README.md
2026-07-04 23:40:05 +08:00
Tianyi Cui
f90f1c358e Merge remote-tracking branch 'origin/master' into simpl-e-acp-trim
# Conflicts:
#	docs/rfc/README.md
2026-07-04 23:22:16 +08:00
Tianyi Cui
c01d8c0dfc Merge remote-tracking branch 'origin/master' into simpl-g-hook-contract
# Conflicts:
#	docs/rfc/README.md
2026-07-04 23:22:08 +08:00
Tianyi Cui
54fc3d65ab Merge remote-tracking branch 'origin/master' into simpl-d-fs-write-only
# Conflicts:
#	docs/rfc/README.md
2026-07-04 23:21:46 +08:00
Tianyi Cui
2728e3bd5b Close remaining keyof-join holes the review verification found
- The owning top-level interface SessionEventMap must now be the SINGLE
  EXPORTED declaration in @deepseek-ai/dsh-session: a non-exported local
  interface (even inside the owning package) and a second exported copy
  are hard errors, so a same-named helper can no longer be catalogued as
  the on-disk vocabulary.
- Any SessionEventMap declaration carrying an extends clause is a hard
  error: inherited keys join keyof SessionEventMap but have no catalog
  row, so heritage is a silent-skip path the gate must reject.

Three new spec cases; RFC and module doc updated to match.
2026-07-04 23:21:23 +08:00
Tianyi Cui
c64cfbbe5d Merge remote-tracking branch 'origin/master' into simpl-a3-knobs
# Conflicts:
#	docs/rfc/README.md
2026-07-04 23:17:51 +08:00
Tianyi Cui
53dc3c8a28 Harden generator against Codex review findings
- A SessionEventMap member that is not a property signature with an
  explicit payload type is now a hard error instead of silently skipped —
  a method-form or type-less member joins keyof SessionEventMap and must
  not escape the catalog.
- A top-level interface SessionEventMap outside @deepseek-ai/dsh-session
  (ownership read from the package manifest) is now a hard error — an
  unrelated same-named local interface was previously catalogued as the
  on-disk vocabulary.
- JSDoc tag detection runs on the trimmed line, so an extra-indented
  '*  @mode' can no longer bypass the forbidden-tag check and leak into
  prose.

Four new spec cases cover these; RFC and module doc updated to describe
the enforced (not just assumed) invariants.
2026-07-04 23:11:42 +08:00
Tianyi Cui
9862eae898 Merge remote-tracking branch 'origin/master' into simpl-a2-vocab
# Conflicts:
#	docs/rfc/README.md
2026-07-04 23:11:07 +08:00
Tianyi Cui
232f314c3a Add generated persistence log event catalog with freshness + completeness gates
docs/persistence-catalog/log-events.md enumerates every SessionEventMap
member — the owning dsh-session vocabulary plus the dsh-compact and
dsh-hook-protocol declaration merges — with payload, surface/log-only badge,
JSDoc prose, and declaration site. scripts/gen-persistence-catalog.ts is a
pure AST pass in the gen-cordis-catalog mold: verify-persistence-catalog
(--check) joins doc-sync, so a stale committed catalog fails pre-push and CI.

The walk enforces JSDoc completeness (every member needs description prose;
@mode is rejected as a category error — log events do not dispatch on the
cordis bus), derives the surface badge from the SurfaceEventType union with a
stale-member cross-check, and hard-errors on duplicate declarations. Payloads
render through the TypeScript printer so newline-separated multi-line type
literals still emit valid one-line fragments.

Documented the five previously JSDoc-less core events (turn/step boundaries,
tool/call), removed the two stray @mode tags on the hook/* merges, and
replaced the hand-restated event enumerations (session.md hook/* table,
compact README table, hook-protocol README bullets, session README name-list
— whose merge note had already drifted) with links to the catalog. RFC:
docs/rfc/implemented/process/2026-07-04-persistence-log-catalog.md.
2026-07-04 22:58:28 +08:00
Tianyi Cui
8f62086feb Merge remote-tracking branch 'origin/master' into simpl-b2-app-boot
# Conflicts:
#	docs/rfc/README.md
2026-07-04 22:58:26 +08:00
Tianyi Cui
5f295de096 Merge remote-tracking branch 'origin/master' into simpl-f-steering-mirror
# Conflicts:
#	docs/rfc/README.md
2026-07-04 22:50:47 +08:00
Tianyi Cui
544cc0439e Merge remote app attribution branch
Resolve the RFC and implementation to defer OpenRouter-specific attribution headers and keep mandatory attribution to User-Agent only.
2026-07-04 22:47:53 +08:00
Tianyi Cui
1ddd6a9eea Merge remote-tracking branch 'origin/master' into simpl-a1-drop-image
# Conflicts:
#	docs/rfc/README.md
2026-07-04 22:46:55 +08:00
Tianyi Cui
80609cca11 Merge remote-tracking branch 'origin/master' into simpl-c-web-observation
# Conflicts:
#	docs/rfc/README.md
2026-07-04 22:39:41 +08:00
Tianyi Cui
c0349051c6 Merge pull request #149 from deepseek-harness/simpl-b1-fold-ui-stdio
refactor(ui): fold the stdio UI helper into the stdio app
2026-07-04 22:36:43 +08:00
Tianyi Cui
0b97b2f7c1 restore hook/result durationMs — review keeps wall-clock audit timing durable
Reverses item 3 of the tighten-hook-protocol-contract RFC per review:
a persistence log is written for future readers, and hook wall-clock
runtime is audit signal (which hook made a turn slow). runHook keeps
its injected now clock and RunHookResult wrapper, the bridges pass the
measured duration through HookResultRecord, the snapshot normalizer
keeps its replay scrub, and the hook fixtures carry the field again.
The RFC records the reversal; the other three prunes stand.
2026-07-04 22:00:12 +08:00
Tianyi Cui
663e57c6d6 Merge branch 'simpl-a2-vocab' into simpl-a3-knobs
# Conflicts:
#	packages/core/tools/src/index.ts
2026-07-04 21:20:55 +08:00
Tianyi Cui
5441665585 Merge branch 'simpl-b1-fold-ui-stdio' into simpl-b2-app-boot
# Conflicts:
#	AGENTS.md
#	packages/README.md
2026-07-04 21:14:15 +08:00
Tianyi Cui
7ab322909f Merge branch 'simpl-a1-drop-image' into simpl-a2-vocab 2026-07-04 21:14:14 +08:00
Tianyi Cui
456cb3b532 Merge remote-tracking branch 'origin/master' into simpl-a1-drop-image
# Conflicts:
#	docs/architecture.md
#	packages/compact/compact-basic/README.md
2026-07-04 21:12:33 +08:00
Tianyi Cui
e2cd7379ed Merge remote-tracking branch 'origin/master' into simpl-e-acp-trim 2026-07-04 21:11:25 +08:00
Tianyi Cui
19ae955009 Merge remote-tracking branch 'origin/master' into simpl-g-hook-contract
# Conflicts:
#	packages/hooks/hook-protocol/src/events.ts
#	packages/hooks/hook-protocol/tests/events.spec.ts
#	packages/hooks/hooks-claude/README.md
#	packages/hooks/hooks-claude/src/index.ts
#	packages/hooks/hooks-codex/README.md
#	packages/hooks/hooks-codex/src/index.ts
2026-07-04 21:08:50 +08:00
Tianyi Cui
1905c809e3 Merge remote-tracking branch 'origin/master' into simpl-c-web-observation
# Conflicts:
#	docs/architecture.md
#	packages/web/web/src/index.ts
2026-07-04 20:54:42 +08:00
Tianyi Cui
52addacf66 Merge remote-tracking branch 'origin/master' into simpl-d-fs-write-only
# Conflicts:
#	docs/rfc/implemented/simplification/2026-07-04-prune-write-only-fs-surface.md
#	packages/fs/fs-local/src/fsio.ts
2026-07-04 20:50:40 +08:00
Tianyi Cui
582caee90a Merge remote-tracking branch 'origin/master' into simpl-f-steering-mirror
# Conflicts:
#	docs/cordis-catalog/events-and-services.md
#	packages/core/agent/src/types.ts
2026-07-04 20:44:34 +08:00
Tianyi Cui
ef86a36ef6 Merge remote-tracking branch 'origin/master' into simpl-b1-fold-ui-stdio
# Conflicts:
#	AGENTS.md
#	packages/README.md
2026-07-04 20:38:38 +08:00
Tianyi Cui
d67836f0d3 Merge remote-tracking branch 'origin/master' into worktree-plugin-config-guideline 2026-07-04 20:21:10 +08:00
Tianyi Cui
d752eed88b Cover the remaining gate guards with focused tests
Codex review: the RFC claims the fixtures prove each guard fires, but the
binding-pattern guards (events + services), the service no-prose branch,
and the empty-@param/@returns-description branches had no focused tests.
Add the five missing cases; every violation branch in the generator now
has a matching fixture.
2026-07-04 19:18:11 +08:00
Tianyi Cui
a29bbe1453 Add JSDoc completeness gate for the cordis surface
gen-cordis-catalog now hard-errors (aggregated, not fail-fast) when an
event lacks description prose or a payload @param, or a public service
method lacks JSDoc, a @param per parameter, a @returns on a non-void
result, or an explicit return type annotation. The this receiver and the
trailing waterfall next are exempt on events (mode machinery owned by
@mode); a stale @param naming no real parameter errors, mirroring the
@mode contradiction check. parseJsDoc now ends prose at the first block
tag (standard JSDoc semantics), so the tags never change the rendered
catalog — only Source: line pointers moved.

Fills the ~139 gaps found across the 15 surface files, extends the spec
with negative-path fixtures for every new guard plus the exemptions,
records the decision as an implemented process RFC, and extends the
AGENTS.md typed-events bullet with the authoring rule. Runs inside
verify-cordis-catalog -> doc-sync, so CI and pre-push enforce it with
zero new wiring.
2026-07-04 19:06:35 +08:00
Tianyi Cui
5a8234643a refactor(llm): drop the inert request knobs — prefill and strict
GenerateOptions.prefill had no production setter and both adapters
rejected it with LlmError('UNSUPPORTED') — its entire observable
behavior was two throws, each pinned by one adapter test. DeepSeek's
chat-prefix completion is a Beta feature on a base URL neither adapter
targets. ToolSchema.strict was threaded through defineTool, the
registry's schemas() allowlist, the deepseek wire mapping, a per-tool
payload-patching pass in the pi-ai adapter, and a tool-catalog render
row, yet no shipped tool set it and the internal endpoint story for
strict mode was never built.

Remove both fields end-to-end: the vocabulary in dsh-llm, the adapter
guards and wire branches, the dsh-tools threading, the tool-catalog
Strict row, the pinning tests, the core.md pastes, the adapter README
rows, and the cookbook line that used prefill as the UNSUPPORTED
example (now stated generically). The pi-ai payload fixup keeps the
half with a job: pi-ai stamps strict:false on every serialized tool,
so the fixup scrubs it unconditionally for wire parity with the
hand-rolled twin (per-tool set/delete machinery gone). temperature/
stop/maxTokens are untouched — honored end-to-end by both adapters.

Each knob returns with its first real producer: prefill with an
adapter that implements chat-prefix completion, strict with a tool
that wants it and a beta-endpoint story.

RFC: docs/rfc/implemented/simplification/2026-07-04-drop-inert-request-knobs.md
(moved from proposed/, amended to shipped reality); the content-block
vocabulary RFC's consequence line now records prefill as producer-gated.
2026-07-04 18:38:39 +08:00
Tianyi Cui
ac42c46a65 Merge branch 'master' into codex/app-attribution-rfc 2026-07-04 18:36:10 +08:00
Tianyi Cui
3da966a52a Merge remote-tracking branch 'origin/master' into worktree-plugin-config-guideline
Master's docs-overhaul stack (#142-#144) rewrote AGENTS.md into the
slim budget-gated form and repointed the review skill's citations.
Resolutions:
- AGENTS.md: master's rewrite wins; the no-hardcoded-tunables
  convention is re-added as one terse bullet in the new style, after
  'Explicit > implicit at package seams'. Within the verify-doc-budgets
  ceiling, so no displacement or raise needed.
- dsh-code-review SKILL.md: master's repointed citations win; the
  hardcoded-tunables reviewer check and the Conventions keyword are
  re-applied on top.
- packages/README.md: master replaced the hand-maintained dependency
  list (which carried this branch's chars-per-token wording) with a
  pointer to the generated module graph — master's side taken whole;
  the estimator wording lives on in the compact package READMEs.
2026-07-04 18:32:52 +08:00
Tianyi Cui
cc15ef54ef Sync remaining chars-per-token prose in overview READMEs
The convergence pass found four summary-level sites still describing
the estimator as fixed char/4: packages/README.md (twice), the compact
group and interface READMEs, and compact-basic's package.json
description. All now say chars-per-token with the charsPerToken
default, matching the authoritative package README/module doc/RFC.
2026-07-04 18:15:54 +08:00
Tianyi Cui
0ebb86e70f Implement mandatory app-attribution headers per the RFC
dsh-llm owns the vocabulary (attribution.ts): AppIdentity with the version
read from the package manifest, userAgent(), and attributionHeaders(target,
identity) over a closed AttributionTarget union ('generic' | 'openrouter').
Both adapters send the headers on every provider request — llm-deepseek in
its fetch headers, llm-pi-ai through pi-ai's StreamOptions.headers — behind
an explicit attributionTarget config (never inferred from baseURL), with
mock-server tests asserting exact wire arrival and the absence of the
OpenRouter set by default.

The RFC moves to implemented/ amended with the settled identity (the
deepseek-harness token, the DeepSeek Harness title, the planned
deepseek-ai/deepseek-harness-sdk URL behind a FIXME until that repo exists)
and the explicit-config OpenRouter decision.
2026-07-04 18:14:42 +08:00
Tianyi Cui
48d25cdd44 Fix review findings: validate the hooks cap, integer read caps, doc drift, config plumb-through test
A Codex review pass on the draft caught four real gaps and two solid
suggestions; all addressed except one pushed back on the merits:

- hooks-claude/hooks-codex: stderrSummaryMaxChars was the one new knob
  with NO range validation — a negative/NaN cap would silently
  misbehave inside slice(). Both bridges now assert a positive integer
  at the TOP of apply() (before the config-file parse's early return,
  so a bad value fails the load loudly), with rejection tests.
- tool-fs: the read caps count lines/chars/bytes, so positive-FINITE
  was too loose (a fractional readLimit would flow into windowing
  arithmetic and the schema description). All four now require a
  positive integer, matching tool-web's cap.
- Doc drift the gates cannot catch: tool-web's README tools table
  still named WEB_SEARCH_MAX_RESULTS as the mechanism; compact-basic's
  README/module doc and the compaction-capability-seam RFC still
  described estimation as fixed char/4 rather than the charsPerToken
  default.
- subagent-acp: the dispose graces were tested only at the
  startAcpRun level, so a regression that stopped threading plugin
  config into AcpRunSpec would have survived. A provider-path test now
  drives the trap-escalation scenario through ctx.subagents.start with
  small config graces and bounds dispose at 4s.

Pushed back on: converting compact-basic's charsPerToken to a
schemastery field. The package's whole config is deliberately
hand-rolled (resolveConfig, every threshold REQUIRED with no default —
a documented design posture); one schemastery field beside it would be
incoherent. The knob is cordis.yml-reachable, defaulted, and validated,
which is what the convention requires; migrating the package to
schemastery wholesale is pre-existing config-surface hygiene out of
this change's scope.
2026-07-04 18:06:35 +08:00
Tianyi Cui
3567d000c4 refactor(vocab): prune producer-less variants — cache hints, agent source, continuation trigger
The vocabulary maps grow by declaration merging, and the admission policy
stated on TurnEndReasonMap is that a variant lands with its first emitter.
Three declared items had no producer and no consumer:

- CacheHint and the cache?: CacheHint fields on TextBlock/ToolResultBlock:
  nothing constructs a block with cache:, and neither adapter reads .cache —
  DeepSeek prompt caching is automatic (hints map OUT of responses, never IN).
- MessageSourceMap.agent: zero constructors; the subagent backends send the
  parent prompt with no source (logs as user), and the envelope renderer
  interpolates source.kind without routing on it.
- TurnTriggerMap.continuation: the loop structurally cannot emit it —
  continuation is further steps within a turn, never a new turn — and its only
  writer was an llm-replay test fixture that needed any non-message trigger
  (now an injection trigger).

Each variant returns the day it gains a real producer, via the same
merge-extensible maps. Docs updated in the same change: the MessageSourceMap
paste in core.md, the TurnTriggerMap paste in session.md (manifest untouched —
both symbols survive), the content-block vocabulary RFC's cache-hints
consequence line, and the RFC moved to implemented/ and amended to shipped
reality (the image block's own cache field had already left with the
drop-image RFC).
2026-07-04 17:50:50 +08:00
Tianyi Cui
774d460889 Expose audited hardcoded tunables as plugin config
The audit swept every packages/*/* plugin for the new AGENTS.md
convention (no hardcoded tunables in plugins) and exposes each finding
as a defaulted, validated Config field. Defaults are the previously
hardcoded values throughout, so no deployment or golden changes.

- tool-fs (had NO Config): readLimit, readMaxLineLength, readMaxBytes,
  readStreamMinSize. The caps thread through ReadToolCaps/ReadWindow —
  read-render already documented that the consumer applies the caps, so
  they become explicit per-request fields.
- tool-web: searchMaxResults (WEB_SEARCH_MAX_RESULTS stays as the
  schemastery default). Also fixes the stale GREP_LIMIT references in
  search.ts and the web-capability-seam RFC (no such constant exists).
- bash-local: graceMs (SIGTERM->SIGKILL escalation grace). The
  RunInternals.graceMs test seam is gone: graceMs is now a required
  SpawnSpec field filled from config, so tests exercise the real
  config path and the defaults live in exactly one place.
- subagent-acp: disposeEofGraceMs / disposeGraceMs. The AcpRunSpec
  fields become required for the same one-defaulting-layer reason.
- session-persistence-sqlite: journalMode ('wal' default; the
  rollback-journal modes serve filesystems where WAL's shared-memory
  files do not work, e.g. network mounts).
- hooks-claude + hooks-codex: stderrSummaryMaxChars for the persisted
  hook/result stderr summary. The duplicated summarize() helpers merge
  into hook-protocol's summarizeStderr(stderr, maxChars), beside the
  HookResultRecord field it feeds, with the bound parameterized the
  same way runHook's defaultTimeoutMs already is.
- compact-basic: charsPerToken for the token estimator (default 4, the
  English-text heuristic; CJK-heavy deployments need ~1-2 or compaction
  fires far too late). Also corrects the BasicCompactService class doc,
  which claimed defaults the required-field config never had.
- fs-local: deletes the dead STREAM_MIN_SIZE constant and the dead
  FsIoInternals.streamMinSize seam — the read-routing bound lives in
  the consumer (tool-fs), where it is now config. This is item 1 of
  the proposed prune-write-only-fs-surface RFC, annotated accordingly.

Every new field gets range validation (following the existing
assertPositiveFinite pattern), a README row, and tests covering the
configured behavior, the schema default, and load-time rejection.
2026-07-04 17:37:23 +08:00
Tianyi Cui
2745879132 refactor(llm): drop the image content block until a path can honor it
ImageBlock had no production producer and every consumer dropped it:
the deepseek serializer skipped it, the pi-ai converter skipped it as
unrepresentable, the ACP bridge neither advertises image prompt
capability nor forwards image blocks, and compact-basic charged a flat
85-token estimate and rendered an [image] placeholder. A block
constructed today would silently vanish from the wire — the vocabulary
advertised a capability no path honors, the silent-data-loss shape the
defensive patterns warn against. The only constructors were tests
pinning the skip/estimate branches.

Remove ImageBlock and its ContentBlockMap entry (its cache?: CacheHint
field leaves with it; CacheHint itself and the other two cache? fields
are out of scope). compact-basic loses its explicit image estimate and
placeholder arms (the merge-extensible default arms absorb the case);
the deepseek serializer, pi-ai converter, and ACP codec already handled
image in their default arms, so only their image-naming comments
change. The codec's inbound rejection of ACP-protocol image prompt
content stays — that guards wire content a client can send regardless
of our vocabulary.

Tests that constructed harness image blocks to pin the removed branches
are dropped (the 85-token estimate pin) or retargeted onto plugin-added
block types / other non-text blocks, which the surviving default arms
own. Docs, the type-equiv pastes, and the content-block vocabulary
RFC's block list and multimodal-home consequence are updated in the
same change; the RFC moves to implemented/ and the index is
regenerated. A real multimodal feature reintroduces image via
declaration merging together with the adapter mapping, ACP
advertisement, and compaction pricing that honor it.
2026-07-04 17:21:13 +08:00
Tianyi Cui
d5a3e2c492 Merge remote-tracking branch 'origin/simpl-b1-fold-ui-stdio' into simpl-b2-app-boot
# Conflicts:
#	docs/module-graph.md
#	packages/README.md
#	pnpm-lock.yaml
2026-07-04 17:20:43 +08:00
Tianyi Cui
6fc33da960 docs: regenerate the module graph and dependency row for the dsh-llm edge 2026-07-04 17:17:36 +08:00
Tianyi Cui
695e64a978 fix(stdio-agent): declare the dsh-llm dependency the moved spec uses
stdio-chat.spec.ts imports ContentBlock/StreamChunk types from
@deepseek-ai/dsh-llm; the manifest entry lived on the folded package
and did not move with the tests. Declared peer+dev like the module's
other harness deps (the src consumes dsh-llm vocabulary through the
session events it renders).
2026-07-04 17:12:50 +08:00
Tianyi Cui
4aaf7d848c docs(app-boot): fix review findings — exit-semantics precision, dep row, composition wording
The module/README prose claimed both guard-covered failure classes
would otherwise exit 0; only the failed-IMPORT class does (an init
throw already exits non-zero via Node's default handler — the guard
contributes the labelled line and the guaranteed exit(1), as its own
JSDoc says). The dependency-graph row now says loader/include (include
is a peer: boot() names it by entry string, so the installed consumer
provides it). The bins are self-executing compositions, not main()
wrappers.
2026-07-04 17:05:00 +08:00
Tianyi Cui
4a0941fb4b feat(ui): share the app bins' boot glue in @deepseek-ai/dsh-app-boot
The four near-twin helpers the two published bins carried — loadEnv,
installFailLoud, assertEntriesLoaded, boot — live once in
packages/ui/app-boot, parameterized by the bin's diagnostic prefix and
injectable at their side-effect seams (warn sink, process slice), so
every branch sits under the per-file 100% coverage gate: the unit suite
drives boot() in-process against the real Loader (relative-specifier
configs) through both the settled-tree path and the fiber-less-entry
rejection, and exercises the ENOENT/unloadable .env split, the
Error/non-Error/stackless fail-loud arms, and the disabled-entry
exclusion. resolveConfigPath (snapshot-aware) becomes the single path
resolver for both bins.

Each bin.ts is now a thin self-executing composition plus its
app-specific lifecycle (acp: replay env-skip + stdin-EOF dispose;
stdio: nothing extra), exports nothing, and stays coverage-excluded;
the built-bin smokes still prove both artifacts under plain node in the
node_modules-shaped temp dir (now symlinking ui/app-boot), including
the missing-config non-zero exit.

Implements docs/rfc/implemented/simplification/2026-07-04-share-app-bin-boot-glue.md
(moved from proposed/ and amended); the extract-example-app-packages
RFC's bin-ownership facts are amended in the same change.
2026-07-04 16:43:06 +08:00
Tianyi Cui
6df70c2079 docs: same smoke-vs-shape claim fixed at its two remaining sites
The stdio app's module doc and its unit suite's doc carried the claim
the review already corrected elsewhere: an inject-less app boots past a
collapsed export shape, so the smoke proves the tree runs while the
unwrapExports assertion in the unit suite pins the shape.
2026-07-04 16:08:03 +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
e9589b523f docs: fix review findings — support-group summary row, smoke-prose export-shape claims
The packages/README.md group table still described support/ as holding
the stdio UI; and three prose sites credited the keyless smokes with
guarding the app export shape, which a bundle without inject cannot do
(a stray default boots rather than crashes) — the shape is pinned by
the stdio-agent unit suite's explicit unwrapExports assertion; the
smokes prove the composed tree boots.
2026-07-04 15:59:12 +08:00