# Conflicts: # .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml # .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.zh.md # .agents/notes/implemented/architecture/2026-06-11-custom-schema-dsl.i18n.yaml # .agents/notes/implemented/architecture/2026-06-11-custom-schema-dsl.zh.md # .agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.i18n.yaml # .agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.zh.md # .agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.i18n.yaml # .agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.zh.md # .agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.i18n.yaml # .agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.zh.md # .agents/notes/implemented/architecture/2026-06-11-runtime-arg-validation.i18n.yaml # .agents/notes/implemented/architecture/2026-06-11-runtime-arg-validation.zh.md # .agents/notes/implemented/architecture/2026-06-11-structured-error-taxonomy.i18n.yaml # .agents/notes/implemented/architecture/2026-06-11-structured-error-taxonomy.zh.md # .agents/notes/implemented/architecture/2026-06-11-tool-schemas-in-prompt-assembly.i18n.yaml # .agents/notes/implemented/architecture/2026-06-11-tool-schemas-in-prompt-assembly.zh.md # .agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml # .agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md # .agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.i18n.yaml # .agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.zh.md # .agents/notes/implemented/architecture/2026-06-14-session-persistence.i18n.yaml # .agents/notes/implemented/architecture/2026-06-14-session-persistence.zh.md # .agents/notes/implemented/architecture/2026-06-15-turn-enclosure-invariant.i18n.yaml # .agents/notes/implemented/architecture/2026-06-15-turn-enclosure-invariant.zh.md # .agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.i18n.yaml # .agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.zh.md # .agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-seams.i18n.yaml # .agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-seams.zh.md # .agents/notes/implemented/architecture/2026-06-18-session-surface.i18n.yaml # .agents/notes/implemented/architecture/2026-06-18-session-surface.zh.md # .agents/notes/implemented/architecture/2026-06-18-shared-persistence-write-coordinator.i18n.yaml # .agents/notes/implemented/architecture/2026-06-18-shared-persistence-write-coordinator.zh.md # .agents/notes/implemented/architecture/2026-06-20-branded-ids.i18n.yaml # .agents/notes/implemented/architecture/2026-06-20-branded-ids.zh.md # .agents/notes/implemented/architecture/2026-06-20-extract-example-app-packages.i18n.yaml # .agents/notes/implemented/architecture/2026-06-20-extract-example-app-packages.zh.md # .agents/notes/implemented/architecture/2026-06-20-package-hierarchy.i18n.yaml # .agents/notes/implemented/architecture/2026-06-20-package-hierarchy.md # .agents/notes/implemented/architecture/2026-06-20-package-hierarchy.zh.md # .agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.i18n.yaml # .agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.zh.md # .agents/notes/implemented/architecture/2026-06-24-web-capability-seam.i18n.yaml # .agents/notes/implemented/architecture/2026-06-24-web-capability-seam.zh.md # .agents/notes/implemented/architecture/2026-06-26-file-context-as-event-gate.i18n.yaml # .agents/notes/implemented/architecture/2026-06-26-file-context-as-event-gate.zh.md # .agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-surface.i18n.yaml # .agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-surface.zh.md # .agents/notes/implemented/architecture/2026-06-30-event-domain-semantics.i18n.yaml # .agents/notes/implemented/architecture/2026-06-30-event-domain-semantics.zh.md # .agents/notes/implemented/architecture/2026-07-02-fs-per-session-cwd.i18n.yaml # .agents/notes/implemented/architecture/2026-07-02-fs-per-session-cwd.zh.md # .agents/notes/implemented/architecture/2026-07-02-result-time-applied-hunk-diffs.i18n.yaml # .agents/notes/implemented/architecture/2026-07-02-result-time-applied-hunk-diffs.zh.md # .agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.i18n.yaml # .agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.zh.md # .agents/notes/implemented/architecture/2026-07-03-filesystem-directory-listing-seam.i18n.yaml # .agents/notes/implemented/architecture/2026-07-03-filesystem-directory-listing-seam.zh.md # .agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.i18n.yaml # .agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.zh.md # .agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.i18n.yaml # .agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.zh.md # .agents/notes/implemented/architecture/2026-07-05-subagent-provider-lifecycle-events.i18n.yaml # .agents/notes/implemented/architecture/2026-07-05-subagent-provider-lifecycle-events.zh.md # .agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.i18n.yaml # .agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.zh.md # .agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.i18n.yaml # .agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.zh.md # .agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.i18n.yaml # .agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.zh.md # .agents/notes/implemented/architecture/2026-07-12-agent-scope-runtime-design.i18n.yaml # .agents/notes/implemented/architecture/2026-07-12-agent-scope-runtime-design.zh.md # .agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.i18n.yaml # .agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.zh.md # .agents/notes/implemented/feature/2026-06-14-acp-multi-session.i18n.yaml # .agents/notes/implemented/feature/2026-06-14-acp-multi-session.zh.md # .agents/notes/implemented/feature/2026-06-15-code-mode.i18n.yaml # .agents/notes/implemented/feature/2026-06-15-code-mode.zh.md # .agents/notes/implemented/feature/2026-06-17-filesystem-tool-schemas.i18n.yaml # .agents/notes/implemented/feature/2026-06-17-filesystem-tool-schemas.zh.md # .agents/notes/implemented/feature/2026-06-18-acp-terminal-and-tool-rendering.i18n.yaml # .agents/notes/implemented/feature/2026-06-18-acp-terminal-and-tool-rendering.zh.md # .agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.i18n.yaml # .agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.zh.md # .agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.i18n.yaml # .agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.md # .agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.zh.md # .agents/notes/implemented/feature/2026-06-22-acp-subagent-backend.i18n.yaml # .agents/notes/implemented/feature/2026-06-22-acp-subagent-backend.zh.md # .agents/notes/implemented/feature/2026-06-25-ask-user-question.i18n.yaml # .agents/notes/implemented/feature/2026-06-25-ask-user-question.zh.md # .agents/notes/implemented/feature/2026-06-29-todo-write-tool.i18n.yaml # .agents/notes/implemented/feature/2026-06-29-todo-write-tool.zh.md # .agents/notes/implemented/feature/2026-06-30-hook-bridges.i18n.yaml # .agents/notes/implemented/feature/2026-06-30-hook-bridges.zh.md # .agents/notes/implemented/feature/2026-06-30-hook-protocol-lib.i18n.yaml # .agents/notes/implemented/feature/2026-06-30-hook-protocol-lib.zh.md # .agents/notes/implemented/feature/2026-06-30-interception-seams.i18n.yaml # .agents/notes/implemented/feature/2026-06-30-interception-seams.zh.md # .agents/notes/implemented/feature/2026-06-30-session-store-fork-api.i18n.yaml # .agents/notes/implemented/feature/2026-06-30-session-store-fork-api.zh.md # .agents/notes/implemented/feature/2026-06-30-subagent-observe-enrich.i18n.yaml # .agents/notes/implemented/feature/2026-06-30-subagent-observe-enrich.zh.md # .agents/notes/implemented/feature/2026-07-05-dynamic-workflows.i18n.yaml # .agents/notes/implemented/feature/2026-07-05-dynamic-workflows.zh.md # .agents/notes/implemented/feature/2026-07-05-skill-system.i18n.yaml # .agents/notes/implemented/feature/2026-07-05-skill-system.zh.md # .agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml # .agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md # .agents/notes/implemented/feature/2026-07-06-explicit-tool-order.i18n.yaml # .agents/notes/implemented/feature/2026-07-06-explicit-tool-order.zh.md # .agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml # .agents/notes/implemented/feature/2026-07-06-sandbox.zh.md # .agents/notes/implemented/feature/2026-07-07-mcp-client-plugin.i18n.yaml # .agents/notes/implemented/feature/2026-07-07-mcp-client-plugin.zh.md # .agents/notes/implemented/feature/2026-07-07-session-prefix.i18n.yaml # .agents/notes/implemented/feature/2026-07-07-session-prefix.zh.md # .agents/notes/implemented/feature/2026-07-08-repeat-tool-guard.i18n.yaml # .agents/notes/implemented/feature/2026-07-08-repeat-tool-guard.zh.md # .agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.i18n.yaml # .agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.zh.md # .agents/notes/implemented/feature/2026-07-10-session-query-service.i18n.yaml # .agents/notes/implemented/feature/2026-07-10-session-query-service.zh.md # .agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.i18n.yaml # .agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.zh.md # .agents/notes/implemented/process/2026-06-11-doc-sync-enforcement.i18n.yaml # .agents/notes/implemented/process/2026-06-11-doc-sync-enforcement.zh.md # .agents/notes/implemented/process/2026-06-11-quality-gates.i18n.yaml # .agents/notes/implemented/process/2026-06-11-quality-gates.md # .agents/notes/implemented/process/2026-06-11-quality-gates.zh.md # .agents/notes/implemented/process/2026-06-11-tsdown-over-dumble.i18n.yaml # .agents/notes/implemented/process/2026-06-11-tsdown-over-dumble.zh.md # .agents/notes/implemented/process/2026-06-11-vendor-cordis-as-source.i18n.yaml # .agents/notes/implemented/process/2026-06-11-vendor-cordis-as-source.zh.md # .agents/notes/implemented/process/2026-06-16-pnpm-over-yarn.i18n.yaml # .agents/notes/implemented/process/2026-06-16-pnpm-over-yarn.zh.md # .agents/notes/implemented/process/2026-06-17-ts-build-config.i18n.yaml # .agents/notes/implemented/process/2026-06-17-ts-build-config.zh.md # .agents/notes/implemented/process/2026-06-18-markdown-cross-link-lint.i18n.yaml # .agents/notes/implemented/process/2026-06-18-markdown-cross-link-lint.zh.md # .agents/notes/implemented/process/2026-06-20-core-data-structures-catalog.i18n.yaml # .agents/notes/implemented/process/2026-06-20-core-data-structures-catalog.zh.md # .agents/notes/implemented/process/2026-06-20-generated-cordis-catalog.i18n.yaml # .agents/notes/implemented/process/2026-06-20-generated-cordis-catalog.zh.md # .agents/notes/implemented/process/2026-06-20-rfc-classification.i18n.yaml # .agents/notes/implemented/process/2026-06-20-rfc-classification.zh.md # .agents/notes/implemented/process/2026-07-02-tool-schema-catalog.i18n.yaml # .agents/notes/implemented/process/2026-07-02-tool-schema-catalog.zh.md # .agents/notes/implemented/process/2026-07-03-documentation-graph-atlas.i18n.yaml # .agents/notes/implemented/process/2026-07-03-documentation-graph-atlas.zh.md # .agents/notes/implemented/process/2026-07-04-cordis-jsdoc-completeness-gate.i18n.yaml # .agents/notes/implemented/process/2026-07-04-cordis-jsdoc-completeness-gate.zh.md # .agents/notes/implemented/process/2026-07-04-doc-tiers-and-budgets.i18n.yaml # .agents/notes/implemented/process/2026-07-04-doc-tiers-and-budgets.zh.md # .agents/notes/implemented/process/2026-07-04-generate-rfc-index-tables.i18n.yaml # .agents/notes/implemented/process/2026-07-04-generate-rfc-index-tables.zh.md # .agents/notes/implemented/process/2026-07-04-persistence-log-catalog.i18n.yaml # .agents/notes/implemented/process/2026-07-04-persistence-log-catalog.zh.md # .agents/notes/implemented/process/2026-07-05-uniform-rfc-format.i18n.yaml # .agents/notes/implemented/process/2026-07-05-uniform-rfc-format.zh.md # .agents/notes/implemented/process/2026-07-06-export-surface-jsdoc-gate.i18n.yaml # .agents/notes/implemented/process/2026-07-06-export-surface-jsdoc-gate.zh.md # .agents/notes/implemented/process/2026-07-06-generated-config-catalog.i18n.yaml # .agents/notes/implemented/process/2026-07-06-generated-config-catalog.zh.md # .agents/notes/implemented/process/2026-07-06-node-engine-floor.i18n.yaml # .agents/notes/implemented/process/2026-07-06-node-engine-floor.zh.md # .agents/notes/implemented/process/2026-07-06-parallel-github-ci-gates.i18n.yaml # .agents/notes/implemented/process/2026-07-06-parallel-github-ci-gates.zh.md # .agents/notes/implemented/process/2026-07-06-parallel-pre-push-gates.i18n.yaml # .agents/notes/implemented/process/2026-07-06-parallel-pre-push-gates.zh.md # .agents/notes/implemented/process/2026-07-10-readme-known-limitations-gate.i18n.yaml # .agents/notes/implemented/process/2026-07-10-readme-known-limitations-gate.zh.md # .agents/notes/implemented/process/2026-07-12-package-model-experience-contract.i18n.yaml # .agents/notes/implemented/process/2026-07-12-package-model-experience-contract.zh.md # .agents/notes/implemented/simplification/2026-06-19-drop-mutable-session-summary.i18n.yaml # .agents/notes/implemented/simplification/2026-06-19-drop-mutable-session-summary.zh.md # .agents/notes/implemented/simplification/2026-06-20-collapse-trace-only-session-events.i18n.yaml # .agents/notes/implemented/simplification/2026-06-20-collapse-trace-only-session-events.zh.md # .agents/notes/implemented/simplification/2026-06-20-drop-unconsumed-llm-adapter-change-event.i18n.yaml # .agents/notes/implemented/simplification/2026-06-20-drop-unconsumed-llm-adapter-change-event.zh.md # .agents/notes/implemented/simplification/2026-06-20-drop-unconsumed-llm-assembled-surfaces.i18n.yaml # .agents/notes/implemented/simplification/2026-06-20-drop-unconsumed-llm-assembled-surfaces.zh.md # .agents/notes/implemented/simplification/2026-06-20-prune-dead-seam-methods.i18n.yaml # .agents/notes/implemented/simplification/2026-06-20-prune-dead-seam-methods.md # .agents/notes/implemented/simplification/2026-06-20-prune-dead-seam-methods.zh.md # .agents/notes/implemented/simplification/2026-06-20-public-agent-stop-surface.i18n.yaml # .agents/notes/implemented/simplification/2026-06-20-public-agent-stop-surface.zh.md # .agents/notes/implemented/simplification/2026-06-20-remove-agent-boundary-mirror-events.i18n.yaml # .agents/notes/implemented/simplification/2026-06-20-remove-agent-boundary-mirror-events.zh.md # .agents/notes/implemented/simplification/2026-06-26-fsspec-style-fs-seam.i18n.yaml # .agents/notes/implemented/simplification/2026-06-26-fsspec-style-fs-seam.zh.md # .agents/notes/implemented/simplification/2026-07-02-remove-stream-chunk-mirror.i18n.yaml # .agents/notes/implemented/simplification/2026-07-02-remove-stream-chunk-mirror.zh.md # .agents/notes/implemented/simplification/2026-07-04-drop-image-content-block.i18n.yaml # .agents/notes/implemented/simplification/2026-07-04-drop-image-content-block.zh.md # .agents/notes/implemented/simplification/2026-07-04-drop-inert-request-knobs.i18n.yaml # .agents/notes/implemented/simplification/2026-07-04-drop-inert-request-knobs.zh.md # .agents/notes/implemented/simplification/2026-07-04-drop-unconsumed-web-observation-surface.i18n.yaml # .agents/notes/implemented/simplification/2026-07-04-drop-unconsumed-web-observation-surface.zh.md # .agents/notes/implemented/simplification/2026-07-04-fold-stdio-ui-helper.i18n.yaml # .agents/notes/implemented/simplification/2026-07-04-fold-stdio-ui-helper.md # .agents/notes/implemented/simplification/2026-07-04-fold-stdio-ui-helper.zh.md # .agents/notes/implemented/simplification/2026-07-04-prune-producerless-vocabulary-variants.i18n.yaml # .agents/notes/implemented/simplification/2026-07-04-prune-producerless-vocabulary-variants.zh.md # .agents/notes/implemented/simplification/2026-07-04-prune-write-only-fs-surface.i18n.yaml # .agents/notes/implemented/simplification/2026-07-04-prune-write-only-fs-surface.zh.md # .agents/notes/implemented/simplification/2026-07-04-remove-agent-steering-mirror.i18n.yaml # .agents/notes/implemented/simplification/2026-07-04-remove-agent-steering-mirror.zh.md # .agents/notes/implemented/simplification/2026-07-04-share-app-bin-boot-glue.i18n.yaml # .agents/notes/implemented/simplification/2026-07-04-share-app-bin-boot-glue.zh.md # .agents/notes/implemented/simplification/2026-07-04-tighten-hook-protocol-contract.i18n.yaml # .agents/notes/implemented/simplification/2026-07-04-tighten-hook-protocol-contract.zh.md # .agents/notes/implemented/simplification/2026-07-04-trim-acp-bridge-unreachable-surface.i18n.yaml # .agents/notes/implemented/simplification/2026-07-04-trim-acp-bridge-unreachable-surface.zh.md # .agents/notes/implemented/simplification/2026-07-12-drop-unconsumed-skill-provider-events.i18n.yaml # .agents/notes/implemented/simplification/2026-07-12-drop-unconsumed-skill-provider-events.zh.md # .agents/notes/implemented/simplification/2026-07-12-prune-unused-web-seam-fields.i18n.yaml # .agents/notes/implemented/simplification/2026-07-12-prune-unused-web-seam-fields.zh.md # .agents/notes/implemented/testing/2026-06-11-property-based-testing.i18n.yaml # .agents/notes/implemented/testing/2026-06-11-property-based-testing.zh.md # .agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.i18n.yaml # .agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.zh.md # .agents/notes/implemented/testing/2026-06-19-real-api-e2e-ci.i18n.yaml # .agents/notes/implemented/testing/2026-06-19-real-api-e2e-ci.zh.md # .agents/notes/implemented/testing/2026-06-20-remove-redundant-snapshot-log-goldens.i18n.yaml # .agents/notes/implemented/testing/2026-06-20-remove-redundant-snapshot-log-goldens.zh.md # .agents/notes/implemented/testing/2026-06-22-fork-child-replay-seed-boundary.i18n.yaml # .agents/notes/implemented/testing/2026-06-22-fork-child-replay-seed-boundary.zh.md # .agents/notes/implemented/testing/2026-06-22-fork-snapshot-scenarios.i18n.yaml # .agents/notes/implemented/testing/2026-06-22-fork-snapshot-scenarios.zh.md # .agents/notes/implemented/testing/2026-06-22-subagent-snapshot-replay.i18n.yaml # .agents/notes/implemented/testing/2026-06-22-subagent-snapshot-replay.zh.md # .agents/notes/implemented/testing/2026-07-04-hook-snapshot-matrix.i18n.yaml # .agents/notes/implemented/testing/2026-07-04-hook-snapshot-matrix.zh.md # .agents/notes/implemented/testing/2026-07-04-single-source-acp-replay-config.i18n.yaml # .agents/notes/implemented/testing/2026-07-04-single-source-acp-replay-config.zh.md # .agents/notes/implemented/testing/2026-07-06-pin-request-header-content-in-one-scenario.i18n.yaml # .agents/notes/implemented/testing/2026-07-06-pin-request-header-content-in-one-scenario.zh.md # .agents/notes/implemented/testing/2026-07-08-shared-acp-snapshot-package.i18n.yaml # .agents/notes/implemented/testing/2026-07-08-shared-acp-snapshot-package.zh.md # .agents/notes/proposed/architecture/2026-06-16-typed-event-schemas.i18n.yaml # .agents/notes/proposed/architecture/2026-06-16-typed-event-schemas.zh.md # .agents/notes/proposed/architecture/2026-06-20-generic-long-running-tool-runtime.i18n.yaml # .agents/notes/proposed/architecture/2026-06-20-generic-long-running-tool-runtime.zh.md # .agents/notes/proposed/feature/2026-06-30-pre-tool-input-rewrite.i18n.yaml # .agents/notes/proposed/feature/2026-06-30-pre-tool-input-rewrite.zh.md # .agents/notes/proposed/feature/2026-07-07-claude-code-and-codex-subagent-backends.i18n.yaml # .agents/notes/proposed/feature/2026-07-07-claude-code-and-codex-subagent-backends.zh.md # .agents/notes/proposed/feature/2026-07-08-interactive-side-sessions.i18n.yaml # .agents/notes/proposed/feature/2026-07-08-interactive-side-sessions.zh.md # .agents/notes/proposed/feature/2026-07-10-sqlite-session-query-provider.i18n.yaml # .agents/notes/proposed/feature/2026-07-10-sqlite-session-query-provider.zh.md # .agents/notes/proposed/feature/2026-07-13-stream-workflow-progress-through-tool-calls.i18n.yaml # .agents/notes/proposed/feature/2026-07-13-stream-workflow-progress-through-tool-calls.zh.md # .agents/notes/proposed/process/2026-06-11-api-extractor-reports.i18n.yaml # .agents/notes/proposed/process/2026-06-11-api-extractor-reports.md # .agents/notes/proposed/process/2026-06-11-api-extractor-reports.zh.md # .agents/notes/proposed/process/2026-06-11-architectural-conformance.i18n.yaml # .agents/notes/proposed/process/2026-06-11-architectural-conformance.zh.md # .agents/notes/proposed/process/2026-06-11-supply-chain-and-vendor-drift.i18n.yaml # .agents/notes/proposed/process/2026-06-11-supply-chain-and-vendor-drift.zh.md # .agents/notes/proposed/process/2026-06-20-discover-package-inventory.i18n.yaml # .agents/notes/proposed/process/2026-06-20-discover-package-inventory.zh.md # .agents/notes/proposed/simplification/2026-06-20-unify-agent-and-session-id.i18n.yaml # .agents/notes/proposed/simplification/2026-06-20-unify-agent-and-session-id.zh.md # .agents/notes/proposed/simplification/2026-07-04-prune-dead-core-spine-surface.i18n.yaml # .agents/notes/proposed/simplification/2026-07-04-prune-dead-core-spine-surface.zh.md # .agents/notes/proposed/simplification/2026-07-12-simplify-session-log-representation.i18n.yaml # .agents/notes/proposed/simplification/2026-07-12-simplify-session-log-representation.zh.md # .agents/notes/proposed/testing/2026-06-11-deterministic-and-stress-testing.i18n.yaml # .agents/notes/proposed/testing/2026-06-11-deterministic-and-stress-testing.zh.md # .agents/notes/proposed/testing/2026-06-11-mutation-testing.i18n.yaml # .agents/notes/proposed/testing/2026-06-11-mutation-testing.zh.md # .agents/notes/rejected/architecture/2026-06-11-immutable-public-surfaces.i18n.yaml # .agents/notes/rejected/architecture/2026-06-11-immutable-public-surfaces.zh.md # .agents/notes/rejected/architecture/2026-06-20-providerless-example-base.i18n.yaml # .agents/notes/rejected/architecture/2026-06-20-providerless-example-base.zh.md # .agents/notes/rejected/simplification/2026-06-20-assembled-assistant-messages-only.i18n.yaml # .agents/notes/rejected/simplification/2026-06-20-assembled-assistant-messages-only.zh.md # .agents/notes/rejected/simplification/2026-06-20-drop-acp-session-load.i18n.yaml # .agents/notes/rejected/simplification/2026-06-20-drop-acp-session-load.zh.md # .agents/notes/rejected/simplification/2026-06-20-drop-acp-terminal-meta.i18n.yaml # .agents/notes/rejected/simplification/2026-06-20-drop-acp-terminal-meta.zh.md # .agents/notes/rejected/simplification/2026-06-20-drop-bash-output-spill-files.i18n.yaml # .agents/notes/rejected/simplification/2026-06-20-drop-bash-output-spill-files.zh.md # .agents/notes/rejected/simplification/2026-06-20-drop-durable-step-boundaries.i18n.yaml # .agents/notes/rejected/simplification/2026-06-20-drop-durable-step-boundaries.zh.md # .agents/notes/rejected/simplification/2026-06-20-drop-unused-session-lineage.i18n.yaml # .agents/notes/rejected/simplification/2026-06-20-drop-unused-session-lineage.zh.md # .agents/notes/rejected/simplification/2026-06-20-fold-session-persistence-interface.i18n.yaml # .agents/notes/rejected/simplification/2026-06-20-fold-session-persistence-interface.zh.md # .agents/notes/rejected/simplification/2026-06-20-generic-tool-rendering.i18n.yaml # .agents/notes/rejected/simplification/2026-06-20-generic-tool-rendering.zh.md # .agents/notes/rejected/simplification/2026-06-20-retire-mid-turn-steering.i18n.yaml # .agents/notes/rejected/simplification/2026-06-20-retire-mid-turn-steering.zh.md # .agents/notes/rejected/simplification/2026-06-20-single-session-acp-bridge.i18n.yaml # .agents/notes/rejected/simplification/2026-06-20-single-session-acp-bridge.zh.md # .agents/notes/rejected/simplification/2026-06-20-truncate-interrupted-turns.i18n.yaml # .agents/notes/rejected/simplification/2026-06-20-truncate-interrupted-turns.zh.md # .agents/notes/rejected/simplification/2026-07-04-prune-unimplemented-subagent-vocabulary.i18n.yaml # .agents/notes/rejected/simplification/2026-07-04-prune-unimplemented-subagent-vocabulary.zh.md # .agents/notes/rejected/simplification/2026-07-12-collapse-workflow-to-foreground-core.i18n.yaml # .agents/notes/rejected/simplification/2026-07-12-collapse-workflow-to-foreground-core.zh.md # .agents/notes/rejected/simplification/2026-07-12-prune-unused-skill-registry-surface.i18n.yaml # .agents/notes/rejected/simplification/2026-07-12-prune-unused-skill-registry-surface.zh.md # docs/rfc/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-seams.md # docs/rfc/implemented/architecture/2026-06-18-session-surface.md # docs/rfc/implemented/architecture/2026-06-20-branded-ids.md # docs/rfc/implemented/architecture/2026-07-02-fs-per-session-cwd.md # docs/rfc/implemented/feature/2026-06-18-compaction-capability-seam.md # docs/rfc/implemented/feature/2026-07-07-session-prefix.md # docs/rfc/implemented/process/2026-06-20-rfc-classification.md # docs/rfc/implemented/process/2026-07-04-generate-rfc-index-tables.md # docs/rfc/implemented/process/2026-07-05-uniform-rfc-format.md # docs/rfc/implemented/process/2026-07-06-parallel-github-ci-gates.md # docs/rfc/implemented/process/2026-07-06-parallel-pre-push-gates.md # docs/rfc/implemented/process/2026-07-12-package-model-experience-contract.md # docs/rfc/implemented/simplification/2026-06-20-remove-agent-boundary-mirror-events.md # docs/rfc/implemented/simplification/2026-07-04-prune-producerless-vocabulary-variants.md # docs/rfc/implemented/testing/2026-06-20-remove-redundant-snapshot-log-goldens.md # docs/rfc/implemented/testing/2026-07-08-shared-acp-snapshot-package.md # docs/rfc/proposed/architecture/2026-06-20-generic-long-running-tool-runtime.md # docs/rfc/proposed/simplification/2026-06-20-unify-agent-and-session-id.md # docs/rfc/proposed/simplification/2026-07-12-simplify-session-log-representation.md # docs/rfc/rejected/simplification/2026-07-04-prune-unimplemented-subagent-vocabulary.md # scripts/translation-pairing.manifest.json
49 lines
8.2 KiB
Markdown
49 lines
8.2 KiB
Markdown
# Agent Note: Rich ACP bash rendering — the terminal card via the `_meta` convention
|
|
|
|
Status: implemented
|
|
|
|
English | [中文](2026-06-18-acp-terminal-and-tool-rendering.zh.md)
|
|
|
|
## Problem
|
|
|
|
The ACP bridge lets each tool own its call rendering via `presentCall`/`presentResult` (see [tool-call UI presentation](2026-06-14-acp-agent-client-protocol.md) and `packages/core/tools`). For `bash` we surface the exact command as the `tool_call` title, the model's `description` as a content text block, `kind: 'execute'`, and the completed output wrapped in a fenced ` ```console ` text block.
|
|
|
|
Reference editors render terminal metadata as a dedicated card with cwd, command, live-style output, and exit status; plain text loses that structure. The command is the title because execute cards hide raw input, while the human-readable description remains a separate block above the card.
|
|
|
|
## Key finding: agent-executed terminals use a `_meta` convention, NOT `terminal/create`
|
|
|
|
The ACP spec has a *client-side* terminal sub-protocol — the agent calls the client's `terminal/create` with `{ command, args, cwd, env }` and the **editor** executes the process, then the agent reads `terminal/output` / `wait_for_exit`. That model is wrong for us: our harness executes bash itself through `dsh-bash` (sandboxed env-scrub, background-task ownership, per-session cwd). Routing execution to the editor would bypass all of that and fork execution into two backends.
|
|
|
|
Studying the two reference agents (2026-06-18) shows neither uses `terminal/create` for their own shell tool — **both keep agent-side execution and emit a `_meta` convention** that Zed special-cases:
|
|
|
|
- **`claude-agent-acp`** (`tools.ts`, `acp-agent.ts`): gated on `clientCapabilities._meta.terminal_output`. The `tool_call` carries `content: [{ type: 'terminal', terminalId }]` and `_meta.terminal_info.{ terminal_id, cwd }`; output/exit arrive on the `tool_call_update`'s `_meta.terminal_output.{ terminal_id, data }` and `_meta.terminal_exit.{ terminal_id, exit_code, signal }`.
|
|
- **`codex-acp`** (`CodexToolCallMapper.ts`, `TerminalOutputMode.ts`): same `terminal_info` on the call; output via `_meta.terminal_output` (full) or `_meta.terminal_output_delta` (incremental), selected from the same `_meta.terminal_output` capability.
|
|
|
|
Zed's side (`crates/agent_servers/src/acp.rs`, verified): on a `ToolCall` whose `_meta.terminal_info.terminal_id` is set, it registers a **display-only** terminal (header = `terminal_info.cwd`, label = `tool_call.title`); on a `ToolCallUpdate`, `_meta.terminal_output.data` writes to that terminal and `_meta.terminal_exit.{exit_code,signal}` sets the status. It advertises the capability as `clientCapabilities._meta.terminal_output = true`. `_meta` itself is a spec-blessed ACP extensibility point (typed `{[k]: unknown} | null` on `ToolCall`/`ToolCallUpdate`); the *specific keys* here (`terminal_info`/`terminal_output`/`terminal_exit`) are a Zed convention, not part of the ACP spec — but they are the de-facto contract for the Zed integration and the only way to get the terminal card while keeping execution agent-side.
|
|
|
|
## Decision
|
|
|
|
Keep `dsh-bash` agent-side execution; render the terminal card via the `_meta` convention, capability-gated, with the ` ```console ` text block as the guaranteed fallback.
|
|
|
|
1. **Capability.** `initialize` reads `clientCapabilities._meta.terminal_output` and the bridge remembers it per connection.
|
|
2. **Neutral presentation vocabulary.** `dsh-tools` gains a terminal-shaped presentation a tool can return — provider-neutral (`cwd`, the output `data`, an `exitCode`/`signal`), NO ACP types. `dsh-tool-bash` returns it for `bash` (cwd from the resolved workdir; output + exit parsed from the run result).
|
|
3. **Bridge mapping.** When the client advertised the capability, the bridge maps that presentation to: on `tool_call`, `content:[…, {type:'terminal', terminalId}]` (any tool `content`, e.g. the description, rendered BEFORE the terminal block) + `_meta.terminal_info.{terminal_id,cwd}`; on `tool_call_update`, `_meta.terminal_output.{terminal_id,data}` (the captured output) + `_meta.terminal_exit.{terminal_id, exit_code|signal}` (the parsed exit), with the update's text `content` OMITTED (an ACP `tool_call_update.content` REPLACES the call's content collection, so re-sending the fenced block would clobber the terminal content block). `terminalId` is derived from the harness `callId` (stable, unique per call). When the capability is absent, the bridge sends the description content block on the call and the existing ` ```console ` text content on the update — unchanged.
|
|
4. **The exit pill is parsed from the rendered output; no new execution path, no live streaming.** Output is attached at completion (from the agent's own `tool/result`), not streamed token-by-token. The exit-status pill (`_meta.terminal_exit.{exit_code,signal}`) IS emitted: the pure `presentResult(args, result)` seam sees only content blocks, so `dsh-tool-bash` recovers the structured exit by parsing the status markers (`[exit code: N]` / `[killed by signal: …]`) that `renderResult` appended — the parse is the exact inverse of the marker emission, the two co-evolve in one file, and a round-trip test guards the pair. Disposal is unaffected: nothing new to tear down, since the bridge never creates a client-side terminal.
|
|
|
|
## Alternatives considered
|
|
|
|
- **The ACP client-side terminal sub-protocol (`terminal/create`)** — explicitly rejected: the editor would execute the process, bypassing `dsh-bash`'s env scrub, background-task ownership, and per-session cwd, and forking execution into two backends. Both reference agents reject it the same way (the key finding above); agent-side execution plus the `_meta` convention is the only shape that yields the terminal card while keeping the harness's execution policy.
|
|
- **Threading a structured exit through the event schema** — rejected in favor of the marker round-trip: the pure `presentResult(args, result)` seam sees only content blocks, and the parse is the exact inverse of the marker emission, co-evolving in one file under a round-trip test.
|
|
|
|
## Consequences
|
|
|
|
- **Zed-convention `_meta` keys.** The terminal card rides on Zed-specific keys (`terminal_info`/`terminal_output`/`terminal_exit`) inside ACP's spec-blessed `_meta` extensibility point, NOT on the ACP terminal sub-protocol. A client that doesn't recognize the keys still gets the text fallback (the capability gate ensures we only emit them when the client opted in via `_meta.terminal_output`), so a non-Zed client is never worse off. If ACP later standardizes agent-executed terminals, migrate to that and drop the convention keys.
|
|
- **Capability honesty.** Emit terminal metadata ONLY when the client advertised `_meta.terminal_output`; the text fallback is the contract for everyone else and must never regress. Covered by a no-capability test asserting the ` ```console ` path.
|
|
- **terminalId collisions.** Deriving it from the per-call `callId` keeps it unique within a session and stable across the call/result pair; never reuse one across calls.
|
|
- **Exit parsed from rendered text.** The exit pill recovers `exit_code`/`signal` by parsing `renderResult`'s status markers rather than threading a structured exit through the event schema (which the pure `presentResult` seam never sees). The parse is the exact inverse of the marker emission and lives in the same file; a round-trip test pins the pair so a marker-format change that breaks the parse fails the suite. If the markers ever need to diverge from what the pill wants, surface a structured exit on the result event instead.
|
|
- **Provider-neutral vocabulary creep.** The terminal presentation widens the `dsh-tools` surface; keep it neutral (no ACP types leak into `dsh-tools`) and only as rich as a second UI consumer would also want.
|
|
|
|
## Out of scope / non-goals
|
|
|
|
The text-block baseline stays the no-capability default. Two follow-ups are deliberately NOT built here and would each warrant their own Agent Note when someone takes them on: **live incremental streaming** (`_meta.terminal_output_delta` as chunks arrive, which needs an incremental-output seam on `dsh-bash`), and **command classification** (parsing a `cat`/`sed` as a `read` card with a file location, a `grep` as a `search`, etc., falling back to the terminal card — display-only, must never change what executes).
|