Remove generated Agent Note index

This commit is contained in:
Tianyi Cui
2026-07-19 23:15:23 +08:00
parent e8eddc7ef8
commit 4779d04af8
20 changed files with 210 additions and 490 deletions

View File

@@ -1,248 +0,0 @@
# Agent Note index
Generated by `pnpm run gen-agent-note-index` from the Agent Note tree — never edit by hand; `verify-agent-note-classification` fails when this file is stale. The curated front door — layout, classification, when to write one, and the in-file format — is [README.md](README.md).
## Proposed
### Feature
| Title | First proposed |
|---|---|
| [Pre-tool input rewrite — a consistent design](proposed/feature/2026-06-30-pre-tool-input-rewrite.md) | 2026-06-30 |
| [Recallable compaction — index checkpoints, a state checkpoint, and in-session history recall](proposed/feature/2026-07-06-recallable-compaction.md) | 2026-07-06 |
| [Claude Code and Codex subagent backends (out-of-process delegation to external coding agents)](proposed/feature/2026-07-07-claude-code-and-codex-subagent-backends.md) | 2026-07-07 |
| [Interactive side sessions and merge-back](proposed/feature/2026-07-08-interactive-side-sessions.md) | 2026-07-08 |
| [SQLite FTS5 session search](proposed/feature/2026-07-10-sqlite-session-query-provider.md) | 2026-07-10 |
| [Stream workflow progress through tool calls](proposed/feature/2026-07-13-stream-workflow-progress-through-tool-calls.md) | 2026-07-13 |
| [Developer-owned SDK projects](proposed/feature/2026-07-14-sdk-developer-projects.md) | 2026-07-14 |
| [SDK follow-up capabilities](proposed/feature/2026-07-17-sdk-follow-up-capabilities.md) | 2026-07-17 |
### Simplification
| Title | First proposed |
|---|---|
| [Prune dead public and result surface](proposed/simplification/2026-07-04-prune-dead-core-spine-surface.md) | 2026-07-04 |
| [Make JSON-RPC completion and transport directional](proposed/simplification/2026-07-19-make-jsonrpc-directional.md) | 2026-07-19 |
### Architecture
| Title | First proposed |
|---|---|
| [Runtime schemas for the event vocabulary (Zod vs the merge-extensible-map pattern)](proposed/architecture/2026-06-16-typed-event-schemas.md) | 2026-06-16 |
| [SDK project editing architecture](proposed/architecture/2026-07-15-sdk-project-editing-architecture.md) | 2026-07-15 |
### Process
| Title | First proposed |
|---|---|
| [API extractor reports](proposed/process/2026-06-11-api-extractor-reports.md) | 2026-06-11 |
| [Architectural conformance — dependency rules and the adapter kit](proposed/process/2026-06-11-architectural-conformance.md) | 2026-06-11 |
| [Supply chain checks and vendor drift verification](proposed/process/2026-06-11-supply-chain-and-vendor-drift.md) | 2026-06-11 |
| [Discover package inventories instead of maintaining static lists](proposed/process/2026-06-20-discover-package-inventory.md) | 2026-06-20 |
| [Periodic human-review maintenance for dsh-code-review](proposed/process/2026-07-13-human-review-skill-maintenance.md) | 2026-07-13 |
### Testing
| Title | First proposed |
|---|---|
| [Deterministic tests, the replay invariant fixture, and race stress](proposed/testing/2026-06-11-deterministic-and-stress-testing.md) | 2026-06-11 |
| [Mutation testing as the coverage counterweight](proposed/testing/2026-06-11-mutation-testing.md) | 2026-06-11 |
## Implemented
### Feature
| Title | First proposed |
|---|---|
| [Agent Client Protocol (ACP) support — drive the coding agent from external editors](implemented/feature/2026-06-14-acp-agent-client-protocol.md) | 2026-06-14 |
| [Multiplex concurrent ACP sessions over one connection](implemented/feature/2026-06-14-acp-multi-session.md) | 2026-06-14 |
| [Code Mode — the model writes TypeScript against the tool registry](implemented/feature/2026-06-15-code-mode.md) | 2026-06-15 |
| [Filesystem tool schemas — model-facing read/write/edit shapes](implemented/feature/2026-06-17-filesystem-tool-schemas.md) | 2026-06-17 |
| [Rich ACP bash rendering — the terminal card via the `_meta` convention](implemented/feature/2026-06-18-acp-terminal-and-tool-rendering.md) | 2026-06-18 |
| [Compaction as a capability seam (abstract contract + basic backend)](implemented/feature/2026-06-18-compaction-capability-seam.md) | 2026-06-18 |
| [Subagent capability seam](implemented/feature/2026-06-21-subagent-capability-seam.md) | 2026-06-21 |
| [ACP subagent backend (out-of-process delegation)](implemented/feature/2026-06-22-acp-subagent-backend.md) | 2026-06-22 |
| [Workspace context instruction files](implemented/feature/2026-06-24-workspace-context.md) | 2026-06-24 |
| [Ask-user question capability](implemented/feature/2026-06-25-ask-user-question.md) | 2026-06-25 |
| [The `todo_write` tool — model task list as event-sourced session state](implemented/feature/2026-06-29-todo-write-tool.md) | 2026-06-29 |
| [dsh-hooks-claude + dsh-hooks-codex — the Claude Code / Codex hook bridges](implemented/feature/2026-06-30-hook-bridges.md) | 2026-06-30 |
| [dsh-hook-protocol — the shared Claude Code / Codex hook wire-protocol core](implemented/feature/2026-06-30-hook-protocol-lib.md) | 2026-06-30 |
| [Interception seams — the typed-Decision surface a hook programs against](implemented/feature/2026-06-30-interception-seams.md) | 2026-06-30 |
| [SessionStore fork API](implemented/feature/2026-06-30-session-store-fork-api.md) | 2026-06-30 |
| [Subagent lifecycle enrichment — lastAssistantMessage (observe-only)](implemented/feature/2026-06-30-subagent-observe-enrich.md) | 2026-06-30 |
| [Dynamic workflows — a script-driven multi-agent orchestration seam](implemented/feature/2026-07-05-dynamic-workflows.md) | 2026-07-05 |
| [Skill system — progressive disclosure instructions for agents](implemented/feature/2026-07-05-skill-system.md) | 2026-07-05 |
| [The approval seam — one-shot permission decisions over a waterfall of answerers](implemented/feature/2026-07-06-approval-seam.md) | 2026-07-06 |
| [Explicit model-facing tool order](implemented/feature/2026-07-06-explicit-tool-order.md) | 2026-07-06 |
| [The subprocess sandbox — confinement seam, native runners, escalation, and per-session modes](implemented/feature/2026-07-06-sandbox.md) | 2026-07-06 |
| [MCP client plugin — connect to external MCP servers and bridge their tools](implemented/feature/2026-07-07-mcp-client-plugin.md) | 2026-07-07 |
| [The session prefix — request-only messages in front of the derived history](implemented/feature/2026-07-07-session-prefix.md) | 2026-07-07 |
| [Background subagent tasks](implemented/feature/2026-07-08-background-subagent-tasks.md) | 2026-07-08 |
| [Repeat-tool-call guard plugin](implemented/feature/2026-07-08-repeat-tool-guard.md) | 2026-07-08 |
| [The self-referential cordis toolset](implemented/feature/2026-07-08-self-referential-cordis-toolset.md) | 2026-07-08 |
| [Bash-backed grep and glob discovery tools](implemented/feature/2026-07-09-bash-backed-grep-glob-discovery.md) | 2026-07-09 |
| [Expose agent session identity and JSONL location to tools and hooks](implemented/feature/2026-07-10-agent-session-identity-and-log-location.md) | 2026-07-10 |
| [Parallel tool-call execution by per-call safety](implemented/feature/2026-07-10-parallel-tool-call-execution.md) | 2026-07-10 |
| [Exact session query service](implemented/feature/2026-07-10-session-query-service.md) | 2026-07-10 |
| [Configure subagent persona, tool visibility, and depth](implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md) | 2026-07-12 |
| [Session query relationship tracing](implemented/feature/2026-07-13-session-query-tracing.md) | 2026-07-13 |
| [Optional time-context plugin](implemented/feature/2026-07-14-time-context-plugin.md) | 2026-07-14 |
| [Durable per-step time context](implemented/feature/2026-07-16-durable-per-step-time-context.md) | 2026-07-16 |
| [Dedicated full-screen TUI front door](implemented/feature/2026-07-17-dedicated-full-screen-tui-front-door.md) | 2026-07-17 |
### Simplification
| Title | First proposed |
|---|---|
| [Drop the mutable session summary](implemented/simplification/2026-06-19-drop-mutable-session-summary.md) | 2026-06-19 |
| [Fold trace-only session facts into load-bearing events](implemented/simplification/2026-06-20-collapse-trace-only-session-events.md) | 2026-06-20 |
| [Drop the unconsumed `llm/adapter-change` event](implemented/simplification/2026-06-20-drop-unconsumed-llm-adapter-change-event.md) | 2026-06-20 |
| [Drop unconsumed assembled LLM convenience surfaces](implemented/simplification/2026-06-20-drop-unconsumed-llm-assembled-surfaces.md) | 2026-06-20 |
| [Prune dead methods from the persistence seam](implemented/simplification/2026-06-20-prune-dead-seam-methods.md) | 2026-06-20 |
| [Keep one public stop primitive](implemented/simplification/2026-06-20-public-agent-stop-surface.md) | 2026-06-20 |
| [Stop mirroring durable boundaries as agent events](implemented/simplification/2026-06-20-remove-agent-boundary-mirror-events.md) | 2026-06-20 |
| [Unify the agent id and the session id](implemented/simplification/2026-06-20-unify-agent-and-session-id.md) | 2026-06-20 |
| [Split the filesystem seam — provider text mutations plus the `dsh-fs-policy` plugin](implemented/simplification/2026-06-26-fsspec-style-fs-seam.md) | 2026-06-26 |
| [Stop mirroring the token stream as an agent event](implemented/simplification/2026-07-02-remove-stream-chunk-mirror.md) | 2026-07-02 |
| [Drop the `image` content block until a path can honor it](implemented/simplification/2026-07-04-drop-image-content-block.md) | 2026-07-04 |
| [Drop `GenerateOptions.prefill` and `ToolSchema.strict` — request knobs with no working end-to-end path](implemented/simplification/2026-07-04-drop-inert-request-knobs.md) | 2026-07-04 |
| [Drop the unconsumed web observation surface — the `providers-change` event and the status methods](implemented/simplification/2026-07-04-drop-unconsumed-web-observation-surface.md) | 2026-07-04 |
| [Fold the stdio UI helper into the stdio app](implemented/simplification/2026-07-04-fold-stdio-ui-helper.md) | 2026-07-04 |
| [Prune producer-less vocabulary variants (block cache hints, the `agent` message source, the `continuation` turn trigger)](implemented/simplification/2026-07-04-prune-producerless-vocabulary-variants.md) | 2026-07-04 |
| [Prune write-only fields and a dead routing knob from the fs seam](implemented/simplification/2026-07-04-prune-write-only-fs-surface.md) | 2026-07-04 |
| [Remove the `agent/steering` mirror emit](implemented/simplification/2026-07-04-remove-agent-steering-mirror.md) | 2026-07-04 |
| [Share the app bins' boot glue instead of maintaining twin copies](implemented/simplification/2026-07-04-share-app-bin-boot-glue.md) | 2026-07-04 |
| [Tighten the hook-protocol contract — dialect, discarded fields, double defaults, and lib-owned `hook/result` semantics](implemented/simplification/2026-07-04-tighten-hook-protocol-contract.md) | 2026-07-04 |
| [Trim unreachable ACP bridge surface — the branding knobs and the kind-sniffing fallback](implemented/simplification/2026-07-04-trim-acp-bridge-unreachable-surface.md) | 2026-07-04 |
| [Drop unconsumed skill provider events](implemented/simplification/2026-07-12-drop-unconsumed-skill-provider-events.md) | 2026-07-12 |
| [Prune unused web seam fields](implemented/simplification/2026-07-12-prune-unused-web-seam-fields.md) | 2026-07-12 |
| [Simplify session-log representation](implemented/simplification/2026-07-12-simplify-session-log-representation.md) | 2026-07-12 |
| [Retire the standalone subagent mock package](implemented/simplification/2026-07-19-retire-subagent-mock-package.md) | 2026-07-19 |
| [Use one surface manager per session](implemented/simplification/2026-07-19-use-one-session-surface-manager.md) | 2026-07-19 |
### Architecture
| Title | First proposed |
|---|---|
| [Provider-neutral content-block vocabulary owned by dsh-llm](implemented/architecture/2026-06-11-content-block-vocabulary.md) | 2026-06-11 |
| [Custom typed tool-schema DSL instead of schemastery](implemented/architecture/2026-06-11-custom-schema-dsl.md) | 2026-06-11 |
| [Source-owned session immutability and dev-mode invariants](implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.md) | 2026-06-11 |
| [Event-sourced sessions with derived message history](implemented/architecture/2026-06-11-event-sourced-sessions.md) | 2026-06-11 |
| [Microkernel — extension via Cordis event taxonomy, one concrete loop](implemented/architecture/2026-06-11-microkernel-event-taxonomy.md) | 2026-06-11 |
| [Runtime arg validation at the model boundary](implemented/architecture/2026-06-11-runtime-arg-validation.md) | 2026-06-11 |
| [Structured error taxonomy](implemented/architecture/2026-06-11-structured-error-taxonomy.md) | 2026-06-11 |
| [Tool schemas are part of the system-prompt assembly](implemented/architecture/2026-06-11-tool-schemas-in-prompt-assembly.md) | 2026-06-11 |
| [Capability seams — interface / implementation / consumer split](implemented/architecture/2026-06-13-capability-seams.md) | 2026-06-13 |
| [Two LLM adapters as a design-verification twin](implemented/architecture/2026-06-13-twin-llm-adapters.md) | 2026-06-13 |
| [Session persistence as an abstract service over the existing `SessionEvent`](implemented/architecture/2026-06-14-session-persistence.md) | 2026-06-14 |
| [Every session event is enclosed in a turn](implemented/architecture/2026-06-15-turn-enclosure-invariant.md) | 2026-06-15 |
| [Filesystem capability seam — ctx.fs, local backend, and model-facing filesystem tools](implemented/architecture/2026-06-17-filesystem-capability-seam.md) | 2026-06-17 |
| [Agent lifecycle and ownership seams](implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-seams.md) | 2026-06-18 |
| [Session surface — an ordered projection over the event log](implemented/architecture/2026-06-18-session-surface.md) | 2026-06-18 |
| [Shared persistence write coordinator](implemented/architecture/2026-06-18-shared-persistence-write-coordinator.md) | 2026-06-18 |
| [Branded IDs everywhere they belong](implemented/architecture/2026-06-20-branded-ids.md) | 2026-06-20 |
| [Extract example apps into packages](implemented/architecture/2026-06-20-extract-example-app-packages.md) | 2026-06-20 |
| [The background task runtime (`ctx.tasks`) and generic task control tools](implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md) | 2026-06-20 |
| [Reorganize packages into a modular hierarchy](implemented/architecture/2026-06-20-package-hierarchy.md) | 2026-06-20 |
| [Mandatory `User-Agent` attribution for provider requests](implemented/architecture/2026-06-21-mandatory-app-attribution-headers.md) | 2026-06-21 |
| [Web capability seam - stable tools over multiple providers](implemented/architecture/2026-06-24-web-capability-seam.md) | 2026-06-24 |
| [Make `dsh-fs-policy` an event-gate plugin, not a method interface](implemented/architecture/2026-06-26-file-context-as-event-gate.md) | 2026-06-26 |
| [stdin + extra env on the bash seam](implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-surface.md) | 2026-06-30 |
| [Event-domain semantics — session is the fact log, agent is the live surface](implemented/architecture/2026-06-30-event-domain-semantics.md) | 2026-06-30 |
| [Resolve filesystem paths against the caller's session cwd](implemented/architecture/2026-07-02-fs-per-session-cwd.md) | 2026-07-02 |
| [Result-time applied-hunk diffs for file mutations](implemented/architecture/2026-07-02-result-time-applied-hunk-diffs.md) | 2026-07-02 |
| [Tagged render-intent union for tool-call presentation](implemented/architecture/2026-07-02-tool-render-intent-union.md) | 2026-07-02 |
| [Add direct directory listing to the filesystem seam](implemented/architecture/2026-07-03-filesystem-directory-listing-seam.md) | 2026-07-03 |
| [Prompt variables and tool-guidance ownership](implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.md) | 2026-07-05 |
| [Every LLM request is reconstructable from the session log](implemented/architecture/2026-07-05-reconstructable-requests.md) | 2026-07-05 |
| [Subagent provider-lifecycle events — `subagent/provider-added` / `subagent/provider-removed`](implemented/architecture/2026-07-05-subagent-provider-lifecycle-events.md) | 2026-07-05 |
| [A shared timeout/deadline primitive, with hard-kill left to each capability](implemented/architecture/2026-07-06-timeout-deadline-library.md) | 2026-07-06 |
| [Tool result retention library](implemented/architecture/2026-07-06-tool-result-retention-library.md) | 2026-07-06 |
| [Tool-call timeout policy as a plugin](implemented/architecture/2026-07-07-tool-call-timeout-policy.md) | 2026-07-07 |
| [The agent is a registration scope](implemented/architecture/2026-07-08-agent-scope-contexts.md) | 2026-07-08 |
| [Tool output spill policy](implemented/architecture/2026-07-08-tool-output-spill-files.md) | 2026-07-08 |
| [After-call compaction pressure and context-overflow recovery](implemented/architecture/2026-07-10-after-call-compaction-pressure-and-overflow-recovery.md) | 2026-07-10 |
| [Single-file executable SDK runtime distribution (single-exe)](implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md) | 2026-07-10 |
| [Agent-scope runtime design and correctness](implemented/architecture/2026-07-12-agent-scope-runtime-design.md) | 2026-07-12 |
| [Provider-routed LLM adapters and a generic pi-ai backend](implemented/architecture/2026-07-14-provider-routed-llm-adapters.md) | 2026-07-14 |
| [Initiating Agent scope over AsyncLocalStorage](implemented/architecture/2026-07-15-agent-initiator-scope.md) | 2026-07-15 |
| [Advisory LLM catalogs and per-session ACP model selection](implemented/architecture/2026-07-15-llm-model-catalog-and-acp-selection.md) | 2026-07-15 |
| [Replay token meter service](implemented/architecture/2026-07-15-replay-token-meter-service.md) | 2026-07-15 |
### Process
| Title | First proposed |
|---|---|
| [Doc-sync enforcement](implemented/process/2026-06-11-doc-sync-enforcement.md) | 2026-06-11 |
| [Mechanical quality gates over prose guidelines](implemented/process/2026-06-11-quality-gates.md) | 2026-06-11 |
| [tsdown for JS bundling instead of dumble](implemented/process/2026-06-11-tsdown-over-dumble.md) | 2026-06-11 |
| [Vendor Cordis as source, not npm dependencies](implemented/process/2026-06-11-vendor-cordis-as-source.md) | 2026-06-11 |
| [pnpm as the package manager instead of Yarn 4](implemented/process/2026-06-16-pnpm-over-yarn.md) | 2026-06-16 |
| [TSC-first build and one tsconfig](implemented/process/2026-06-17-ts-build-config.md) | 2026-06-17 |
| [Markdown cross-link validity linting](implemented/process/2026-06-18-markdown-cross-link-lint.md) | 2026-06-18 |
| [Classify Agent Notes by kind via path-encoded subdirectories](implemented/process/2026-06-20-agent-note-classification.md) | 2026-06-20 |
| [Core-data-structures catalog and the `ts type-equiv` drift gate](implemented/process/2026-06-20-core-data-structures-catalog.md) | 2026-06-20 |
| [Generated cordis events + services catalog](implemented/process/2026-06-20-generated-cordis-catalog.md) | 2026-06-20 |
| [Bilingual documentation via paired sibling files and a pairing gate](implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.md) | 2026-07-02 |
| [Generated tool-schema catalog (boot-and-harvest)](implemented/process/2026-07-02-tool-schema-catalog.md) | 2026-07-02 |
| [Documentation graph index for maintainers and SDK users](implemented/process/2026-07-03-documentation-graph-atlas.md) | 2026-07-03 |
| [JSDoc completeness gate for the cordis surface](implemented/process/2026-07-04-cordis-jsdoc-completeness-gate.md) | 2026-07-04 |
| [Documentation tiers, budgets, and the ceiling gate](implemented/process/2026-07-04-doc-tiers-and-budgets.md) | 2026-07-04 |
| [Generate the Agent Note index tables](implemented/process/2026-07-04-generate-agent-note-index-tables.md) | 2026-07-04 |
| [Generated persistence log event catalog](implemented/process/2026-07-04-persistence-log-catalog.md) | 2026-07-04 |
| [One gated in-file format for Agent Notes](implemented/process/2026-07-05-uniform-agent-note-format.md) | 2026-07-05 |
| [Export-surface JSDoc gate](implemented/process/2026-07-06-export-surface-jsdoc-gate.md) | 2026-07-06 |
| [Generated plugin config catalog](implemented/process/2026-07-06-generated-config-catalog.md) | 2026-07-06 |
| [Raise the Node LTS engine floor to 22.19](implemented/process/2026-07-06-node-engine-floor.md) | 2026-07-06 |
| [Parallel GitHub CI gates](implemented/process/2026-07-06-parallel-github-ci-gates.md) | 2026-07-06 |
| [Parallel pre-push gates](implemented/process/2026-07-06-parallel-pre-push-gates.md) | 2026-07-06 |
| [A gated Known-Limitations section in every package README](implemented/process/2026-07-10-readme-known-limitations-gate.md) | 2026-07-10 |
| [Package Model Experience contract](implemented/process/2026-07-12-package-model-experience-contract.md) | 2026-07-12 |
| [TypeScript Program-backed semantic gates](implemented/process/2026-07-14-typescript-program-backed-semantic-gates.md) | 2026-07-14 |
| [Run CI examples from built lib](implemented/process/2026-07-17-run-ci-examples-from-built-lib.md) | 2026-07-17 |
### Testing
| Title | First proposed |
|---|---|
| [Property-based testing for protocol-shaped code](implemented/testing/2026-06-11-property-based-testing.md) | 2026-06-11 |
| [ACP snapshot tests — record-once / replay-deterministic](implemented/testing/2026-06-19-acp-snapshot-tests.md) | 2026-06-19 |
| [Real-API e2e in CI against the external DeepSeek API](implemented/testing/2026-06-19-real-api-e2e-ci.md) | 2026-06-19 |
| [Use `session.jsonl` as the only snapshot session-log artifact](implemented/testing/2026-06-20-remove-redundant-snapshot-log-expected-output.md) | 2026-06-20 |
| [Persist the seed boundary so fork-child replay routes correctly](implemented/testing/2026-06-22-fork-child-replay-seed-boundary.md) | 2026-06-22 |
| [Record fork and mixed spawn+fork snapshot scenarios](implemented/testing/2026-06-22-fork-snapshot-scenarios.md) | 2026-06-22 |
| [Per-session snapshot replay for nested agents](implemented/testing/2026-06-22-subagent-snapshot-replay.md) | 2026-06-22 |
| [Hook snapshot matrix — end-to-end expected outputs for both bridges](implemented/testing/2026-07-04-hook-snapshot-matrix.md) | 2026-07-04 |
| [Single-source the acp-agent replay config](implemented/testing/2026-07-04-single-source-acp-replay-config.md) | 2026-07-04 |
| [Pin request-header content in one snapshot scenario](implemented/testing/2026-07-06-pin-request-header-content-in-one-scenario.md) | 2026-07-06 |
| [Extract the ACP snapshot suite into a support package](implemented/testing/2026-07-08-shared-acp-snapshot-package.md) | 2026-07-08 |
| [Snapshot semantic terminal state for the TUI](implemented/testing/2026-07-18-tui-terminal-state-snapshots.md) | 2026-07-18 |
## Rejected
### Simplification
| Title | First proposed |
|---|---|
| [Persist assembled assistant messages, not stream chunks](rejected/simplification/2026-06-20-assembled-assistant-messages-only.md) | 2026-06-20 |
| [Drop ACP session/load until resume has a product shape](rejected/simplification/2026-06-20-drop-acp-session-load.md) | 2026-06-20 |
| [Drop ACP terminal `_meta` rendering](rejected/simplification/2026-06-20-drop-acp-terminal-meta.md) | 2026-06-20 |
| [Drop bash full-output spill files](rejected/simplification/2026-06-20-drop-bash-output-spill-files.md) | 2026-06-20 |
| [Drop durable step boundary events](rejected/simplification/2026-06-20-drop-durable-step-boundaries.md) | 2026-06-20 |
| [Drop unused session lineage metadata](rejected/simplification/2026-06-20-drop-unused-session-lineage.md) | 2026-06-20 |
| [Fold the persistence interface into dsh-session](rejected/simplification/2026-06-20-fold-session-persistence-interface.md) | 2026-06-20 |
| [Collapse tool-owned UI presentation](rejected/simplification/2026-06-20-generic-tool-rendering.md) | 2026-06-20 |
| [Retire mid-turn steering](rejected/simplification/2026-06-20-retire-mid-turn-steering.md) | 2026-06-20 |
| [Return the ACP bridge to one live session per connection](rejected/simplification/2026-06-20-single-session-acp-bridge.md) | 2026-06-20 |
| [Truncate interrupted final turns on load](rejected/simplification/2026-06-20-truncate-interrupted-turns.md) | 2026-06-20 |
| [Prune the unimplemented subagent seam vocabulary](rejected/simplification/2026-07-04-prune-unimplemented-subagent-vocabulary.md) | 2026-07-04 |
| [Collapse workflows to the exercised foreground core](rejected/simplification/2026-07-12-collapse-workflow-to-foreground-core.md) | 2026-07-12 |
| [Prune unused skill registry surface](rejected/simplification/2026-07-12-prune-unused-skill-registry-surface.md) | 2026-07-12 |
| [Fold the single compaction backend into its service package](rejected/simplification/2026-07-19-fold-compaction-package-split.md) | 2026-07-19 |
### Architecture
| Title | First proposed |
|---|---|
| [Deep-readonly public surfaces](rejected/architecture/2026-06-11-immutable-public-surfaces.md) | 2026-06-11 |
| [Make the shared example base providerless](rejected/architecture/2026-06-20-providerless-example-base.md) | 2026-06-20 |

View File

@@ -1,6 +1,6 @@
# Agent Notes # Agent Notes
One kind of design doc lives here. An **Agent Note** records a decision or proposal that shapes this codebase — the *why* and *what we gave up*, the parts code and docs can't carry. The full list is the generated [INDEX.md](INDEX.md); this file is the contract where Agent Notes live, when to write one, and [the in-file format](#the-file-format). One kind of design doc lives here. An **Agent Note** records a decision or proposal that shapes this codebase — the *why* and *what we gave up*, the parts code and docs can't carry. This file is the front door and contract: where Agent Notes live, when to write one, and [the in-file format](#the-file-format).
## Layout and naming ## Layout and naming
@@ -14,9 +14,11 @@ Every Agent Note has two axes, both encoded in its **path** — `{lifecycle}/{cl
The date in the filename is when the topic was **first proposed** (per git history). Cross-references between Agent Notes use relative markdown links (`[topic](../../implemented/architecture/2026-…-….md)`) — never bare prose or numbers — so they are mechanically checkable and survive moves between folders. The date in the filename is when the topic was **first proposed** (per git history). Cross-references between Agent Notes use relative markdown links (`[topic](../../implemented/architecture/2026-…-….md)`) — never bare prose or numbers — so they are mechanically checkable and survive moves between folders.
The tree is the inventory: browse its lifecycle/class folders or search the repository. Do not add a centralized `INDEX.md`; the [no-index Agent Note](implemented/process/2026-07-19-remove-generated-agent-note-index.md) owns the rationale.
## Classification ## Classification
Each Agent Note belongs to one path-encoded class from the closed set in `scripts/agent-note-index.ts`; the classification gate rejects other folders. [INDEX.md](INDEX.md) is generated from paths, titles, and filename dates, and its freshness is gated. Adding a class requires updating the canonical set and this section. See the [classification](implemented/process/2026-06-20-agent-note-classification.md) and [index-generation](implemented/process/2026-07-04-generate-agent-note-index-tables.md) Agent Notes. Each Agent Note belongs to one path-encoded class from the closed set in `scripts/agent-note-tree.ts`; the classification gate rejects other folders. Adding a class requires updating the canonical set and this section. See the [classification Agent Note](implemented/process/2026-06-20-agent-note-classification.md).
| Class | What it covers | | Class | What it covers |
|---|---| |---|---|

View File

@@ -4,7 +4,7 @@ Status: implemented
## Problem ## Problem
`.agents/notes/` grouped Agent Notes by **lifecycle** only`proposed/` / `implemented/` / `rejected/`. Nothing recorded what *kind* of decision each Agent Note was. The index was one flat list per lifecycle, with no way to scan "show me every simplification" or "every testing-strategy decision." A wave of simplification Agent Notes landing on the same day made the gap concrete: a reader skimming `proposed/` could not tell a new capability from a removal from a tooling-policy change without opening each file. A lifecycle-only Agent Note tree`proposed/` / `implemented/` / `rejected/` — does not record what *kind* of decision each file contains. A reader browsing one lifecycle cannot distinguish a new capability from a removal or a tooling-policy change without opening each file.
The repo's standing bias is [mechanical quality gates over prose guidelines](2026-06-11-quality-gates.md): a convention that isn't machine-checked rots. So a classification scheme here had to be enforceable, not an honor-system header. The repo's standing bias is [mechanical quality gates over prose guidelines](2026-06-11-quality-gates.md): a convention that isn't machine-checked rots. So a classification scheme here had to be enforceable, not an honor-system header.
@@ -29,18 +29,18 @@ The `architecture` / `process` line: **architecture** is about the source we shi
Both are `doc-sync` members, in the `verify-md-wrap` style (tsx ESM, verify-don't-generate, exit non-zero on the first violation): Both are `doc-sync` members, in the `verify-md-wrap` style (tsx ESM, verify-don't-generate, exit non-zero on the first violation):
- **`scripts/verify-agent-note-classification.ts`** — the closed set and index freshness. It asserts every file under a lifecycle folder lives in a class folder from the canonical set (a loose `.md` at a lifecycle root, or an unknown class folder, fails), and that the generated [INDEX.md](../../INDEX.md) byte-matches a fresh render from the tree (see [generate the Agent Note index tables](2026-07-04-generate-agent-note-index-tables.md)). The canonical class set lives as a `const` in `scripts/agent-note-index.ts` — the machine source of truth shared with the generator — and [the README](../../README.md) documents it in prose; the class *descriptions* stay hand-written, the index is generated. - **`scripts/verify-agent-note-classification.ts`** — the closed lifecycle and class sets. It asserts every file under a lifecycle folder lives in a class folder from the canonical set (a loose `.md` at a lifecycle root, or an unknown class folder, fails) and rejects a centralized `INDEX.md`. The canonical sets live in `scripts/agent-note-tree.ts`, and [the README](../../README.md) documents each class in prose.
- **`scripts/verify-doc-refs.ts`** — source comments that cite docs. Agent Note paths are referenced not only from Markdown but from TypeScript doc comments (root-relative prose like `.agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.md`). `verify-md-links` never saw those, so the reorg could have silently orphaned them. This gate scans repo-authored `.ts` under `packages/**` and `examples/**` (excluding built `lib/` and `vendor/`) for `docs/….md` tokens, resolves each root-relative, and asserts it exists. It requires the `.md` extension so extensionless prose (`docs/postmortem/0001`, `docs/architecture.md § Extending The Harness`) is left alone. - **`scripts/verify-doc-refs.ts`** — source comments that cite docs. Agent Note paths are referenced not only from Markdown but from TypeScript doc comments (root-relative prose like `.agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.md`). `verify-md-links` does not see those, so a reorganization could silently orphan them. This gate scans repo-authored `.ts` under `packages/**` and `examples/**` (excluding built `lib/` and `vendor/`) for `docs/….md` and `.agents/notes/….md` tokens, resolves each root-relative path, and asserts it exists. It requires the `.md` extension so extensionless prose is left alone.
## Alternatives considered ## Alternatives considered
- **A `Classification:` prose line** in each file (next to `Status:`), parsed by the gate. Workable, but it duplicates into the file a fact the path can already carry, and a line can disagree with its folder. Path-encoding makes the label and its storage the same thing — there is nothing to keep in sync. - **A `Classification:` prose line** in each file (next to `Status:`), parsed by the gate. Workable, but it duplicates into the file a fact the path can already carry, and a line can disagree with its folder. Path-encoding makes the label and its storage the same thing — there is nothing to keep in sync.
- **A `refactor` class.** It overlaps `simplification` almost entirely; the only discriminator anyone reached for was "does observable behavior change?", which `simplification` already encodes (it does not). One class, not two. - **A `refactor` class.** It overlaps `simplification` almost entirely; the only discriminator anyone reached for was "does observable behavior change?", which `simplification` already encodes (it does not). One class, not two.
- **Auto-generating the index** from the filesystem. Rejected here to keep the index hand-written; superseded by [generate the Agent Note index tables](2026-07-04-generate-agent-note-index-tables.md) once stacked proposal waves made the hand-written tables the repo's most conflict-prone docs region — the list is now the fully generated [INDEX.md](../../INDEX.md) while the README prose stays curated. - **A generated or hand-maintained corpus index.** Rejected because the lifecycle/class tree is authoritative, while a centralized inventory creates a merge hotspot without providing discovery that tree navigation or repository search cannot provide. The separate [index proposal](../../rejected/process/2026-07-04-generate-agent-note-index-tables.md) records the discarded generated shape.
## Consequences ## Consequences
- Every Agent Note now sits under a class folder, and the index groups by class within each lifecycle. A reader scans one heading to see all simplifications, or all testing decisions. - Every Agent Note sits under a class folder. A reader can browse one folder to see all simplifications or all testing decisions within a lifecycle.
- Two more fast tsx scripts in the `doc-sync` chain; no new dependency (the mdast/GFM stack was already present for `verify-md-wrap`/`verify-md-links`). - Two more fast tsx scripts in the `doc-sync` chain; no new dependency (the mdast/GFM stack was already present for `verify-md-wrap`/`verify-md-links`).
- Adding a class is a deliberate act: amend the `const` in `scripts/agent-note-index.ts` and the [Classification section](../../README.md#classification), not just `mkdir` a folder. The gate rejects an unknown folder, so an ad-hoc class can't slip in. - Adding a class is a deliberate act: amend the `const` in `scripts/agent-note-tree.ts` and the [Classification section](../../README.md#classification), not just `mkdir` a folder. The gate rejects an unknown folder, so an ad-hoc class can't slip in.
- Source-comment doc references are now gated too — a moved or renamed doc that a `.ts` comment cites fails the pre-push hook, closing a drift class `verify-md-links` structurally could not see. - Source-comment doc references are now gated too — a moved or renamed doc that a `.ts` comment cites fails the pre-push hook, closing a drift class `verify-md-links` structurally could not see.

View File

@@ -1,32 +0,0 @@
# Agent Note: Generate the Agent Note index tables
Status: implemented
## Problem
The Agent Note index's per-lifecycle/per-class tables list facts that are fully derivable: an Agent Note's path encodes lifecycle and class, its filename encodes the first-proposed date, and its H1 carries the title. A hand-maintained copy of those facts is also the repo's highest-contention docs hotspot: every proposal wave appends rows to the same few lines, so concurrent Agent Note branches conflict precisely there while agreeing everywhere else, and each conflict is resolved by hand-merging rows whose content the filesystem already knows. [The classification Agent Note](2026-06-20-agent-note-classification.md) originally kept the index hand-written for curation's sake — but the curated part of the README is the prose, and the prose never conflicts; only the mechanical tables do.
## Decision
Keep the curated prose; generate the list. The tables live in [`.agents/notes/INDEX.md`](../../INDEX.md), a **fully generated file** — the curated prose stays in README.md, which carries no index rows at all. [`scripts/agent-note-index.ts`](../../../../scripts/agent-note-index.ts) is the shared source of truth — the tree walker (owning the closed lifecycle/class sets and the structure rules, including a parseable-H1 requirement) and the renderer (rows from H1 title with any `Agent Note: ` prefix stripped, plus the filename date, sorted by date then filename, grouped as `### {Class}` sections in canonical class order). Two thin consumers share it:
- [`scripts/gen-agent-note-index.ts`](../../../../scripts/gen-agent-note-index.ts) (`pnpm run gen-agent-note-index`) rewrites INDEX.md in full from the tree.
- [`scripts/verify-agent-note-classification.ts`](../../../../scripts/verify-agent-note-classification.ts) (a `doc-sync` member) checks structure, asserts the committed INDEX.md byte-matches a fresh render — the `gen-cordis-catalog`/`verify-cordis-catalog` pattern — and rejects an index-shaped row in the curated README. Freshness subsumes the index-completeness check: a generated-from-disk table is definitionally complete and correctly headed.
Adding, moving, or deleting an Agent Note means editing only the Agent Note file and running the generator; the classification Agent Note's rejected-alternatives record carries the supersession cross-link.
## Alternatives considered
### Why not marker-delimited regions inside README.md?
The first landed shape: the generator spliced the tables into README.md between `gen-agent-note-index` marker comments, under each `## {Lifecycle}` heading. Superseded by the whole-file INDEX.md once the README also absorbed the in-file format contract ([the uniform-format Agent Note](2026-07-05-uniform-agent-note-format.md)): a front-door README hosting hundreds of generated rows dwarfed its curated prose, and splice mechanics (marker pairs, heading checks, outside-region row detection) exist only to protect curated text that a dedicated generated file simply doesn't contain.
### Why not the verifier-only model?
It catches mistakes but still makes every proposal edit a shared hotspot in a hand-maintained table, and a failed verifier is strictly more annoying than a generator for a purely mechanical row: the author has already named and placed the file; the index copy adds no information. This is the same hand-list-versus-derivation judgment the [package-inventory proposal](../../proposed/process/2026-06-20-discover-package-inventory.md) applies to tsconfig references and knip stanzas — applied to the one list that demonstrably conflicts.
## Consequences
- The generated file is explicit: its banner names the generator, there is no curated region to protect inside it, and the generator refuses to run on a structurally invalid tree.
- A malformed or missing H1 is a hard error in both the generator and the gate — the H1 is now load-bearing as the index title source.
- Concurrent Agent Note branches resolve index conflicts by rerunning the generator, never by hand-merging rows.

View File

@@ -18,10 +18,10 @@ The whole corpus was normalized in the same change that defined the format — t
- **Header-only normalization** (H1 and Status, bodies untouched) — rejected: the debt markers flagged the *body* genre split, and leaving `Context`/`Decision` beside `Problem`/`Proposal` indefinitely resolves nothing. - **Header-only normalization** (H1 and Status, bodies untouched) — rejected: the debt markers flagged the *body* genre split, and leaving `Context`/`Decision` beside `Problem`/`Proposal` indefinitely resolves nothing.
- **No Status line** (the folder already is the status; the three newest pre-format Agent Notes (and the zh counterpart of one) omitted the line) — rejected in favor of keeping a self-describing file: the drift risk that motivated dropping it is neutralized by gating the line against the folder instead. - **No Status line** (the folder already is the status; the three newest pre-format Agent Notes (and the zh counterpart of one) omitted the line) — rejected in favor of keeping a self-describing file: the drift risk that motivated dropping it is neutralized by gating the line against the folder instead.
- **Dated status** (`Status: implemented (accepted YYYY-MM-DD)`) — rejected: the acceptance date is narrated history the writing rules keep out of docs; the filename carries first-proposed, git carries the rest, and the gate could check a date's format but never its truth. - **Dated status** (`Status: implemented (accepted YYYY-MM-DD)`) — rejected: the acceptance date is narrated history the writing rules keep out of docs; the filename carries first-proposed, git carries the rest, and the gate could check a date's format but never its truth.
- **A bare `# <title>` H1** — rejected: the `Agent Note: ` prefix is the corpus-majority form and self-describes the genre when a file is read outside its tree; the index generator strips it, so index rows are identical either way. - **A bare `# <title>` H1** — rejected: the `Agent Note: ` prefix self-describes the genre when a file is read outside its tree, and the format gate prevents it from drifting.
- **`## What we give up` as the implemented closer** (the README's own phrase for what an Agent Note records) — rejected: it names only costs, and an honest consequences section records what the trade-off bought as well. - **`## What we give up` as the implemented closer** (the README's own phrase for what an Agent Note records) — rejected: it names only costs, and an honest consequences section records what the trade-off bought as well.
- **Convention without a gate** (write the contract down, enforce by review) — rejected: the slop checklist already outlawed spec-speak in `implemented/` by convention, and nineteen files show what convention alone achieves here. - **Convention without a gate** (write the contract down, enforce by review) — rejected: the slop checklist already outlawed spec-speak in `implemented/` by convention, and nineteen files show what convention alone achieves here.
- **A standalone `FORMAT.md` contract file** — the first landed home; folded into README.md once the generated index moved out to [INDEX.md](../../INDEX.md): with the tables gone the README regained the room, and one front door carrying layout, classification, and format beats splitting the contract across two files. - **A standalone `FORMAT.md` contract file** — rejected because one front door carrying layout, classification, and format is easier to discover and maintain than two contract files.
## Consequences ## Consequences

View File

@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-19-remove-generated-agent-note-index.md: 27c1591b29a1ca64370de6ffadfb9c524a804ced
2026-07-19-remove-generated-agent-note-index.zh.md: 868955bc10900f784bd88066042abe24454e27b5

View File

@@ -0,0 +1,33 @@
# Agent Note: Keep Agent Notes discoverable without a generated index
Status: implemented
English | [中文](2026-07-19-remove-generated-agent-note-index.zh.md)
## Problem
A committed Agent Note index duplicates facts already encoded by each file's lifecycle/class path, filename date, and H1. Every branch that adds, moves, or renames an otherwise unrelated Agent Note rewrites the same generated file, making that artifact a predictable merge hotspot.
The centralized chronological list adds little discovery value beyond browsing the lifecycle/class tree or searching the repository, while its generator, renderer, command, and freshness check remain maintenance surface.
## Decision
The lifecycle/class filesystem tree is the Agent Note inventory. [README.md](../../README.md) remains the curated front door and contract, while ordinary tree navigation and repository search provide discovery.
`scripts/agent-note-tree.ts` owns the closed lifecycle/class sets and structural walker. `verify-agent-note-classification` validates that tree and rejects the legacy homes and a root `INDEX.md`; it does not render or freshness-check a centralized list.
This decision supersedes the rejected [generated-index proposal](../../rejected/process/2026-07-04-generate-agent-note-index-tables.md).
## Alternatives considered
**Keep the committed generated index and resolve conflicts by regenerating it.** Regeneration makes conflict resolution mechanical but does not prevent unrelated branches from modifying the same artifact or reduce the review noise it creates.
**Offer an uncommitted on-demand index command.** It avoids committed conflicts but preserves a renderer and command for a discovery path already served by tree navigation and repository search.
**Restore a hand-maintained index.** It has the same shared-file contention and adds completeness/order mistakes that generation avoided.
## Consequences
- Adding, moving, or renaming an Agent Note no longer changes a corpus-wide generated file.
- The classification gate performs less work and the documentation gate topology gains no process or stage.
- Readers give up a single chronological page and use the lifecycle/class tree or repository search instead.

View File

@@ -0,0 +1,33 @@
# Agent Note: 无需生成索引即可发现 Agent Note
Status: implemented
[English](2026-07-19-remove-generated-agent-note-index.md) | 中文
## 问题
提交到仓库的 Agent Note 索引,会重复记录每个文件的生命周期/类别路径、文件名日期和 H1 已经编码的事实。任何分支只要添加、移动或重命名彼此无关的 Agent Note都会重写同一个生成文件因此该产物会成为可预见的合并冲突热点。
与浏览生命周期/类别目录树或搜索仓库相比,这份集中式时间顺序清单提供的发现价值有限;但其生成器、渲染器、命令和新鲜度检查仍然构成维护负担。
## 决策
生命周期/类别文件系统目录树就是 Agent Note 清单。[README.md](../../README.md) 继续作为人工维护的入口和契约,普通的目录树浏览与仓库搜索负责内容发现。
`scripts/agent-note-tree.ts` 持有封闭的生命周期/类别集合与结构遍历器。`verify-agent-note-classification` 校验该目录树,并拒绝旧目录和根目录中的 `INDEX.md`,但不会渲染集中式清单或检查其新鲜度。
本决策取代已拒绝的[生成索引提案](../../rejected/process/2026-07-04-generate-agent-note-index-tables.md)。
## 备选方案
**保留提交到仓库的生成索引,并通过重新生成解决冲突。** 重新生成能让冲突解决过程机械化,但无法阻止无关分支修改同一产物,也不会减少由此产生的评审噪音。
**提供不提交到仓库的按需索引命令。** 这可以避免已提交文件的冲突,但仍需维护渲染器和命令,而目录树浏览与仓库搜索已经覆盖该发现路径。
**恢复人工维护的索引。** 它具有相同的共享文件争用问题,还会重新引入生成机制已经避免的完整性和排序错误。
## 影响
- 添加、移动或重命名 Agent Note 时,不再改动覆盖整个语料库的生成文件。
- 分类门禁执行的工作更少,文档门禁拓扑也不会增加进程或阶段。
- 读者不再获得单一的时间顺序页面,改用生命周期/类别目录树或仓库搜索。

View File

@@ -0,0 +1,36 @@
# Agent Note: Generate the Agent Note index tables
Status: rejected — a centralized generated list is merge-prone and adds little discovery value
## Problem
Per-lifecycle/per-class tables would list facts that are fully derivable: an Agent Note's path encodes lifecycle and class, its filename encodes the first-proposed date, and its H1 carries the title. A hand-maintained copy of those facts would also be a high-contention docs hotspot because concurrent Agent Note branches append rows to the same few lines. [The classification Agent Note](../../implemented/process/2026-06-20-agent-note-classification.md) makes the tree itself authoritative.
## Proposal
Keep the curated prose and generate the list as a fully generated `.agents/notes/INDEX.md`. A shared `scripts/agent-note-index.ts` module would own both the tree walker and the renderer. Two thin consumers would share it:
- `scripts/gen-agent-note-index.ts` (`pnpm run gen-agent-note-index`) would rewrite INDEX.md in full from the tree.
- `scripts/verify-agent-note-classification.ts` would check structure and assert that the committed INDEX.md byte-matches a fresh render.
Adding, moving, or deleting an Agent Note would mean editing the Agent Note file and running the generator.
## Alternatives considered
### Why not marker-delimited regions inside README.md?
Marker-delimited tables inside README.md would mix generated and curated text, requiring splice mechanics and protection for the surrounding contract. A dedicated generated file would at least keep those concerns separate.
### Why not the verifier-only model?
It catches mistakes but still makes every proposal edit a shared hotspot in a hand-maintained table. The author has already named and placed the file, so the index copy adds no information. This is the same hand-list-versus-derivation judgment the [package-inventory proposal](../../proposed/process/2026-06-20-discover-package-inventory.md) applies to tsconfig references and knip stanzas.
## Consequences
- The generated file would be explicit and contain no curated region.
- A malformed or missing H1 would be a hard error because the H1 supplies each row title.
- Concurrent branches would still modify the same committed artifact, even if conflicts could be resolved by rerunning the generator.
## Related
The implemented [no-index decision](../../implemented/process/2026-07-19-remove-generated-agent-note-index.md) keeps the tree and repository search as the discovery mechanisms.

View File

@@ -14,7 +14,7 @@ description: Use when reviewing a pull request in the deepseek-harness repo —
- [docs/AGENTS.md](../../../docs/AGENTS.md): documentation placement and prose discipline. - [docs/AGENTS.md](../../../docs/AGENTS.md): documentation placement and prose discipline.
- [dsh-prose-standard](../dsh-prose-standard/SKILL.md): required coverage and editorial judgment for comments, docs, prompts, and visible strings. - [dsh-prose-standard](../dsh-prose-standard/SKILL.md): required coverage and editorial judgment for comments, docs, prompts, and visible strings.
- [docs/testing.md](../../../docs/testing.md) and the [quality-gates Agent Note](../../notes/implemented/process/2026-06-11-quality-gates.md): required test tiers and gates. - [docs/testing.md](../../../docs/testing.md) and the [quality-gates Agent Note](../../notes/implemented/process/2026-06-11-quality-gates.md): required test tiers and gates.
- [Agent Note index](../../notes/README.md): design rationale. Treat disagreement with an Agent Note as a design discussion, not an automatic veto. - [Agent Notes](../../notes/README.md): design rationale. Treat disagreement with an Agent Note as a design discussion, not an automatic veto.
- For bilingual changes, read [translation-rules.md](../../../docs/i18n/translation-rules.md), [terminology.md](../../../docs/i18n/terminology.md), and [dsh-translate-docs](../dsh-translate-docs/SKILL.md). - For bilingual changes, read [translation-rules.md](../../../docs/i18n/translation-rules.md), [terminology.md](../../../docs/i18n/terminology.md), and [dsh-translate-docs](../dsh-translate-docs/SKILL.md).
## Blocking requirements ## Blocking requirements

View File

@@ -11,7 +11,7 @@ This skill helps turn a broad "find things to simplify" request into evidence-ba
- Read `AGENTS.md`, especially the pre-release stance and the conventions (including the tests-are-not-golden-truth and Agent Notes-are-not-golden-truth doctrines), plus [docs/defensive-patterns.md](../../../docs/defensive-patterns.md) and [docs/testing.md](../../../docs/testing.md). - Read `AGENTS.md`, especially the pre-release stance and the conventions (including the tests-are-not-golden-truth and Agent Notes-are-not-golden-truth doctrines), plus [docs/defensive-patterns.md](../../../docs/defensive-patterns.md) and [docs/testing.md](../../../docs/testing.md).
- Skim [docs/architecture.md](../../../docs/architecture.md) before judging anything under `packages/`; simplifications that fight the service map or event taxonomy need extra evidence. - Skim [docs/architecture.md](../../../docs/architecture.md) before judging anything under `packages/`; simplifications that fight the service map or event taxonomy need extra evidence.
- Use the Agent Note index ([.agents/notes/README.md](../../notes/README.md)) to understand intentional architecture. The most relevant implemented examples are [drop mutable session summary](../../notes/implemented/simplification/2026-06-19-drop-mutable-session-summary.md), [shared persistence write coordinator](../../notes/implemented/architecture/2026-06-18-shared-persistence-write-coordinator.md), [capability seams](../../notes/implemented/architecture/2026-06-13-capability-seams.md), and the twin adapter / dual persistence backend Agent Notes. - Use the Agent Note tree and its [contract](../../notes/README.md) to understand intentional architecture. The most relevant implemented examples are [drop mutable session summary](../../notes/implemented/simplification/2026-06-19-drop-mutable-session-summary.md), [shared persistence write coordinator](../../notes/implemented/architecture/2026-06-18-shared-persistence-write-coordinator.md), [capability seams](../../notes/implemented/architecture/2026-06-13-capability-seams.md), and the twin adapter / dual persistence backend Agent Notes.
- Treat dual LLM adapters and dual persistence backends as intentional by default. Do not propose deleting either twin/backend as "low effort" unless the user explicitly overrides that constraint. Removing an unused method or hook inside a protected seam can still be valid if it does not collapse the protected design. - Treat dual LLM adapters and dual persistence backends as intentional by default. Do not propose deleting either twin/backend as "low effort" unless the user explicitly overrides that constraint. Removing an unused method or hook inside a protected seam can still be valid if it does not collapse the protected design.
## What Counts As A Strong Candidate ## What Counts As A Strong Candidate
@@ -68,7 +68,7 @@ Reject or downgrade a candidate when:
## Write The Agent Note ## Write The Agent Note
Create one file per durable proposal under `.agents/notes/<lifecycle>/<class>/yyyy-mm-dd-topic.md`, following the lifecycle/classification contract in `.agents/notes/README.md`. Regenerate `.agents/notes/INDEX.md`; never add a manual Agent Note table to the README. Keep prose paragraphs on one physical line and use relative Markdown links. Create one file per durable proposal under `.agents/notes/<lifecycle>/<class>/yyyy-mm-dd-topic.md`, following the lifecycle/classification contract in `.agents/notes/README.md`. Keep prose paragraphs on one physical line and use relative Markdown links.
Prefer this shape, adjusting when the idea needs it: Prefer this shape, adjusting when the idea needs it:

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority; # side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with: # after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write # pnpm run verify-translation-pairing --write
development.md: 31d9f76b6f32b1d26e7b61cdbc2a09aa3504fd6a development.md: 94eb4f03329b574862a1ac1de2f8c1d4db4f4a0a
development.zh.md: 57d9ca376ed85c212cfd075e1b056882f6449e05 development.zh.md: b533aff43a66ff7cfc5dc61e5b9b224a01c51f12

View File

@@ -86,7 +86,6 @@ pnpm run verify-cordis-catalog # fail if either cordis catalog is stale
pnpm run verify-export-jsdoc # fail if a module-level package export lacks complete JSDoc pnpm run verify-export-jsdoc # fail if a module-level package export lacks complete JSDoc
pnpm run gen-doc-graphs # regenerate generated relationship docs from source and curated graph definitions pnpm run gen-doc-graphs # regenerate generated relationship docs from source and curated graph definitions
pnpm run verify-doc-graphs # fail if generated relationship docs are stale pnpm run verify-doc-graphs # fail if generated relationship docs are stale
pnpm run gen-agent-note-index # regenerate .agents/notes/INDEX.md from the Agent Note tree
pnpm run verify-md-wrap # fail on hard-wrapped prose paragraphs in docs/README markdown pnpm run verify-md-wrap # fail on hard-wrapped prose paragraphs in docs/README markdown
pnpm run verify-mermaid # fail if a ```mermaid diagram has invalid Mermaid syntax pnpm run verify-mermaid # fail if a ```mermaid diagram has invalid Mermaid syntax
pnpm run verify-type-equiv # fail if a ```ts type-equiv doc block drifts from its source type pnpm run verify-type-equiv # fail if a ```ts type-equiv doc block drifts from its source type

View File

@@ -86,7 +86,6 @@ pnpm run verify-cordis-catalog # fail if either cordis catalog is stale
pnpm run verify-export-jsdoc # fail if a module-level package export lacks complete JSDoc pnpm run verify-export-jsdoc # fail if a module-level package export lacks complete JSDoc
pnpm run gen-doc-graphs # regenerate generated relationship docs from source and curated graph definitions pnpm run gen-doc-graphs # regenerate generated relationship docs from source and curated graph definitions
pnpm run verify-doc-graphs # fail if generated relationship docs are stale pnpm run verify-doc-graphs # fail if generated relationship docs are stale
pnpm run gen-agent-note-index # regenerate .agents/notes/INDEX.md from the Agent Note tree
pnpm run verify-md-wrap # fail on hard-wrapped prose paragraphs in docs/README markdown pnpm run verify-md-wrap # fail on hard-wrapped prose paragraphs in docs/README markdown
pnpm run verify-mermaid # fail if a ```mermaid diagram has invalid Mermaid syntax pnpm run verify-mermaid # fail if a ```mermaid diagram has invalid Mermaid syntax
pnpm run verify-type-equiv # fail if a ```ts type-equiv doc block drifts from its source type pnpm run verify-type-equiv # fail if a ```ts type-equiv doc block drifts from its source type

View File

@@ -53,7 +53,6 @@
"verify-runtime-closure": "tsx scripts/verify-runtime-closure.ts", "verify-runtime-closure": "tsx scripts/verify-runtime-closure.ts",
"verify-cordis-config": "tsx scripts/verify-cordis-config.ts", "verify-cordis-config": "tsx scripts/verify-cordis-config.ts",
"gen-cordis-catalog": "tsx scripts/gen-cordis-catalog.ts", "gen-cordis-catalog": "tsx scripts/gen-cordis-catalog.ts",
"gen-agent-note-index": "tsx scripts/gen-agent-note-index.ts",
"verify-cordis-catalog": "tsx scripts/gen-cordis-catalog.ts --check", "verify-cordis-catalog": "tsx scripts/gen-cordis-catalog.ts --check",
"gen-cordis-api": "tsx scripts/gen-cordis-api.ts", "gen-cordis-api": "tsx scripts/gen-cordis-api.ts",
"verify-cordis-api": "tsx scripts/gen-cordis-api.ts --check", "verify-cordis-api": "tsx scripts/gen-cordis-api.ts --check",

View File

@@ -1,130 +0,0 @@
/**
* Shared source of truth for the Agent Note index: the tree walker (structure rules) and the README
* table renderer. `gen-agent-note-index.ts` writes the generated regions;
* `verify-agent-note-classification.ts` checks structure and asserts the committed regions are fresh.
* Lifecycle and class sets are closed under `.agents/notes/README.md`; rows derive
* from path, H1, and filename date and sort deterministically. Import is pure.
*/
import { readFileSync, readdirSync } from 'node:fs'
import { resolve, sep } from 'node:path'
import { globSync } from 'node:fs'
export const agentNoteRoot = resolve(import.meta.dirname, '../.agents/notes')
/** The closed set of Agent Note lifecycles (top-level folders under .agents/notes/). */
const LIFECYCLES = ['proposed', 'implemented', 'rejected'] as const
/**
* The closed set of Agent Note classes (nested folder under each lifecycle). Adding a
* class is a deliberate act: extend this list AND the README's Classification
* section. The gate rejects any folder not listed here.
*/
const CLASSES = ['feature', 'bug-fix', 'simplification', 'architecture', 'process', 'testing'] as const
/** Non-Agent Note Markdown allowed to sit directly at a lifecycle root. */
const ROOT_ALLOWLIST = new Set(['AGENTS.md', 'CLAUDE.md'])
/** Title-case a class/lifecycle folder name for a README heading. */
const heading = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1)
/** One Agent Note file, as discovered by the walker. */
export interface AgentNote {
lifecycle: string
cls: string
base: string
/** Path relative to .agents/notes — the README link target. */
rel: string
/** H1 text with any `Agent Note: ` prefix stripped — the README row title. */
title: string
/** `yyyy-mm-dd` from the filename — the "First proposed" column. */
date: string
}
/**
* Walk the Agent Note tree, enforcing the structure rules. Returns every valid Agent Note
* plus one error string per violation (unknown lifecycle or class folder, bad
* depth, bad filename, missing/malformed H1). Callers treat a non-empty error
* list as fatal — the index is only generated from a structurally valid tree.
*/
export function walkAgentNoteTree(): { notes: AgentNote[]; errors: string[] } {
const notes: AgentNote[] = []
const errors: string[] = []
// The lifecycle set is closed too: any directory under .agents/notes/ that is not
// a known lifecycle would otherwise hold Agent Notes invisible to the walk below.
for (const entry of readdirSync(agentNoteRoot, { withFileTypes: true })) {
if (entry.isDirectory() && !(LIFECYCLES as readonly string[]).includes(entry.name)) {
errors.push(`structure: ${entry.name}/ — unknown lifecycle folder (allowed: ${LIFECYCLES.join(', ')})`)
}
}
for (const lifecycle of LIFECYCLES) {
for (const match of globSync(`${lifecycle}/**/*.md`, { cwd: agentNoteRoot }).map(path => path.split(sep).join('/')).sort()) {
const segs = match.split('/')
// Allowlisted file directly at the lifecycle root (e.g. implemented/AGENTS.md).
if (segs.length === 2 && ROOT_ALLOWLIST.has(segs[1] ?? '')) continue
// A Chinese counterpart (foo.zh.md, docs/i18n/README.md) is the SAME Agent Note,
// indexed via its English filename; the pairing gate owns its consistency.
if (match.endsWith('.zh.md')) continue
const cls = segs[1]
const base = segs[2]
if (segs.length !== 3 || cls === undefined || base === undefined) {
errors.push(`structure: ${match} — expected {lifecycle}/{class}/file.md (got depth ${segs.length})`)
continue
}
if (!(CLASSES as readonly string[]).includes(cls)) {
errors.push(`structure: ${match} — unknown class folder "${cls}" (allowed: ${CLASSES.join(', ')})`)
continue
}
if (!/^\d{4}-\d{2}-\d{2}-.+\.md$/.test(base)) {
errors.push(`structure: ${match} — filename must be yyyy-mm-dd-topic.md`)
continue
}
const firstLine = readFileSync(resolve(agentNoteRoot, match), 'utf8').split('\n', 1)[0] ?? ''
const h1 = /^#\s+(?:Agent Note:\s+)?(.+?)\s*$/.exec(firstLine)
if (!h1?.[1]) {
errors.push(`title: ${match} — first line must be an H1 (\`# Agent Note: <title>\` or \`# <title>\`), got: ${JSON.stringify(firstLine)}`)
continue
}
notes.push({ lifecycle, cls, base, rel: match, title: h1[1], date: base.slice(0, 10) })
}
}
return { notes, errors }
}
/**
* Render one lifecycle's section body: a `### {Class}` heading plus a
* `| Title | First proposed |` table for every non-empty class, in CLASSES
* order, rows sorted by date then filename.
*/
function renderLifecycle(notes: AgentNote[], lifecycle: string): string {
const sections: string[] = []
for (const cls of CLASSES) {
const rows = notes
.filter(r => r.lifecycle === lifecycle && r.cls === cls)
.sort((a, b) => a.date.localeCompare(b.date) || a.base.localeCompare(b.base))
if (rows.length === 0) continue
const table = rows.map(r => `| [${r.title}](${r.rel}) | ${r.date} |`).join('\n')
sections.push(`### ${heading(cls)}\n\n| Title | First proposed |\n|---|---|\n${table}`)
}
return sections.join('\n\n')
}
/**
* Render the complete `.agents/notes/INDEX.md` content: a generated-file banner
* followed by one `## {Lifecycle}` section per lifecycle in canonical order.
* The whole file is generated state — there is no curated region to preserve.
*/
export function renderIndex(notes: AgentNote[]): string {
const parts = [
'# Agent Note index',
'',
'Generated by `pnpm run gen-agent-note-index` from the Agent Note tree — never edit by hand; `verify-agent-note-classification` fails when this file is stale. The curated front door — layout, classification, when to write one, and the in-file format — is [README.md](README.md).',
]
for (const lifecycle of LIFECYCLES) {
parts.push('', `## ${heading(lifecycle)}`, '', renderLifecycle(notes, lifecycle))
}
return `${parts.join('\n')}\n`
}
/** Matches an index-shaped table row (a `| [title](lifecycle/…) |` line) — generated state that must not appear in curated prose. */
export const INDEX_ROW = /^\|\s*\[[^\]]+\]\((?:proposed|implemented|rejected)\//

View File

@@ -0,0 +1,78 @@
/**
* Shared structural source of truth for the Agent Note tree. Lifecycle and class
* sets are closed under `.agents/notes/README.md`; importing this module is pure.
*/
import { globSync, readdirSync } from 'node:fs'
import { resolve, sep } from 'node:path'
export const agentNoteRoot = resolve(import.meta.dirname, '../.agents/notes')
/** The closed set of Agent Note lifecycles (top-level folders under .agents/notes/). */
const LIFECYCLES = ['proposed', 'implemented', 'rejected'] as const
/**
* The closed set of Agent Note classes (nested folder under each lifecycle). Adding a
* class is a deliberate act: extend this list AND the README's Classification
* section. The gate rejects any folder not listed here.
*/
const CLASSES = ['feature', 'bug-fix', 'simplification', 'architecture', 'process', 'testing'] as const
/** Non-Agent Note Markdown allowed to sit directly at a lifecycle root. */
const ROOT_ALLOWLIST = new Set(['AGENTS.md', 'CLAUDE.md'])
/** One Agent Note file, as discovered by the walker. */
export interface AgentNote {
lifecycle: string
/** Path relative to .agents/notes. */
rel: string
/** `yyyy-mm-dd` from the filename. */
date: string
}
/**
* Walk the Agent Note tree, enforcing the structure rules. Returns every valid Agent Note
* plus one error string per violation (unknown lifecycle or class folder, bad
* depth, or bad filename). Callers treat a non-empty error list as fatal.
*/
export function walkAgentNoteTree(): { notes: AgentNote[]; errors: string[] } {
const notes: AgentNote[] = []
const errors: string[] = []
// The lifecycle set is closed too: any directory under .agents/notes/ that is not
// a known lifecycle would otherwise hold Agent Notes invisible to the walk below.
for (const entry of readdirSync(agentNoteRoot, { withFileTypes: true })) {
if (entry.name === 'INDEX.md') {
errors.push('structure: INDEX.md — centralized Agent Note indexes are forbidden; browse the lifecycle/class tree or search the repository')
continue
}
if (entry.isDirectory() && !(LIFECYCLES as readonly string[]).includes(entry.name)) {
errors.push(`structure: ${entry.name}/ — unknown lifecycle folder (allowed: ${LIFECYCLES.join(', ')})`)
}
}
for (const lifecycle of LIFECYCLES) {
for (const match of globSync(`${lifecycle}/**/*.md`, { cwd: agentNoteRoot }).map(path => path.split(sep).join('/')).sort()) {
const segs = match.split('/')
// Allowlisted file directly at the lifecycle root (e.g. implemented/AGENTS.md).
if (segs.length === 2 && ROOT_ALLOWLIST.has(segs[1] ?? '')) continue
// A Chinese counterpart (foo.zh.md, docs/i18n/README.md) is the SAME Agent Note,
// indexed via its English filename; the pairing gate owns its consistency.
if (match.endsWith('.zh.md')) continue
const cls = segs[1]
const base = segs[2]
if (segs.length !== 3 || cls === undefined || base === undefined) {
errors.push(`structure: ${match} — expected {lifecycle}/{class}/file.md (got depth ${segs.length})`)
continue
}
if (!(CLASSES as readonly string[]).includes(cls)) {
errors.push(`structure: ${match} — unknown class folder "${cls}" (allowed: ${CLASSES.join(', ')})`)
continue
}
if (!/^\d{4}-\d{2}-\d{2}-.+\.md$/.test(base)) {
errors.push(`structure: ${match} — filename must be yyyy-mm-dd-topic.md`)
continue
}
notes.push({ lifecycle, rel: match, date: base.slice(0, 10) })
}
}
return { notes, errors }
}

View File

@@ -1,36 +0,0 @@
/**
* Regenerate `.agents/notes/INDEX.md` — the fully generated Agent Note index — from the
* Agent Note tree (see [agent-note-index.ts](./agent-note-index.ts) for the layout contract and
* rendering rules). The whole file is generated state; the curated prose lives
* in `.agents/notes/README.md`. Freshness is asserted by
* `verify-agent-note-classification.ts` (a `doc-sync` member), so a stale committed
* index fails CI.
*
* Run: `pnpm run gen-agent-note-index`.
*/
import { readFileSync, writeFileSync } from 'node:fs'
import { resolve } from 'node:path'
import { agentNoteRoot, renderIndex, walkAgentNoteTree } from './agent-note-index.ts'
const { notes, errors } = walkAgentNoteTree()
if (errors.length > 0) {
console.error('gen-agent-note-index: refusing to generate from a structurally invalid tree:')
for (const e of errors) console.error(` ${e}`)
process.exit(1)
}
const indexPath = resolve(agentNoteRoot, 'INDEX.md')
const next = renderIndex(notes)
let current: string | undefined
try {
current = readFileSync(indexPath, 'utf8')
} catch {
// Missing INDEX.md is the fresh-generation case, not an error: fall through and write it.
}
if (next === current) {
console.log(`gen-agent-note-index: .agents/notes/INDEX.md is up to date (${notes.length} Agent Notes).`)
} else {
writeFileSync(indexPath, next)
console.log(`gen-agent-note-index: .agents/notes/INDEX.md regenerated (${notes.length} Agent Notes).`)
}

View File

@@ -1,13 +1,12 @@
/** /**
* Enforce Agent Note lifecycle/class paths, dated filenames, and titles; verify the * Enforce Agent Note lifecycle/class paths and dated filenames. Structural rules
* generated index and reject index rows in the curated README. Structural rules * are shared with `agent-note-tree.ts`; the closed classification contract lives
* and rendering are shared with `agent-note-index.ts`; the closed classification * in `.agents/notes/README.md`.
* contract lives in `.agents/notes/README.md`.
*/ */
import { existsSync, readFileSync } from 'node:fs' import { existsSync } from 'node:fs'
import { resolve } from 'node:path' import { resolve } from 'node:path'
import { agentNoteRoot, INDEX_ROW, renderIndex, walkAgentNoteTree } from './agent-note-index.ts' import { walkAgentNoteTree } from './agent-note-tree.ts'
const { notes, errors } = walkAgentNoteTree() const { notes, errors } = walkAgentNoteTree()
@@ -19,25 +18,7 @@ for (const legacyRoot of ['docs/rfc', 'docs/rfcs']) {
} }
if (errors.length === 0) { if (errors.length === 0) {
let index: string | undefined console.log(`verify-agent-note-classification: ${notes.length} Agent Note(s) checked, structure consistent.`)
try {
index = readFileSync(resolve(agentNoteRoot, 'INDEX.md'), 'utf8')
} catch {
// A missing INDEX.md is reported below as staleness, exactly like a drifted one.
}
if (renderIndex(notes) !== index) {
errors.push('index: .agents/notes/INDEX.md is stale or missing — run `pnpm run gen-agent-note-index` and commit the result')
}
const readme = readFileSync(resolve(agentNoteRoot, 'README.md'), 'utf8')
for (const line of readme.split('\n')) {
if (INDEX_ROW.test(line)) {
errors.push(`readme: index-shaped row in the curated README (the list lives in INDEX.md): ${JSON.stringify(line.slice(0, 80))}`)
}
}
}
if (errors.length === 0) {
console.log(`verify-agent-note-classification: ${notes.length} Agent Note(s) checked, structure and index consistent.`)
process.exit(0) process.exit(0)
} }

View File

@@ -7,7 +7,7 @@
import { readFileSync } from 'node:fs' import { readFileSync } from 'node:fs'
import { resolve } from 'node:path' import { resolve } from 'node:path'
import { agentNoteRoot, walkAgentNoteTree } from './agent-note-index.ts' import { agentNoteRoot, walkAgentNoteTree } from './agent-note-tree.ts'
/** The date the format contract landed; the grandfather comment is valid only before it. */ /** The date the format contract landed; the grandfather comment is valid only before it. */
const FORMAT_ADOPTED = '2026-07-05' const FORMAT_ADOPTED = '2026-07-05'