diff --git a/.agents/notes/README.i18n.yaml b/.agents/notes/README.i18n.yaml index f6289cf96f..1fa95a5e2d 100644 --- a/.agents/notes/README.i18n.yaml +++ b/.agents/notes/README.i18n.yaml @@ -1,6 +1,46 @@ -# 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: +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/README.md -README.md: 6872de0a1390fa5a1707b9f464c9e0edeb2da4be -README.zh.md: ced81f77fa904ad0b5cb5219383ef651d87392b8 +/agent-notes: + en: a10991a192c7b55d + zh: c2e5b938ece4f366 +/agent-notes/layout-and-naming: + en: 6b38cb0eb38c2baf + zh: 535234fb23fc8921 +/agent-notes/classification: + en: 055a5e49f9af3dc2 + zh: 9f7c78409cccfded +/agent-notes/archiving-and-deletion: + en: 6c393c7058c787d7 + zh: 70ce9ca3bd9c2133 +/agent-notes/when-to-write-one: + en: 2beb1b94d8fb633c + zh: 889b5542bb771205 +/agent-notes/the-file-format: + en: 601f85df49f80fc7 + zh: acbd0955d6543b13 +/agent-notes/the-file-format/the-header-block: + en: 16fdaab0c74a5bb5 + zh: 2553f145a1eb878f +/agent-notes/the-file-format/the-body-skeleton: + en: 740b7e964b9aec37 + zh: 8551ddef1ffa776a +/agent-notes/the-file-format/the-body-skeleton/proposed: + en: acc0c035c5ca6fd7 + zh: 8a65816dfac9e580 +/agent-notes/the-file-format/the-body-skeleton/implemented: + en: f3523d7e40cc4e2f + zh: 574fa8959f8829a1 +/agent-notes/the-file-format/the-body-skeleton/rejected: + en: f0ff5d05191f2315 + zh: 3f9df0dd01a5cbed +/agent-notes/the-file-format/alternatives-considered-mandatory: + en: fe1bf385aee54033 + zh: 37cb4ea86ec6d99d +/agent-notes/the-file-format/moving-between-lifecycles: + en: d3f18ba194dfb677 + zh: 3d202868deda2f31 +/agent-notes/the-file-format/chinese-counterparts: + en: d72a33b7c63722b2 + zh: f8320c91b1f77ae6 diff --git a/.agents/notes/archived/manifest.json b/.agents/notes/archived/manifest.json index 6fc82fe8a6..5ed6850038 100644 --- a/.agents/notes/archived/manifest.json +++ b/.agents/notes/archived/manifest.json @@ -754,12 +754,12 @@ "bug-fix/2026-09-09-content-sized-diagram-previews.i18n.yaml": "sha256:a4404fe8e35ca5b6371f9cdb58fea6724cf3e7737bb2db8a3a321d534454b17c", "bug-fix/2026-09-09-content-sized-diagram-previews.md": "sha256:5239e98e5c057d6f7e10c3f10a0f67273778d99b0c4f10b31a1921c3c6474b80", "bug-fix/2026-09-09-content-sized-diagram-previews.zh.md": "sha256:c1ee3790a9d5c3561e1d93d5e649afa904c7d19b9d77248c85ef16daccd953e2", - "bug-fix/2026-09-16-movable-mandatory-update-window.i18n.yaml": "sha256:e526ce14ae9557e24364e3686778b130090445ef2152d976b7cc93e76eac6401", - "bug-fix/2026-09-16-movable-mandatory-update-window.md": "sha256:67546cea0b3de2b3e32957a508dbde097d91dd919fe067c8dbecb2c65b50c366", - "bug-fix/2026-09-16-movable-mandatory-update-window.zh.md": "sha256:20a0aade6ee71c89e84d70e23c89bb51e8a38c674d103dd43022feabb8d27be3", "bug-fix/2026-09-11-session-controller-fork-turn-cut.i18n.yaml": "sha256:4442529ced1c8e48d30f7b50c65ff03eb92dce9815beb438cedbf29f234bce47", "bug-fix/2026-09-11-session-controller-fork-turn-cut.md": "sha256:a996f24a896c7fc5d81e015db3eae27d8a46c853287572e815623ce35eae1b12", "bug-fix/2026-09-11-session-controller-fork-turn-cut.zh.md": "sha256:6486f0eacf5067ef9850dc32f1c27b2109a7d4e9e3c498366f5c38742bb53ac5", + "bug-fix/2026-09-16-movable-mandatory-update-window.i18n.yaml": "sha256:e526ce14ae9557e24364e3686778b130090445ef2152d976b7cc93e76eac6401", + "bug-fix/2026-09-16-movable-mandatory-update-window.md": "sha256:67546cea0b3de2b3e32957a508dbde097d91dd919fe067c8dbecb2c65b50c366", + "bug-fix/2026-09-16-movable-mandatory-update-window.zh.md": "sha256:20a0aade6ee71c89e84d70e23c89bb51e8a38c674d103dd43022feabb8d27be3", "feature/2026-06-14-acp-agent-client-protocol.i18n.yaml": "sha256:006795baa43ae962a8d125cc0f1e9f134bc2ee9fb758b6e7669e3fa0126e1918", "feature/2026-06-14-acp-agent-client-protocol.md": "sha256:6828c0af74bb3fb96206ca6b21c0e56a000b50e4744aad4bc2c05092f3a5a31b", "feature/2026-06-14-acp-agent-client-protocol.zh.md": "sha256:ba104e841a1fb84edbd3b6c8119d50445b7785255a7a8d13bb9ac8a2cb4d2e69", @@ -1561,6 +1561,9 @@ "process/2026-08-08-api-remotes-generated-contract-build.i18n.yaml": "sha256:da10469121712bd6ac4fb1f665ca8bd59597a94b56324d2fe4bdef5235498b6e", "process/2026-08-08-api-remotes-generated-contract-build.md": "sha256:8c3d7712cce4913cd3c02d1ac2b87def3f7104a7503681afc3c755896ac45d1f", "process/2026-08-08-api-remotes-generated-contract-build.zh.md": "sha256:e32e1f53c763e769d152c8c41cf8f8977210e82a0d3f7cc7f0421da7e589e9ad", + "process/2026-08-08-automatic-translation-pairing-merges.i18n.yaml": "sha256:5398ef0c48258d3f3a9881e2b34fc4e2086a0b8084b8d7100798dbca6cc39887", + "process/2026-08-08-automatic-translation-pairing-merges.md": "sha256:fb1f3df3246151da920c14fdf195b0cb3bf595a2eed639c84baf70e3f56d36ce", + "process/2026-08-08-automatic-translation-pairing-merges.zh.md": "sha256:9ce7ff6f511ce973637f001b119ce323a5efe0be57cc11d12691aaa36199a8b8", "process/2026-08-08-lightweight-routine-documentation-translation.i18n.yaml": "sha256:f3b44e6148941de9840ef54be60e60ed6ec32ee04b42a1a472e38838b6aa7b14", "process/2026-08-08-lightweight-routine-documentation-translation.md": "sha256:264fe2ee2338053a11fe0f0d5ccf12772897fe9fd4f4a7e8a1d6ba226f853e14", "process/2026-08-08-lightweight-routine-documentation-translation.zh.md": "sha256:3d309e2fc34a6a99bbce4891c32d681e0a23b233791b29a550884f3e753d593c", diff --git a/.agents/notes/archived/process/2026-08-08-automatic-translation-pairing-merges.i18n.yaml b/.agents/notes/archived/process/2026-08-08-automatic-translation-pairing-merges.i18n.yaml new file mode 100644 index 0000000000..48d9fbaaac --- /dev/null +++ b/.agents/notes/archived/process/2026-08-08-automatic-translation-pairing-merges.i18n.yaml @@ -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 .agents/notes/archived/process/2026-08-08-automatic-translation-pairing-merges.md +2026-08-08-automatic-translation-pairing-merges.md: ed693e376d056378b27a8995a6f26fefcdba34b2 +2026-08-08-automatic-translation-pairing-merges.zh.md: 827475a92824c22ee6f4c558de81b645c3c2b8dc diff --git a/.agents/notes/implemented/process/2026-08-08-automatic-translation-pairing-merges.md b/.agents/notes/archived/process/2026-08-08-automatic-translation-pairing-merges.md similarity index 99% rename from .agents/notes/implemented/process/2026-08-08-automatic-translation-pairing-merges.md rename to .agents/notes/archived/process/2026-08-08-automatic-translation-pairing-merges.md index ac4e0c1129..ed693e376d 100644 --- a/.agents/notes/implemented/process/2026-08-08-automatic-translation-pairing-merges.md +++ b/.agents/notes/archived/process/2026-08-08-automatic-translation-pairing-merges.md @@ -1,6 +1,7 @@ # Agent Note: Automatically compose translation pairing records Status: implemented +Archived: 2026-09-23 English | [中文](2026-08-08-automatic-translation-pairing-merges.zh.md) diff --git a/.agents/notes/implemented/process/2026-08-08-automatic-translation-pairing-merges.zh.md b/.agents/notes/archived/process/2026-08-08-automatic-translation-pairing-merges.zh.md similarity index 99% rename from .agents/notes/implemented/process/2026-08-08-automatic-translation-pairing-merges.zh.md rename to .agents/notes/archived/process/2026-08-08-automatic-translation-pairing-merges.zh.md index 820ebdbe8c..827475a928 100644 --- a/.agents/notes/implemented/process/2026-08-08-automatic-translation-pairing-merges.zh.md +++ b/.agents/notes/archived/process/2026-08-08-automatic-translation-pairing-merges.zh.md @@ -1,6 +1,7 @@ # Agent Note: 自动组合翻译配对记录 Status: implemented +Archived: 2026-09-23 [English](2026-08-08-automatic-translation-pairing-merges.md) | 中文 diff --git a/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml index b62c09f26c..5e1614518c 100644 --- a/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-11-content-block-vocabulary.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.md -2026-06-11-content-block-vocabulary.md: 917dd5225fdc4ab391e9e4629769abbb68095731 -2026-06-11-content-block-vocabulary.zh.md: 9d228eb34dafbdebab44b45dc3b290c9327d3b2b +/agent-note-provider-neutral-content-block-vocabulary-owned-by-dsh-llm: + en: 64935f5c8e315004 + zh: 6a9cbb4578eaa437 +/agent-note-provider-neutral-content-block-vocabulary-owned-by-dsh-llm/problem: + en: 4e81df7bca1c1638 + zh: f7483d180a613237 +/agent-note-provider-neutral-content-block-vocabulary-owned-by-dsh-llm/decision: + en: 9526dfcf4da1d000 + zh: ea2bf79a02b26b39 +/agent-note-provider-neutral-content-block-vocabulary-owned-by-dsh-llm/alternatives-considered: + en: 1de2e19e711105e6 + zh: a2cd5a64cc4e9e73 +/agent-note-provider-neutral-content-block-vocabulary-owned-by-dsh-llm/consequences: + en: 999d10e69e447e44 + zh: 38370da5b900ac30 diff --git a/.agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.i18n.yaml index 6578c0b2a2..d01dd83fdb 100644 --- a/.agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-11-dev-invariants-over-deep-readonly.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.md -2026-06-11-dev-invariants-over-deep-readonly.md: 0784960397f4d198e136e284ef9232b4ed3e2c2c -2026-06-11-dev-invariants-over-deep-readonly.zh.md: 7183813130560bf82426c8719570b668ba86b7e5 +/agent-note-source-owned-session-immutability-and-dev-mode-invariants: + en: 052aa271e87074c0 + zh: 3ccffc50fc1a28d4 +/agent-note-source-owned-session-immutability-and-dev-mode-invariants/problem: + en: 6ea85a4531d5e59f + zh: b4b568eb347f016a +/agent-note-source-owned-session-immutability-and-dev-mode-invariants/decision: + en: 6e701ec64c3bbfae + zh: b8ed0f1cb7a0477a +/agent-note-source-owned-session-immutability-and-dev-mode-invariants/decision/session-owns-immutable-history: + en: ff47e58c377a8dc0 + zh: 5edbe4f3642a3fe6 +/agent-note-source-owned-session-immutability-and-dev-mode-invariants/decision/derived-requests-remain-detached: + en: 975df574ee6e6df8 + zh: 96d765058482835a +/agent-note-source-owned-session-immutability-and-dev-mode-invariants/decision/package-owned-invariant-companions-check-relationships: + en: a88e3a896eedca91 + zh: 03e96c7870cba932 +/agent-note-source-owned-session-immutability-and-dev-mode-invariants/alternatives-considered: + en: 6119e2aff3b6be5a + zh: 76136ef5249c23eb +/agent-note-source-owned-session-immutability-and-dev-mode-invariants/alternatives-considered/pervasive-deep-readonly-types: + en: ec54af2931616616 + zh: 5fd9bc469a6fd3a5 +/agent-note-source-owned-session-immutability-and-dev-mode-invariants/alternatives-considered/development-only-freezing: + en: 85591197bb62eabf + zh: ba69b9ccf596a6d7 +/agent-note-source-owned-session-immutability-and-dev-mode-invariants/alternatives-considered/clone-only-when-deriving-messages: + en: a9848dec50664b92 + zh: 7c558550b054627b +/agent-note-source-owned-session-immutability-and-dev-mode-invariants/consequences: + en: bcccf7d464a070db + zh: eccd442a21e2c99e diff --git a/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.i18n.yaml index 868d215253..60451f71cc 100644 --- a/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-11-event-sourced-sessions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.md -2026-06-11-event-sourced-sessions.md: b6d17d2db1d9b489f3d4224683b61e62be485014 -2026-06-11-event-sourced-sessions.zh.md: 11e5740dc2636fc002ed7158167b1dfbb39a971d +/agent-note-event-sourced-sessions-with-derived-message-history: + en: da3abc821101e4b3 + zh: c206fa4830920592 +/agent-note-event-sourced-sessions-with-derived-message-history/problem: + en: 63b684d349a48a15 + zh: 7603f64b445db129 +/agent-note-event-sourced-sessions-with-derived-message-history/decision: + en: d60f161037a10269 + zh: 799a15fae2534ec4 +/agent-note-event-sourced-sessions-with-derived-message-history/alternatives-considered: + en: 73541e0833eb9559 + zh: ddca382d54e498e5 +/agent-note-event-sourced-sessions-with-derived-message-history/consequences: + en: d2ea77a5c8e30949 + zh: 19dc61cb0d29315f diff --git a/.agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.i18n.yaml index 57843018c6..f23e22ad36 100644 --- a/.agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-11-microkernel-event-taxonomy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.md -2026-06-11-microkernel-event-taxonomy.md: 6cacbc30f29c863de0f8ddfa4df7251a64bc80ca -2026-06-11-microkernel-event-taxonomy.zh.md: 1c7919392b835c491b9dc606d46f638a708d2948 +/agent-note-microkernel-extension-via-cordis-event-taxonomy-one-concrete-loop: + en: e5775d7ec6f1cdc3 + zh: a364697f860a545a +/agent-note-microkernel-extension-via-cordis-event-taxonomy-one-concrete-loop/problem: + en: 3bc74749db819441 + zh: 19b5497ed3a9378b +/agent-note-microkernel-extension-via-cordis-event-taxonomy-one-concrete-loop/decision: + en: 2153b0cb5773cb08 + zh: 82d7ad1b250cd52d +/agent-note-microkernel-extension-via-cordis-event-taxonomy-one-concrete-loop/alternatives-considered: + en: e528c5a20e0c55a3 + zh: 004d3bf06241cc26 +/agent-note-microkernel-extension-via-cordis-event-taxonomy-one-concrete-loop/consequences: + en: 6acb80cdaa7c010f + zh: acca672d8094d985 diff --git a/.agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml index 92ea844d93..18a5b7dcf2 100644 --- a/.agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-13-capability-seams.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-13-capability-seams.md -2026-06-13-capability-seams.md: 798739b7ef203b10ea657f9e1c178ea7eab094ad -2026-06-13-capability-seams.zh.md: c8f568aa569fe74146f1e7fcc46e00774a39fb84 +/agent-note-capability-seams-service-definition-service-provider-consumer-roles: + en: 4c1875882be571bb + zh: 90ef4d8b27587c6b +/agent-note-capability-seams-service-definition-service-provider-consumer-roles/problem: + en: 3215928333de66f7 + zh: 2c72fcacccf25741 +/agent-note-capability-seams-service-definition-service-provider-consumer-roles/decision: + en: 774c54c0d3d9acad + zh: 7dd4bfaf0ba2181b +/agent-note-capability-seams-service-definition-service-provider-consumer-roles/terminology-seam-names-the-trio-not-the-interface: + en: 8dca727800bea2f4 + zh: 4c4e028520967ca0 +/agent-note-capability-seams-service-definition-service-provider-consumer-roles/alternatives-considered: + en: cf6e4b1f188d9e4a + zh: bf2485a5f539746c +/agent-note-capability-seams-service-definition-service-provider-consumer-roles/consequences: + en: 941d8b343162edea + zh: 70904b0716de151d diff --git a/.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.i18n.yaml index d9ebd3c9de..30a57122ad 100644 --- a/.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-13-twin-llm-adapters.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.md -2026-06-13-twin-llm-adapters.md: fe8b0b55e0e027e29eb0920e64a1760d0dc35aee -2026-06-13-twin-llm-adapters.zh.md: 4248b5afeb9f3fd4503914e53203c674e3a80dbf +/agent-note-two-llm-adapters-as-a-design-verification-twin: + en: dcb28a02ba26cb31 + zh: 096d0ab60a3ad638 +/agent-note-two-llm-adapters-as-a-design-verification-twin/problem: + en: feb8f5213be03a5c + zh: 5ca85048792db7d8 +/agent-note-two-llm-adapters-as-a-design-verification-twin/decision: + en: 0dd6ebb29aebc164 + zh: 20065ae72f4d131d +/agent-note-two-llm-adapters-as-a-design-verification-twin/alternatives-considered: + en: c523a9b402588189 + zh: bced37eb1040360a +/agent-note-two-llm-adapters-as-a-design-verification-twin/consequences: + en: 71cc34560fc2e012 + zh: 91ea73e3e009a9a5 diff --git a/.agents/notes/implemented/architecture/2026-06-14-session-persistence.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-14-session-persistence.i18n.yaml index f827897a1e..995fba81fe 100644 --- a/.agents/notes/implemented/architecture/2026-06-14-session-persistence.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-14-session-persistence.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-14-session-persistence.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-14-session-persistence.md -2026-06-14-session-persistence.md: d79975e1fedb6efcd0e4ea83bc799bb158082e41 -2026-06-14-session-persistence.zh.md: f70b8005a254cc6a9ea8ada31c32e5552ee0c8b2 +/agent-note-session-persistence-as-an-abstract-service-over-the-existing-sessionevent: + en: d7cf18702f4ed830 + zh: 7e0cc6db7c90a7bd +/agent-note-session-persistence-as-an-abstract-service-over-the-existing-sessionevent/problem: + en: fa1ffb258aee90f6 + zh: c25cead52e72f97d +/agent-note-session-persistence-as-an-abstract-service-over-the-existing-sessionevent/decision: + en: a7076073971de601 + zh: 5ea9a87705340d91 +/agent-note-session-persistence-as-an-abstract-service-over-the-existing-sessionevent/alternatives-considered: + en: e5c9929ca92cc12e + zh: 3e0668f6a822577c +/agent-note-session-persistence-as-an-abstract-service-over-the-existing-sessionevent/consequences: + en: 4f00ed0b90442440 + zh: 994a5b03c862178b diff --git a/.agents/notes/implemented/architecture/2026-06-18-session-surface.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-18-session-surface.i18n.yaml index 1939ff2f17..db7edf6873 100644 --- a/.agents/notes/implemented/architecture/2026-06-18-session-surface.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-18-session-surface.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-18-session-surface.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-18-session-surface.md -2026-06-18-session-surface.md: 26780d54a1ea12283900572c6fd0e8f740de5524 -2026-06-18-session-surface.zh.md: 328a9ee9f1bed9c52996cfd307549a7745e16d4b +/agent-note-session-surface-an-ordered-projection-over-the-event-log: + en: 9ea7a8765e7f3259 + zh: 17e0d51645f01edd +/agent-note-session-surface-an-ordered-projection-over-the-event-log/problem: + en: 4f7a9d20d71a6ab3 + zh: 958abbdfefec4f21 +/agent-note-session-surface-an-ordered-projection-over-the-event-log/decision: + en: a9944b568ec51fad + zh: 6717d30db31b81d7 +/agent-note-session-surface-an-ordered-projection-over-the-event-log/decision/top-level-surface-metadata-on-sessionevent: + en: 788fc16ecdedc252 + zh: 14d05c2a1272de5d +/agent-note-session-surface-an-ordered-projection-over-the-event-log/decision/surfaceop-two-operations: + en: ff075eec0881094a + zh: 1f7768f28b8996d5 +/agent-note-session-surface-an-ordered-projection-over-the-event-log/decision/surfacemanager-delta-based-not-full-rebuild: + en: 0b10fd9c5166d17b + zh: 02de01f70c03f70e +/agent-note-session-surface-an-ordered-projection-over-the-event-log/decision/persistence: + en: 9bb1f81b86b24760 + zh: fe4948645dd0c66d +/agent-note-session-surface-an-ordered-projection-over-the-event-log/decision/crash-recovery: + en: ee71f9c0f12b6a0e + zh: 403b1723f808391d +/agent-note-session-surface-an-ordered-projection-over-the-event-log/decision/invariants: + en: 24b1342fb3b5be29 + zh: a62692b0250c072a +/agent-note-session-surface-an-ordered-projection-over-the-event-log/alternatives-considered: + en: 193157129e65e487 + zh: a0a73b8a9cbd78e6 +/agent-note-session-surface-an-ordered-projection-over-the-event-log/consequences: + en: 801b67f8da564a22 + zh: 3c0433ed07083050 diff --git a/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.i18n.yaml index 22bf3c01c4..ff239e85c9 100644 --- a/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.i18n.yaml @@ -1,6 +1,58 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-20-generic-long-running-tool-runtime.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md -2026-06-20-generic-long-running-tool-runtime.md: 5960eb268656d7e316c763631451db1c6d1c6e49 -2026-06-20-generic-long-running-tool-runtime.zh.md: ea63ae82962a735b3a96e1803708172a33f83e9d +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools: + en: 56e269b2a2839796 + zh: 8fc971036985ac0d +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/problem: + en: 70e26df62568c337 + zh: a9e6f5f8a5482d0a +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/decision: + en: 277869395ad6f792 + zh: 93f13a97d52f10a5 +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/runtime-contract: + en: eeb7ed8eec13668a + zh: 3f236f63c72fbba7 +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/authorization-and-owner-lifecycle: + en: 3819a73ca70ecdfd + zh: c1a4f461a4e45978 +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/service-api: + en: a1a884816aac3d7f + zh: b21129e5cd93b9a1 +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/model-facing-control-api: + en: dd3f4d85d0ec136f + zh: ca4209cb856271dd +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/producer-opt-in: + en: a39343bf6f655051 + zh: d9894d39e7f4d6e1 +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/producer-integrations: + en: ae4a6d6e0d83d3bd + zh: 9072890ba9374426 +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/alternatives-considered: + en: 6119e2aff3b6be5a + zh: e01a6c669a9ec6aa +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/alternatives-considered/per-capability-control-tools: + en: 9781c302dc72fd8e + zh: a78e1dd8da4d8ca8 +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/alternatives-considered/an-immediate-abstract-task-runtime-backend: + en: 404a5c7c45a71a55 + zh: 213621e4a9618a9c +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/alternatives-considered/consumer-owned-authorization-or-cleanup-events: + en: d99de803718d9ca6 + zh: e03a97314851ed0f +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/alternatives-considered/blocking-output-or-a-separate-wait-tool: + en: e3beca50b6a57ce0 + zh: a77663b817d33247 +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/alternatives-considered/runtime-owned-output-sinks: + en: 42eeeba9d84ae681 + zh: 1d540f9740675bee +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/alternatives-considered/random-ids-promotion-or-lifecycle-session-events: + en: e706b1b57241d3d2 + zh: 1779b7fa05f48283 +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/testing: + en: e891db1723828da8 + zh: 657a62ed595bd081 +/agent-note-the-background-job-runtime-ctx-jobs-and-generic-task-control-tools/consequences: + en: b95ecd6052465ad3 + zh: 1527c38d1b4631d6 diff --git a/.agents/notes/implemented/architecture/2026-06-21-bounded-llm-request-recovery.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-21-bounded-llm-request-recovery.i18n.yaml index 0956b2aa0b..2b8a5f380d 100644 --- a/.agents/notes/implemented/architecture/2026-06-21-bounded-llm-request-recovery.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-21-bounded-llm-request-recovery.i18n.yaml @@ -1,6 +1,43 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-21-bounded-llm-request-recovery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-21-bounded-llm-request-recovery.md -2026-06-21-bounded-llm-request-recovery.md: b0a4ebb11b76c4c0068490c9924a88b80a8bc99f -2026-06-21-bounded-llm-request-recovery.zh.md: e8c25f9f6410dc12e34a0272e01e874431624c28 +/agent-note-bounded-recovery-for-transient-llm-request-failures: + en: fb8e336ecd4bf571 + zh: 23e40e4cb224163f +/agent-note-bounded-recovery-for-transient-llm-request-failures/problem: + en: 83a361538a092dae + zh: e8f33cb95d0d3e09 +/agent-note-bounded-recovery-for-transient-llm-request-failures/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-bounded-recovery-for-transient-llm-request-failures/decision/preserve-failure-facts-without-embedding-policy: + en: 943322e6cdbfa440 + zh: 82288531f6194ed2 +/agent-note-bounded-recovery-for-transient-llm-request-failures/decision/put-retry-policy-on-the-existing-failed-step-extension-point: + en: ed4d295378d94a26 + zh: 1fee5ef4947bac8f +/agent-note-bounded-recovery-for-transient-llm-request-failures/decision/make-one-layer-own-visible-attempts: + en: 57dbdd385f48bb3e + zh: 5e15463fae4be582 +/agent-note-bounded-recovery-for-transient-llm-request-failures/decision/bound-stalled-streams-where-they-can-be-stopped: + en: f7369086e87192b9 + zh: e2839ed8cc5c23b8 +/agent-note-bounded-recovery-for-transient-llm-request-failures/decision/keep-attempts-separate-in-the-existing-log: + en: 8f57db4bfd6e1c22 + zh: 67ac62217bb68570 +/agent-note-bounded-recovery-for-transient-llm-request-failures/out-of-scope: + en: 985720529b56cda2 + zh: 8a649bfa9cd8d93f +/agent-note-bounded-recovery-for-transient-llm-request-failures/alternatives-considered: + en: a6d0306740d470ee + zh: 700bd4b0aa58f3e8 +/agent-note-bounded-recovery-for-transient-llm-request-failures/verification: + en: db343f335a9d7cad + zh: 49b8300de55dcfeb +/agent-note-bounded-recovery-for-transient-llm-request-failures/consequences: + en: 08659e8606455ada + zh: 862080f8df5f28ec +/agent-note-bounded-recovery-for-transient-llm-request-failures/related: + en: e85a6ad7387c881b + zh: bb8fb4173ffe613d diff --git a/.agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.i18n.yaml index 2b6c63d334..0856d5ac56 100644 --- a/.agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-21-mandatory-app-attribution-headers.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.md -2026-06-21-mandatory-app-attribution-headers.md: 9e0c029dc03c722512680a563c24e470128ee322 -2026-06-21-mandatory-app-attribution-headers.zh.md: 1427daf8f6065ec2dee324075a8381a625d9e960 +/agent-note-mandatory-user-agent-attribution-for-provider-requests: + en: 3f804e0236d13aba + zh: ef8b1b7b9c3d8376 +/agent-note-mandatory-user-agent-attribution-for-provider-requests/problem: + en: f65797760084b93a + zh: d1fb36ef61a93003 +/agent-note-mandatory-user-agent-attribution-for-provider-requests/investigation: + en: 5ea11f54f507ba64 + zh: 22a83a0714a2fda3 +/agent-note-mandatory-user-agent-attribution-for-provider-requests/decision: + en: b3e29e609e3f0966 + zh: e3df0cb13df1cd5d +/agent-note-mandatory-user-agent-attribution-for-provider-requests/verification: + en: 567737dbccdb3a2a + zh: be92a5303247b889 +/agent-note-mandatory-user-agent-attribution-for-provider-requests/alternatives-considered: + en: 016678c52ef64e51 + zh: a113b57b9e9ddeb5 +/agent-note-mandatory-user-agent-attribution-for-provider-requests/consequences: + en: a9010e68445a0008 + zh: 1ec6104ab2865919 diff --git a/.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.i18n.yaml index bbdb39100a..490d5c5d24 100644 --- a/.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.i18n.yaml @@ -1,6 +1,76 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-24-web-capability-seam.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-24-web-capability-seam.md -2026-06-24-web-capability-seam.md: 8c6c088ea5d7345f9955892b2d6054cfae518bbd -2026-06-24-web-capability-seam.zh.md: 4921c4a4647d180dbb00e6493a19d38584f99bdc +/agent-note-web-capability-seam-stable-tools-over-multiple-providers: + en: ca120635fc40431c + zh: 6be7c5ae3c86cdcc +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/problem: + en: c8b932b02a4e1c80 + zh: 96c466be1a521f3f +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/decision: + en: b57eb0f268033ff1 + zh: 4143382a50181414 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/package-topology: + en: 5ea3ddfae82df181 + zh: 2d05d95e51081696 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/ctx-web-contract: + en: b432f80a424c3e49 + zh: faa26925fdd98387 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/provider-availability-and-selection: + en: dff78c46432311a1 + zh: 58d5db4c3c85b886 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/search-request-and-result-schema: + en: ec3703b7e7c6b23d + zh: 325755e6e90092da +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/fetch-request-and-result-schema: + en: f734fdc57a6546c9 + zh: 027c28cbc584a8c2 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/tool-consumer-behavior: + en: 62127883453dd79c + zh: 01503a8177a0ddab +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/errors: + en: 3440f2b34b93f4a1 + zh: 57a8f784c7e26eff +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/testing: + en: 7f73699ac4459432 + zh: c16be49ac50c34c8 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/alternatives-considered: + en: 6119e2aff3b6be5a + zh: 76136ef5249c23eb +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/alternatives-considered/let-each-provider-register-its-own-model-facing-tool: + en: e0d84a9b1b9c2123 + zh: 9e116a7b96751563 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/alternatives-considered/put-provider-dispatch-directly-in-dsh-tool-web: + en: dc01d014d03b49d2 + zh: b956b02f41c62682 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/alternatives-considered/split-search-and-fetch-into-two-seams-dsh-search-dsh-fetch: + en: 3fb72ba3e554f20a + zh: aff5f0add5773388 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/alternatives-considered/choose-the-first-registered-provider: + en: 1800706ea0f6b90b + zh: ced985b7657e2d7f +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/alternatives-considered/treat-firecrawl-exa-tavily-parallel-extraction-as-fetch: + en: fc22e6a8bfaeaa20 + zh: 64032ea6ab61b836 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/alternatives-considered/mirror-claude-code-s-url-prompt-webfetch-shape: + en: 56a080de39e96056 + zh: ae4d070aa7657503 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/alternatives-considered/validate-dns-and-then-call-an-ordinary-fetch: + en: aa6c1e7e6374a875 + zh: 045c8af6cd44c3e1 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/alternatives-considered/block-private-looking-hostname-strings-without-pinning-resolved-addresses: + en: 3d906f3056733479 + zh: d652723eb5372007 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/alternatives-considered/require-per-call-approval-before-public-fetches: + en: f8d1fc8e9c9659cf + zh: da5792520e35cba0 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/consequences: + en: 12fd20ba54818215 + zh: c1ca000b13666701 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/deferred-work: + en: 48b7b8e7310cd56b + zh: d406cd6a8a649e58 +/agent-note-web-capability-seam-stable-tools-over-multiple-providers/open-questions: + en: 63848c6ef9a6ab44 + zh: 041b340802091e60 diff --git a/.agents/notes/implemented/architecture/2026-06-26-file-context-as-event-gate.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-26-file-context-as-event-gate.i18n.yaml index 7db4727f48..3addc01168 100644 --- a/.agents/notes/implemented/architecture/2026-06-26-file-context-as-event-gate.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-26-file-context-as-event-gate.i18n.yaml @@ -1,6 +1,43 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-26-file-context-as-event-gate.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-26-file-context-as-event-gate.md -2026-06-26-file-context-as-event-gate.md: 2943f11190533f84f3aebea0a25a88372d1204f1 -2026-06-26-file-context-as-event-gate.zh.md: 053f4269b13c8583def01c144badd17b10a5a41a +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface: + en: 950d6bb4d83b39d8 + zh: b40458972583b12b +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/problem: + en: 765a679e88ecda60 + zh: fccabc8ee516ea00 +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/decision: + en: eb8355d4b7a6c66b + zh: 712c6f932f26a0d3 +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/the-policy-is-enforced-by-provider-cas-not-by-dsh-fs-observation-policy-stat: + en: 2edc42b8210c995b + zh: 48f4354c9ec625ee +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/provider-contract-change-the-version-guard-is-optional: + en: a282600f92568e07 + zh: 3e6b2bec22c170c6 +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/event-vocabulary-owned-by-dsh-fs: + en: f57494c21daf90ea + zh: 1a1f8623dc0cbef3 +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/tool-contract-dsh-tool-fs: + en: c7f4457a83739520 + zh: f2d55d018c7dab4f +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/policy-plugin-contract-dsh-fs-observation-policy: + en: a239deb5dde631df + zh: 68cc6c954b247596 +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/bare-provider-behavior-no-dsh-fs-observation-policy: + en: 5aed537454b78157 + zh: 9e8e7108be6a9537 +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/supersedes: + en: 5cc21706fd0f00ad + zh: 2b51da75a95f1777 +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/verification: + en: 1e3de2836160b4c2 + zh: a8af173d161f0949 +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/alternatives-considered: + en: 768c09662714cf25 + zh: cb641e8a77a2e32c +/agent-note-make-dsh-fs-observation-policy-an-event-gate-plugin-not-a-method-interface/consequences: + en: a1c00220fa5c6ce1 + zh: 4691374274aa8df9 diff --git a/.agents/notes/implemented/architecture/2026-06-30-event-domain-semantics.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-30-event-domain-semantics.i18n.yaml index 4a4342d1f2..9afc68c549 100644 --- a/.agents/notes/implemented/architecture/2026-06-30-event-domain-semantics.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-30-event-domain-semantics.i18n.yaml @@ -1,6 +1,16 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-30-event-domain-semantics.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-30-event-domain-semantics.md -2026-06-30-event-domain-semantics.md: 7e0aee220a62777ebe1d8f6a5018aba0f5fa20ee -2026-06-30-event-domain-semantics.zh.md: 14568c7a4660c42cecc47f094373d299380fa563 +/agent-note-event-domain-semantics-session-is-the-fact-log-agent-is-the-live-event-channel: + en: e7cdaa7a6029c259 + zh: ed13f8158ee0eaeb +/agent-note-event-domain-semantics-session-is-the-fact-log-agent-is-the-live-event-channel/problem: + en: 1222c2b55882b1e5 + zh: f81f481f5eb9a684 +/agent-note-event-domain-semantics-session-is-the-fact-log-agent-is-the-live-event-channel/decision: + en: ccc0fed9b7388112 + zh: 3cc527b11affd941 +/agent-note-event-domain-semantics-session-is-the-fact-log-agent-is-the-live-event-channel/consequences: + en: e0c5aa60322e67a1 + zh: 7495550f0c863eda diff --git a/.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.i18n.yaml index 933b3d2826..6e01984aee 100644 --- a/.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-02-tool-render-intent-union.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.md -2026-07-02-tool-render-intent-union.md: 52626d3d9200146df95aee7836d37bbaf7e6a9ec -2026-07-02-tool-render-intent-union.zh.md: bc91b89c53c3c43b6c483dc0d4876a00f5a936b7 +/agent-note-tagged-render-intent-union-for-tool-call-presentation: + en: 599dd6f91059580e + zh: b6a46767bb4198e6 +/agent-note-tagged-render-intent-union-for-tool-call-presentation/problem: + en: 3a4b92dca651b979 + zh: 6b10ce7ba3681180 +/agent-note-tagged-render-intent-union-for-tool-call-presentation/decision: + en: aff6d789bde63f17 + zh: 73782526b46a3ee5 +/agent-note-tagged-render-intent-union-for-tool-call-presentation/decision/why-a-tagged-union-beats-the-field-bag: + en: ed7b15039050e65e + zh: a719562b5fcdbd4e +/agent-note-tagged-render-intent-union-for-tool-call-presentation/decision/producer-mapping: + en: c87f22a29caef002 + zh: 7bfd28c1df80b8a1 +/agent-note-tagged-render-intent-union-for-tool-call-presentation/decision/terminal-fallback-ownership: + en: 0bb2f60726afc4d9 + zh: 60040141447b4a2e +/agent-note-tagged-render-intent-union-for-tool-call-presentation/decision/purity-preserved: + en: 1ba6a480967c524d + zh: 90535e843f346bcf +/agent-note-tagged-render-intent-union-for-tool-call-presentation/alternatives-considered: + en: 2cd4801f3162227b + zh: 76afaa23bc2b9eb0 +/agent-note-tagged-render-intent-union-for-tool-call-presentation/consequences: + en: 81d8366d826285c2 + zh: b437b862794c146e +/agent-note-tagged-render-intent-union-for-tool-call-presentation/non-goals: + en: e9d60967a9b3f9bd + zh: 6dfa9ac30d847879 +/agent-note-tagged-render-intent-union-for-tool-call-presentation/related: + en: fe27f777b3728fa4 + zh: 4b648dbf731ace00 diff --git a/.agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.i18n.yaml index 57dba7f52b..670619cca9 100644 --- a/.agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-05-prompt-variables-and-tool-guidance-ownership.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.md -2026-07-05-prompt-variables-and-tool-guidance-ownership.md: 8f5542cb09930e62fd1e26960166fbdd6d3f6745 -2026-07-05-prompt-variables-and-tool-guidance-ownership.zh.md: 348ae36cf6549d412adab1d3cdb5cc03f0badd01 +/agent-note-prompt-variables-and-tool-guidance-ownership: + en: 6f8b4a9d26ab3e50 + zh: 9741e5718e647f0a +/agent-note-prompt-variables-and-tool-guidance-ownership/problem: + en: 8ccef8fbd9260dfe + zh: 106b2bafe969c676 +/agent-note-prompt-variables-and-tool-guidance-ownership/decision: + en: c551d888282d9c73 + zh: 889b5ca3cdf25aff +/agent-note-prompt-variables-and-tool-guidance-ownership/decision/assemble-context: + en: 46e67248692e333a + zh: 51c5f2c6152c94d7 +/agent-note-prompt-variables-and-tool-guidance-ownership/decision/prompt-variables: + en: 04b623ed2879fdf1 + zh: c111be62834fda93 +/agent-note-prompt-variables-and-tool-guidance-ownership/decision/persona-as-the-order-0-section: + en: c2d32c0ac5d28759 + zh: 59cd252ba6da6e59 +/agent-note-prompt-variables-and-tool-guidance-ownership/decision/tool-guidance-ownership: + en: 308c0d2ef4e41f56 + zh: d38f84a517da20df +/agent-note-prompt-variables-and-tool-guidance-ownership/decision/the-subagent-conversation-history-descriptor: + en: 1cb9644f22918749 + zh: fb9fdee133159ab2 +/agent-note-prompt-variables-and-tool-guidance-ownership/alternatives-considered: + en: 9a114359d2e8988b + zh: ce39453408b2af7f +/agent-note-prompt-variables-and-tool-guidance-ownership/out-of-scope: + en: bbfecc70d0b457fe + zh: 7f207a37a86484f4 +/agent-note-prompt-variables-and-tool-guidance-ownership/shipped-invariants: + en: 31ba63101fca5790 + zh: af4ceefab2033142 +/agent-note-prompt-variables-and-tool-guidance-ownership/consequences: + en: 993f17bf35f6a2e0 + zh: acb429176f0eebcc diff --git a/.agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.i18n.yaml index ac7f2acd4e..987abc5f0e 100644 --- a/.agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-05-reconstructable-requests.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.md -2026-07-05-reconstructable-requests.md: f47d0938b91edf6c9b544223ac44925f02dd8c1f -2026-07-05-reconstructable-requests.zh.md: d2499a6264a3e6bebf31944d8eb056265e082c68 +/agent-note-every-llm-request-is-reconstructable-from-the-session-log: + en: 115dd45f40b0d7d8 + zh: 536b5a0399e7d06a +/agent-note-every-llm-request-is-reconstructable-from-the-session-log/problem: + en: f8f31da854a5fe2e + zh: ef88856c2c7bdfb8 +/agent-note-every-llm-request-is-reconstructable-from-the-session-log/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-every-llm-request-is-reconstructable-from-the-session-log/decision/the-principle: + en: 6da15cf986d59a91 + zh: 40282908b54295f9 +/agent-note-every-llm-request-is-reconstructable-from-the-session-log/decision/the-mechanism: + en: 7d86e5058dbab2fb + zh: 9a97481325c8eded +/agent-note-every-llm-request-is-reconstructable-from-the-session-log/decision/the-minicode-shape-adopted-with-the-event-log-as-the-source: + en: e5f2ffaa3d7de0cc + zh: 5ba6b36787a0e189 +/agent-note-every-llm-request-is-reconstructable-from-the-session-log/alternatives-considered: + en: 96f19ecf38fae991 + zh: 9692252135ef3476 +/agent-note-every-llm-request-is-reconstructable-from-the-session-log/consequences: + en: 0d2e97bc421e67cc + zh: 0a000a69b8cc4b4e diff --git a/.agents/notes/implemented/architecture/2026-07-05-windows-jsonl-durable-publish.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-05-windows-jsonl-durable-publish.i18n.yaml index cc278292d9..2848f7cd4b 100644 --- a/.agents/notes/implemented/architecture/2026-07-05-windows-jsonl-durable-publish.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-05-windows-jsonl-durable-publish.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-05-windows-jsonl-durable-publish.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-05-windows-jsonl-durable-publish.md -2026-07-05-windows-jsonl-durable-publish.md: 546cde6086f3c84e22b4d4de144a48bb3425cd4e -2026-07-05-windows-jsonl-durable-publish.zh.md: b99032e9d7e72e2028f39c5af91659278fd81343 +/agent-note-windows-native-durable-jsonl-publication: + en: db7fe80708911f2f + zh: 42c6639defea2bde +/agent-note-windows-native-durable-jsonl-publication/problem: + en: dcc3c6238131d302 + zh: 4d4e8513a4069af3 +/agent-note-windows-native-durable-jsonl-publication/decision: + en: 385565b209f1e739 + zh: 0eab0997c49a3c33 +/agent-note-windows-native-durable-jsonl-publication/alternatives-considered: + en: 83d5bf5781f89e29 + zh: 068835993789e09d +/agent-note-windows-native-durable-jsonl-publication/consequences: + en: 4be0ad03a334c257 + zh: 95d473ed5b94e270 diff --git a/.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.i18n.yaml index b2ebf2057f..9db3e2596d 100644 --- a/.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-06-timeout-deadline-library.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.md -2026-07-06-timeout-deadline-library.md: 6f726938731f18386105ff1180c79fef981c95bf -2026-07-06-timeout-deadline-library.zh.md: 48bd7b4b91efd0045c03e3e1e1e9e37656b4dcf6 +/agent-note-a-shared-timeout-deadline-primitive-with-hard-kill-left-to-each-capability: + en: 4a9921fef5e65cc8 + zh: 672cd27d68310cb1 +/agent-note-a-shared-timeout-deadline-primitive-with-hard-kill-left-to-each-capability/problem: + en: 110ff68b35bd43cb + zh: f1cea15fb29a9ae9 +/agent-note-a-shared-timeout-deadline-primitive-with-hard-kill-left-to-each-capability/decision: + en: 18645d82d9e40107 + zh: 73e510f1ed1106e6 +/agent-note-a-shared-timeout-deadline-primitive-with-hard-kill-left-to-each-capability/decision/the-library-api: + en: c62681afef60a0db + zh: 69827b4b3165b3da +/agent-note-a-shared-timeout-deadline-primitive-with-hard-kill-left-to-each-capability/decision/the-division-of-labor: + en: 263c8e17bbc87ba0 + zh: d75a74f47713e79f +/agent-note-a-shared-timeout-deadline-primitive-with-hard-kill-left-to-each-capability/decision/how-each-capability-consumes-it: + en: 333eab4967d753ec + zh: dd7537bb82cc717f +/agent-note-a-shared-timeout-deadline-primitive-with-hard-kill-left-to-each-capability/consequences: + en: 832f4dbd93a47f94 + zh: 65ada43f9f23a39b +/agent-note-a-shared-timeout-deadline-primitive-with-hard-kill-left-to-each-capability/alternatives-considered: + en: 7b3445622becbd36 + zh: bb358acf2ff28e26 diff --git a/.agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.i18n.yaml index 4cacefaca8..617b3a053b 100644 --- a/.agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-07-tool-call-timeout-policy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.md -2026-07-07-tool-call-timeout-policy.md: 60d82c1d591f0a32350b1a21ed74e148c4c93576 -2026-07-07-tool-call-timeout-policy.zh.md: 49ca7f397d15c1a351cba4837d4d531e54120ea6 +/agent-note-tool-call-timeout-policy-as-a-plugin: + en: 46fa7d1eac4fe061 + zh: 7a62f8f7b1c66722 +/agent-note-tool-call-timeout-policy-as-a-plugin/problem: + en: b5fffa80b58fb184 + zh: aadf28f95924b1ad +/agent-note-tool-call-timeout-policy-as-a-plugin/decision: + en: 04889f664ab7657d + zh: 2af5913f5e9c1927 +/agent-note-tool-call-timeout-policy-as-a-plugin/decision/the-tools-execute-around-dispatch-extension-point: + en: 8c3b46fa8a48a863 + zh: 662eb09bb7542be8 +/agent-note-tool-call-timeout-policy-as-a-plugin/decision/the-timeout-policy-plugin: + en: 96f5932514a33e41 + zh: 5951d9451ccef1bf +/agent-note-tool-call-timeout-policy-as-a-plugin/decision/existing-tool-adaptation: + en: 43add9b1f723ce89 + zh: f3ee56f97faa2e60 +/agent-note-tool-call-timeout-policy-as-a-plugin/alternatives-considered: + en: dc6da8743b4266fb + zh: 5c28667d952b230a +/agent-note-tool-call-timeout-policy-as-a-plugin/consequences: + en: f7429a5c1fe6b6a1 + zh: 748401be79f89b05 diff --git a/.agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.i18n.yaml index aff7b32029..cfb0644c92 100644 --- a/.agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.i18n.yaml @@ -1,6 +1,46 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-08-agent-scope-contexts.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.md -2026-07-08-agent-scope-contexts.md: 45e635b7bc3138d4e90a25a06ff23b3b57a9415e -2026-07-08-agent-scope-contexts.zh.md: aac860734e744843c3b9e7d55e5bc7a150763090 +/agent-note-the-agent-is-a-registration-scope: + en: f767894b8308f1a0 + zh: 4ff0aead6ee4e27b +/agent-note-the-agent-is-a-registration-scope/problem: + en: 87634b46a5642328 + zh: 2adce8b041626437 +/agent-note-the-agent-is-a-registration-scope/decision: + en: ac58e62f780b0879 + zh: 6b077226de04a8fa +/agent-note-the-agent-is-a-registration-scope/decision/registration-origin-chooses-visibility-and-cleanup: + en: 1ec8e54543272e1b + zh: b5b1695a805574a2 +/agent-note-the-agent-is-a-registration-scope/decision/the-operation-chooses-the-view: + en: 2e236d399efdc0b2 + zh: 00a7ba20f90862c6 +/agent-note-the-agent-is-a-registration-scope/decision/scoped-events-keep-routing-separate-from-event-data: + en: df5f5e4c1de44474 + zh: d851c02959d02380 +/agent-note-the-agent-is-a-registration-scope/decision/creation-publishes-last-and-disposal-revokes-last: + en: f46920b4945e0e6d + zh: 870a157205883144 +/agent-note-the-agent-is-a-registration-scope/security-and-authority-are-non-goals: + en: 5ffc5a8f65ce7dfe + zh: 3362f236356a8033 +/agent-note-the-agent-is-a-registration-scope/alternatives-considered: + en: bf43310538280f62 + zh: e4940ff47c5d47b5 +/agent-note-the-agent-is-a-registration-scope/alternatives-considered/pass-an-agent-option-to-every-registration: + en: 37e7487b1f1eb87a + zh: eeddbaf21eee7ebc +/agent-note-the-agent-is-a-registration-scope/alternatives-considered/filter-events-while-keeping-registries-global: + en: 7eb2628d51ea9ed0 + zh: e58f05faf0e95712 +/agent-note-the-agent-is-a-registration-scope/alternatives-considered/create-one-service-graph-per-agent: + en: 2fd1c41c3d1bc6ca + zh: cffad44a2c69330e +/agent-note-the-agent-is-a-registration-scope/alternatives-considered/inherit-parent-registration-scopes: + en: 01f989446aab1cf1 + zh: 8f5c9018b7b84c94 +/agent-note-the-agent-is-a-registration-scope/consequences: + en: 65c8f47d1607b276 + zh: 950b86b4682f7a0e diff --git a/.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.i18n.yaml index d2f8d60d2d..1325797191 100644 --- a/.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-08-tool-output-spill-files.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.md -2026-07-08-tool-output-spill-files.md: e32aec72f423dff33a29d9012c0f71c9cfbd24fb -2026-07-08-tool-output-spill-files.zh.md: 2941fc516723e72b5d5670e674ce612f3cf581cc +/agent-note-tool-output-spill-policy: + en: 06b99197145a4080 + zh: 698a61dcd2385985 +/agent-note-tool-output-spill-policy/problem: + en: 858cbb874e213697 + zh: 1693b618886ac42d +/agent-note-tool-output-spill-policy/decision: + en: 89536b0d2d7b4c92 + zh: 341240f445885549 +/agent-note-tool-output-spill-policy/decision/spill-seam: + en: 1e92bc9a0548def9 + zh: c99cf6878981ba71 +/agent-note-tool-output-spill-policy/decision/spill-policy: + en: 3c49c0246188c513 + zh: 4b6749c30726903d +/agent-note-tool-output-spill-policy/showcase-web-fetch: + en: d5c334b50f458925 + zh: 7631307b5d9fbc55 +/agent-note-tool-output-spill-policy/relationship-to-retention-and-early-spill: + en: 7314ba8b0a03c0d9 + zh: 8429f79ff3a7bd1f +/agent-note-tool-output-spill-policy/non-goals: + en: f82b5399ecddd8a1 + zh: 9675b58631bb5c90 +/agent-note-tool-output-spill-policy/deferred: + en: 094f8c71672ea726 + zh: 252dbe825d6e34ca +/agent-note-tool-output-spill-policy/testing: + en: c98759345e1aebfa + zh: d1faeadb99bd748a +/agent-note-tool-output-spill-policy/consequences: + en: e023260e52a246d6 + zh: 2e49237e564a83da +/agent-note-tool-output-spill-policy/alternatives-considered: + en: d53fb144141de557 + zh: 1b851eb64c421803 diff --git a/.agents/notes/implemented/architecture/2026-07-10-after-call-compaction-pressure-and-overflow-recovery.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-10-after-call-compaction-pressure-and-overflow-recovery.i18n.yaml index ec2f5318d6..ee57a4b8cf 100644 --- a/.agents/notes/implemented/architecture/2026-07-10-after-call-compaction-pressure-and-overflow-recovery.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-10-after-call-compaction-pressure-and-overflow-recovery.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-10-after-call-compaction-pressure-and-overflow-recovery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-10-after-call-compaction-pressure-and-overflow-recovery.md -2026-07-10-after-call-compaction-pressure-and-overflow-recovery.md: 89c8917484c11057ff2e6b55e2311e83f724f7ed -2026-07-10-after-call-compaction-pressure-and-overflow-recovery.zh.md: 48f954f2c4720894548ecab387965d3a3d1799b0 +/agent-note-after-call-compaction-pressure-and-context-overflow-recovery: + en: 8bfe0d8b79d9840f + zh: 6921dc88e5ef9c83 +/agent-note-after-call-compaction-pressure-and-context-overflow-recovery/problem: + en: 036da3e545debe29 + zh: 82e031a3120ca36c +/agent-note-after-call-compaction-pressure-and-context-overflow-recovery/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-after-call-compaction-pressure-and-context-overflow-recovery/decision/successful-pressure-runs-at-the-next-pre-step-boundary: + en: 5f5a656b38730ec6 + zh: aece66b85cc610cf +/agent-note-after-call-compaction-pressure-and-context-overflow-recovery/decision/request-recovery-is-limited-to-the-final-model-boundary: + en: fb7da851bf6a020e + zh: b40dc932d6c3101c +/agent-note-after-call-compaction-pressure-and-context-overflow-recovery/decision/compactionengine-exposes-intent-not-token-accounting: + en: be9505b3d73c7f6b + zh: ed753f1afec2787a +/agent-note-after-call-compaction-pressure-and-context-overflow-recovery/testing: + en: b0e1704bd3724301 + zh: 2279353ff615f183 +/agent-note-after-call-compaction-pressure-and-context-overflow-recovery/alternatives-considered: + en: 3cb5363732ef5758 + zh: 07746411cc80878f +/agent-note-after-call-compaction-pressure-and-context-overflow-recovery/consequences: + en: dfe515fb04127eb5 + zh: 1924b2e1e9997910 diff --git a/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml index e09f7db568..5e078a7885 100644 --- a/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml @@ -1,6 +1,43 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-10-single-file-executable-sdk-runtime-distribution.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md -2026-07-10-single-file-executable-sdk-runtime-distribution.md: 7260d11c84f8fb07cf6c4691357f92e0d00fd8f3 -2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md: 653fb3d9b782d9010f693e4af8ad94475abb9d94 +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe: + en: 00b5d91d3e44a9f8 + zh: eabd3c4b338249b3 +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/problem: + en: 112178b76e5209f6 + zh: 68726254ae530566 +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/decision/packaging-route-yao-pkg-pkg-s-sea-mode: + en: f1c2b60e9474111d + zh: 5de398b5e8554429 +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/decision/the-serving-interface-is-a-plugin-inside-the-dsh-application: + en: 5fdde26e9e8c6108 + zh: 629559d733c1f0c5 +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/decision/plugin-resolution-the-vfs-holds-a-real-package-tree-the-closure-manifest-is-the-deploy-root: + en: c35ea4b858448b49 + zh: 1f8ff0a9f82ca881 +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/decision/build-pipeline-and-artifacts: + en: 53ba44431d2ce411 + zh: 4159475549273422 +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/decision/python-sdk-distribution-two-carriers-exe-for-production-node-for-development: + en: 9bd60549d4a52ec0 + zh: e2343b7210212ee0 +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/decision/naming-lineage: + en: 31a5aecb8bf828bb + zh: 2dffb6fd2e0f8194 +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/packaged-workflow-and-code-execution: + en: 0426f598f3f44e64 + zh: fc66728e17f3bcfb +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/testing: + en: b3c9820f4dc7c6c8 + zh: 3b5768ef1770bfcb +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/alternatives-considered: + en: 50d965ca81a401ba + zh: 0c6296245b97b9ac +/agent-note-single-file-executable-sdk-runtime-distribution-single-exe/consequences: + en: 601a72b3a7a91fe4 + zh: 5baaa866e789923e diff --git a/.agents/notes/implemented/architecture/2026-07-12-agent-scope-runtime-design.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-12-agent-scope-runtime-design.i18n.yaml index 16591b4f3e..6d5a779689 100644 --- a/.agents/notes/implemented/architecture/2026-07-12-agent-scope-runtime-design.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-12-agent-scope-runtime-design.i18n.yaml @@ -1,6 +1,157 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-12-agent-scope-runtime-design.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-12-agent-scope-runtime-design.md -2026-07-12-agent-scope-runtime-design.md: b9b2c837f560c2b8b98da37e3656caf298b705e2 -2026-07-12-agent-scope-runtime-design.zh.md: 4b94d1b8449bd619c47f6bee0712ec8ed0b39593 +/agent-note-agent-scope-runtime-design-and-correctness: + en: b63ecbd21fc1f427 + zh: 4990d96d76888802 +/agent-note-agent-scope-runtime-design-and-correctness/problem: + en: ae7b688bd991a6df + zh: 73b6b28755852054 +/agent-note-agent-scope-runtime-design-and-correctness/decision: + en: cfd6abca8404c7d4 + zh: a9372aae85e49f55 +/agent-note-agent-scope-runtime-design-and-correctness/cordis-model-context-fiber-effect-receiver-and-waterfall: + en: 4d4bdb629a57139d + zh: 7b4d21d9eb42d94b +/agent-note-agent-scope-runtime-design-and-correctness/cordis-model-context-fiber-effect-receiver-and-waterfall/a-context-is-an-ownership-path-through-one-service-graph: + en: 201a1882518455e2 + zh: 830e25eab7ed37db +/agent-note-agent-scope-runtime-design-and-correctness/cordis-model-context-fiber-effect-receiver-and-waterfall/fibers-and-effects-make-cleanup-structural: + en: d0ef6e1b5d453350 + zh: 4a774ac9daf20849 +/agent-note-agent-scope-runtime-design-and-correctness/cordis-model-context-fiber-effect-receiver-and-waterfall/receivers-route-listeners-waterfalls-compose-decisions: + en: 594e198a8b566049 + zh: 50378e7a2a533dff +/agent-note-agent-scope-runtime-design-and-correctness/scope-routing-one-opaque-key-selects-one-layer: + en: fa59d22549e9e44a + zh: 80904729042e87b3 +/agent-note-agent-scope-runtime-design-and-correctness/scope-routing-one-opaque-key-selects-one-layer/scope-identity-uses-object-identity: + en: 3a05a7bfb2197f58 + zh: fbb599031788b70b +/agent-note-agent-scope-runtime-design-and-correctness/scope-routing-one-opaque-key-selects-one-layer/registry-reads-overlay-one-exact-layer: + en: 28636ae6d55935d7 + zh: 33a989f049de2f3e +/agent-note-agent-scope-runtime-design-and-correctness/scope-routing-one-opaque-key-selects-one-layer/fused-dispatch-helpers-prevent-subject-drift: + en: 638e3711206e3c41 + zh: 61d370123d30c1ed +/agent-note-agent-scope-runtime-design-and-correctness/agent-creation-one-transaction-owns-the-complete-operation: + en: ef58215c8554180b + zh: 44571074148d2467 +/agent-note-agent-scope-runtime-design-and-correctness/agent-creation-one-transaction-owns-the-complete-operation/registry-entries-are-the-only-live-identity-records: + en: 092b49671e83df98 + zh: 330ea6e45c4deb99 +/agent-note-agent-scope-runtime-design-and-correctness/agent-creation-one-transaction-owns-the-complete-operation/the-transaction-owns-preparation-before-awaiting-it: + en: 3940920908ec6066 + zh: 888e36ca43611d30 +/agent-note-agent-scope-runtime-design-and-correctness/agent-creation-one-transaction-owns-the-complete-operation/setup-is-trusted-composition-inside-a-private-world: + en: 40a73b8eede856ee + zh: 7dab8f2548cb92ea +/agent-note-agent-scope-runtime-design-and-correctness/agent-creation-one-transaction-owns-the-complete-operation/publication-has-one-ordered-commit-path: + en: 227eff7a5adacd0e + zh: b9ee423c2dd4212f +/agent-note-agent-scope-runtime-design-and-correctness/agent-creation-one-transaction-owns-the-complete-operation/teardown-preserves-work-before-revoking-registrations: + en: 1cbe77cff192815d + zh: 7f517936a8aa469e +/agent-note-agent-scope-runtime-design-and-correctness/session-append-materialize-validate-commit-notify: + en: cc37e93081fea4cb + zh: daf2234f84e4c9bf +/agent-note-agent-scope-runtime-design-and-correctness/session-append-materialize-validate-commit-notify/durable-data-is-materialized-once: + en: d0a57b0ac227d84c + zh: e9ae6ced0e65fe49 +/agent-note-agent-scope-runtime-design-and-correctness/session-append-materialize-validate-commit-notify/pre-commit-listeners-can-veto-post-commit-observers-cannot: + en: 15255d3d0b62fac0 + zh: c1995d5aa3c78f0a +/agent-note-agent-scope-runtime-design-and-correctness/trust-boundaries-copy-only-when-ownership-actually-changes: + en: 22b381902fe903f3 + zh: 8a2efe9a8b458bba +/agent-note-agent-scope-runtime-design-and-correctness/tools-and-prompts-one-view-authoritative-assembly-committed-outcomes: + en: 456ac0359d3c02f6 + zh: 9099e15d22139751 +/agent-note-agent-scope-runtime-design-and-correctness/tools-and-prompts-one-view-authoritative-assembly-committed-outcomes/one-resolver-defines-the-tool-view: + en: 120e1c79f0b99b1a + zh: 1c21a5b1d6b08235 +/agent-note-agent-scope-runtime-design-and-correctness/tools-and-prompts-one-view-authoritative-assembly-committed-outcomes/tool-execution-owns-identity-and-boundary-materialization: + en: 41f1f2ad73d83d73 + zh: e6bff63958ede05e +/agent-note-agent-scope-runtime-design-and-correctness/tools-and-prompts-one-view-authoritative-assembly-committed-outcomes/the-assembly-waterfall-owns-the-final-model-visible-composition: + en: 5c5880ccea139058 + zh: 3e5b7d10cb4c6ff8 +/agent-note-agent-scope-runtime-design-and-correctness/tools-and-prompts-one-view-authoritative-assembly-committed-outcomes/structured-output-commits-only-authoritative-outcomes: + en: a9a711cf31559765 + zh: e9083b000fc89128 +/agent-note-agent-scope-runtime-design-and-correctness/tools-and-prompts-one-view-authoritative-assembly-committed-outcomes/three-execution-boundaries-are-deliberately-one-way: + en: a109f3fadf338061 + zh: 12eb46fe775fa46a +/agent-note-agent-scope-runtime-design-and-correctness/tools-and-prompts-one-view-authoritative-assembly-committed-outcomes/skill-and-approval-services-trust-typed-callers: + en: 9572833d47f779e6 + zh: 7ff491d309060030 +/agent-note-agent-scope-runtime-design-and-correctness/subagents-publication-is-the-start-promise: + en: b9216021f8f50bcc + zh: fda52f9434cc8191 +/agent-note-agent-scope-runtime-design-and-correctness/subagents-publication-is-the-start-promise/the-service-contract-has-one-cancellation-channel: + en: 84a4be83b78c045b + zh: 043e14cf628413cd +/agent-note-agent-scope-runtime-design-and-correctness/subagents-publication-is-the-start-promise/in-process-providers-reuse-the-core-transaction: + en: b5e0b3dcf0dff750 + zh: 63905010383781b9 +/agent-note-agent-scope-runtime-design-and-correctness/subagents-publication-is-the-start-promise/acp-providers-own-the-process-until-readiness-or-cleanup: + en: aa0c00cee368c7e6 + zh: 767539b0f4d56f55 +/agent-note-agent-scope-runtime-design-and-correctness/workflows-and-acp-processes-retain-only-independent-async-facts: + en: effbb0acf7f66bed + zh: e0cc9ad6ac0777de +/agent-note-agent-scope-runtime-design-and-correctness/workflows-and-acp-processes-retain-only-independent-async-facts/workflow-children-are-pending-starts-or-published-records: + en: 9f05eed800f3413c + zh: 8230a28a0f94bffa +/agent-note-agent-scope-runtime-design-and-correctness/workflows-and-acp-processes-retain-only-independent-async-facts/terminal-result-and-physical-cleanup-remain-separate: + en: 5ad141c6df9f4fc3 + zh: 63effa4f14f3c530 +/agent-note-agent-scope-runtime-design-and-correctness/workflows-and-acp-processes-retain-only-independent-async-facts/acp-prompt-settlement-does-not-depend-on-update-delivery: + en: d39f73f50f0370bd + zh: 3889c1db46de560e +/agent-note-agent-scope-runtime-design-and-correctness/correctness-enforcement: + en: 840564e766d2f05c + zh: 059243afea7eb9c0 +/agent-note-agent-scope-runtime-design-and-correctness/correctness-enforcement/types-make-the-ordinary-path-hard-to-misuse: + en: 9183eb29dddfd97f + zh: e6ce13295e6c3e65 +/agent-note-agent-scope-runtime-design-and-correctness/correctness-enforcement/runtime-invariants-cover-cross-service-facts: + en: fabafbebc0ab4f95 + zh: 06d94a98ed5aa40c +/agent-note-agent-scope-runtime-design-and-correctness/correctness-enforcement/generated-artifacts-keep-public-contracts-aligned: + en: d0ddc5f38289225d + zh: 781d910228d5e334 +/agent-note-agent-scope-runtime-design-and-correctness/alternatives-considered: + en: 5eef7873a795c8f0 + zh: 3e8ba109a6e29ba5 +/agent-note-agent-scope-runtime-design-and-correctness/alternatives-considered/use-a-transparent-proxy-as-the-scope-carrier: + en: 199c7345a237e7e9 + zh: b262d5ad0c7cb562 +/agent-note-agent-scope-runtime-design-and-correctness/alternatives-considered/reserve-agent-and-session-ids-before-setup: + en: 3a8cb6969139dd84 + zh: 2913bb68433c9ec7 +/agent-note-agent-scope-runtime-design-and-correctness/alternatives-considered/snapshot-every-typed-same-process-argument: + en: 3e1f19f909f8d138 + zh: 0727777e34964afe +/agent-note-agent-scope-runtime-design-and-correctness/alternatives-considered/give-readiness-cancellation-and-disposal-separate-controllers: + en: f2c6ecbd139bbdb0 + zh: 0ff5b1e192dcb376 +/agent-note-agent-scope-runtime-design-and-correctness/alternatives-considered/keep-synchronous-subagent-start-plus-run-started: + en: 7f5669933cb35c9c + zh: c55e35d4c175af36 +/agent-note-agent-scope-runtime-design-and-correctness/alternatives-considered/restore-selected-prompt-or-tool-contributions-after-assembly: + en: a2b2e48d9ccda310 + zh: 3a4e925fde9d05b0 +/agent-note-agent-scope-runtime-design-and-correctness/alternatives-considered/remove-worker-process-lifecycle-guards-with-same-process-hardening: + en: 662e0904d90a3a94 + zh: 84c5e49f7cc59b32 +/agent-note-agent-scope-runtime-design-and-correctness/consequences: + en: 0d781b2dc4c41ddb + zh: 844652a4aaac37aa +/agent-note-agent-scope-runtime-design-and-correctness/consequences/what-the-design-guarantees: + en: eb2001592d7bd7b1 + zh: e534dbb6daa9af32 +/agent-note-agent-scope-runtime-design-and-correctness/consequences/costs-and-limits: + en: e9383713d56b9e10 + zh: d3ab00aea8ecf4e0 diff --git a/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.i18n.yaml index 07a0a60247..7d88d4ba73 100644 --- a/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-14-provider-routed-llm-adapters.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.md -2026-07-14-provider-routed-llm-adapters.md: 1001b10e18837399b41578658ffe62065e294ba8 -2026-07-14-provider-routed-llm-adapters.zh.md: c5bff0ef407c8a2c22e8cad7e7d32c58c8b0e2da +/agent-note-provider-routed-llm-adapters-and-a-generic-pi-ai-backend: + en: e57698907c40f783 + zh: 47004d8f68af1d7d +/agent-note-provider-routed-llm-adapters-and-a-generic-pi-ai-backend/problem: + en: 2e51f5fa703b0677 + zh: 385937219b88c447 +/agent-note-provider-routed-llm-adapters-and-a-generic-pi-ai-backend/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-provider-routed-llm-adapters-and-a-generic-pi-ai-backend/decision/provider-is-the-adapter-registration-key: + en: 4921a060c657b790 + zh: 2f9632469c6f0b60 +/agent-note-provider-routed-llm-adapters-and-a-generic-pi-ai-backend/decision/explicit-pi-ai-provider-profiles: + en: 5461685553dac663 + zh: e5c7e0ad7ac84e29 +/agent-note-provider-routed-llm-adapters-and-a-generic-pi-ai-backend/decision/recorded-assistant-route-and-replay-state: + en: 8439e90c9f6d7642 + zh: daeda3ce5146c9f5 +/agent-note-provider-routed-llm-adapters-and-a-generic-pi-ai-backend/decision/propagate-the-target-through-every-request-producer: + en: ba1908bc1517ed23 + zh: 1c9353a422cf74e1 +/agent-note-provider-routed-llm-adapters-and-a-generic-pi-ai-backend/alternatives-considered: + en: ad0d610ea92aa9b8 + zh: fe09d62762e73f01 +/agent-note-provider-routed-llm-adapters-and-a-generic-pi-ai-backend/consequences: + en: a0c98bced8a5e6fb + zh: 23caf082a08ba507 +/agent-note-provider-routed-llm-adapters-and-a-generic-pi-ai-backend/testing: + en: 5a36121f12701d08 + zh: 90f0f8ed44f7234f +/agent-note-provider-routed-llm-adapters-and-a-generic-pi-ai-backend/risks: + en: 11db2a349f9f26c2 + zh: 550d6017d8639854 diff --git a/.agents/notes/implemented/architecture/2026-07-15-agent-initiator-scope.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-15-agent-initiator-scope.i18n.yaml index 99577f250e..a90633f326 100644 --- a/.agents/notes/implemented/architecture/2026-07-15-agent-initiator-scope.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-15-agent-initiator-scope.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-15-agent-initiator-scope.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-15-agent-initiator-scope.md -2026-07-15-agent-initiator-scope.md: ab11da116a463cd706418e797eb58f1bc4ab9b1c -2026-07-15-agent-initiator-scope.zh.md: 343acba5f99379b6d2c3af41368e8fbe90b20611 +/agent-note-initiating-agent-scope-over-asynclocalstorage: + en: b0a59e3a34c41826 + zh: 7131428a14901d14 +/agent-note-initiating-agent-scope-over-asynclocalstorage/problem: + en: a26991200892c735 + zh: 04a7dfaca64e3f0c +/agent-note-initiating-agent-scope-over-asynclocalstorage/decision: + en: 43a4f0c503b30d95 + zh: a6a780584f94ed73 +/agent-note-initiating-agent-scope-over-asynclocalstorage/verification: + en: 312f5c4b843d515e + zh: a8993e3b84844fab +/agent-note-initiating-agent-scope-over-asynclocalstorage/alternatives-considered: + en: fd2ae1369fb3fbc6 + zh: e2a3d7f9331fc8ac +/agent-note-initiating-agent-scope-over-asynclocalstorage/consequences: + en: 625c6afc49489e29 + zh: ed7e5c5e56c781fb diff --git a/.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.i18n.yaml index a3dae54b9b..a7c6542f24 100644 --- a/.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-16-explicit-turn-cancellation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.md -2026-07-16-explicit-turn-cancellation.md: d59accf2dc3f894ffab226e5ddc9d2e746f4d93e -2026-07-16-explicit-turn-cancellation.zh.md: 8fb0728eb2bbe8fa01dbefebe7e02aa8c836617a +/agent-note-explicit-turn-cancellation-capability: + en: 729ed6291e9d4d2c + zh: 32ae526ef41199da +/agent-note-explicit-turn-cancellation-capability/problem: + en: 0a7826345be2a509 + zh: 430fccb5c4d6a5e2 +/agent-note-explicit-turn-cancellation-capability/decision: + en: 2c15edb35f38e7e5 + zh: fa5145d26e3bff20 +/agent-note-explicit-turn-cancellation-capability/verification: + en: a7ab1d06542be1c0 + zh: 1687979b7f2460fa +/agent-note-explicit-turn-cancellation-capability/alternatives-considered: + en: bf69bbf7eb280306 + zh: a434a0ecb5008b2b +/agent-note-explicit-turn-cancellation-capability/consequences: + en: 1066aff1aec4ed01 + zh: 31d6a60496e2e730 diff --git a/.agents/notes/implemented/architecture/2026-07-19-cooperative-tool-cancellation.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-19-cooperative-tool-cancellation.i18n.yaml index 41d4664d7d..7354602835 100644 --- a/.agents/notes/implemented/architecture/2026-07-19-cooperative-tool-cancellation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-19-cooperative-tool-cancellation.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-cooperative-tool-cancellation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-19-cooperative-tool-cancellation.md -2026-07-19-cooperative-tool-cancellation.md: 5ca2b44b24a4af189df27c6f724021a7bf290e2b -2026-07-19-cooperative-tool-cancellation.zh.md: d6d49fb44c5d5629729a8b5b4bad07ea9b2f7ee9 +/agent-note-cooperative-tool-cancellation-at-the-registry-boundary: + en: 84c827aa3baa331a + zh: 10cad03e58b10e31 +/agent-note-cooperative-tool-cancellation-at-the-registry-boundary/problem: + en: e386b22491b468c1 + zh: 82015f5145b679cd +/agent-note-cooperative-tool-cancellation-at-the-registry-boundary/decision: + en: ca66d3b6af50be10 + zh: f054b10d0c965e82 +/agent-note-cooperative-tool-cancellation-at-the-registry-boundary/decision/mutability-follows-the-pipeline-stage: + en: 0e1399cad4151f87 + zh: 960fa0ccbe0f8fea +/agent-note-cooperative-tool-cancellation-at-the-registry-boundary/decision/cancellation-codes-record-whether-dispatch-occurred: + en: c787fba8731ac147 + zh: 21b5968ae6f8cd59 +/agent-note-cooperative-tool-cancellation-at-the-registry-boundary/decision/pre-aborted-entry-short-circuits-after-materialization: + en: 53362db6a0c71698 + zh: 311de45ca26d3fdc +/agent-note-cooperative-tool-cancellation-at-the-registry-boundary/decision/started-work-still-reaches-quiescence: + en: 26e4b71366bebd1b + zh: 10598e12b28c586e +/agent-note-cooperative-tool-cancellation-at-the-registry-boundary/verification: + en: fbd101d4576afa92 + zh: 35f5d3c2f6cad6a8 +/agent-note-cooperative-tool-cancellation-at-the-registry-boundary/alternatives-considered: + en: 1f205f1a78d4fd5b + zh: 6c17e35da2909302 +/agent-note-cooperative-tool-cancellation-at-the-registry-boundary/consequences: + en: 24a9ad2c4c7c86b5 + zh: debdd29d272e07ea diff --git a/.agents/notes/implemented/architecture/2026-07-19-gui-web-client-architecture.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-19-gui-web-client-architecture.i18n.yaml index a64c2c83c2..b48fcf3403 100644 --- a/.agents/notes/implemented/architecture/2026-07-19-gui-web-client-architecture.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-19-gui-web-client-architecture.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-gui-web-client-architecture.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-19-gui-web-client-architecture.md -2026-07-19-gui-web-client-architecture.md: 4d62d7ddbeddd2d5c02e42194b035ee08b5cf041 -2026-07-19-gui-web-client-architecture.zh.md: aeb6c89e677d7b65daef03d5d31372f484ae3117 +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer: + en: e940be9ef95509ff + zh: c06cea53bb49c718 +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer/problem: + en: c5a3dda6ccd57c9e + zh: 122307b113bb1c09 +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer/decision: + en: 29742775aee9fbc3 + zh: 54a2df8816e2ea2e +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer/the-client-cordis-tree-and-the-loading-chain: + en: 23b0b6c3f29e4f5e + zh: 53bf897b502c645b +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer/the-slot-system-how-the-page-composes: + en: 1661f3dd74dc9df6 + zh: 3152467c7dd8e6ef +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer/services-and-scope-addressing: + en: 9da9311f677c5da6 + zh: 9cb16a92cee87055 +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer/the-data-object-layer-packages-api-session-controller-src-client: + en: 909682e20c0d23a1 + zh: ed1defbcf7745e8e +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer/the-react-face-packages-client-ui-renderer: + en: 0971d6196b5358fd + zh: 26175d648feccfd9 +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer/directory-shape: + en: 74c45680c8aab51c + zh: fd431ae5d3656038 +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer/how-to-develop: + en: cbc6abcd9f291868 + zh: 0078f15f2d08a02e +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer/consequences: + en: 56a9086da5783306 + zh: 8147576101d22aa0 +/agent-note-web-client-architecture-the-client-cordis-plugin-tree-the-slot-system-and-the-react-free-object-layer/alternatives-considered: + en: 8bedf2e688b14322 + zh: 7cda12f7474832ee diff --git a/.agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.i18n.yaml index ec285a946f..f8fe485684 100644 --- a/.agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-package-invariant-runtime-contracts.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.md -2026-07-19-package-invariant-runtime-contracts.md: a1b635cc40844f1846c04e203dbb842d1c7328ed -2026-07-19-package-invariant-runtime-contracts.zh.md: d315c440f1c100911386f57d6f82d5f16be631ca +/agent-note-meaningful-package-invariant-contracts: + en: e5db3b3373f72761 + zh: 312b83d320d9aaab +/agent-note-meaningful-package-invariant-contracts/problem: + en: 220a4ceb3cd9b9c9 + zh: 9eac93e1762b2914 +/agent-note-meaningful-package-invariant-contracts/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-meaningful-package-invariant-contracts/decision/published-assertions-must-be-meaningful: + en: 11a1c080592def10 + zh: d1189de665f9e327 +/agent-note-meaningful-package-invariant-contracts/decision/representative-implemented-checks: + en: 2f7ae4ed588d6de8 + zh: ed7ea9ccc6c54e87 +/agent-note-meaningful-package-invariant-contracts/decision/repository-gate-and-tests: + en: 37e646754f13dd65 + zh: 355ebf3ce1403117 +/agent-note-meaningful-package-invariant-contracts/alternatives-considered: + en: 74c6a5a0cfadbf88 + zh: e41356bb1a8c1fdf +/agent-note-meaningful-package-invariant-contracts/consequences: + en: 1f8d53063fb5903e + zh: 5edd23739749b065 diff --git a/.agents/notes/implemented/architecture/2026-07-19-zstandard-jsonl-session-logs.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-19-zstandard-jsonl-session-logs.i18n.yaml index 5e0c9ab302..9e8a30179e 100644 --- a/.agents/notes/implemented/architecture/2026-07-19-zstandard-jsonl-session-logs.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-19-zstandard-jsonl-session-logs.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-zstandard-jsonl-session-logs.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-19-zstandard-jsonl-session-logs.md -2026-07-19-zstandard-jsonl-session-logs.md: 96b76febee1c8853f70d7e4897894ea26390f524 -2026-07-19-zstandard-jsonl-session-logs.zh.md: 4cf184ce107b9de6dbbf3f0e571d4009d50ca636 +/agent-note-zstandard-jsonl-session-logs: + en: b46a6b48493de93e + zh: 0e394abf1d11fd43 +/agent-note-zstandard-jsonl-session-logs/problem: + en: da8b3d94d10b5bc4 + zh: da9c6d98a300b7bb +/agent-note-zstandard-jsonl-session-logs/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-zstandard-jsonl-session-logs/decision/configuration-and-suffix-ownership: + en: 1f29970aecc71980 + zh: 94414765645bace0 +/agent-note-zstandard-jsonl-session-logs/decision/frame-and-write-path: + en: da213ed32dfa6000 + zh: a0f3cd11684dbdc9 +/agent-note-zstandard-jsonl-session-logs/decision/read-listing-and-crash-recovery: + en: 63d4fe7d9c2a0a8a + zh: 2c4ef3e6aad73195 +/agent-note-zstandard-jsonl-session-logs/decision/consumers-and-verification: + en: 6d9d16d610b80e55 + zh: efa083ffaa7301e0 +/agent-note-zstandard-jsonl-session-logs/alternatives-considered: + en: c5f447029fb644f7 + zh: 5b84162e87bc6c86 +/agent-note-zstandard-jsonl-session-logs/consequences: + en: e721552f16340e4c + zh: d5be8c3ffd1c7cc2 diff --git a/.agents/notes/implemented/architecture/2026-07-20-canonical-tool-output-contract.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-20-canonical-tool-output-contract.i18n.yaml index cf9b3216dc..531d05cdc9 100644 --- a/.agents/notes/implemented/architecture/2026-07-20-canonical-tool-output-contract.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-20-canonical-tool-output-contract.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-20-canonical-tool-output-contract.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-20-canonical-tool-output-contract.md -2026-07-20-canonical-tool-output-contract.md: 4dbcac3da8381e69809b15a653cdb4987af4e0e7 -2026-07-20-canonical-tool-output-contract.zh.md: c2f4ebdfc7266495570766c69b3aa264f91172cc +/agent-note-canonical-tool-output-contract: + en: 01677f7875da9579 + zh: 41bae59177ba5125 +/agent-note-canonical-tool-output-contract/problem: + en: d0bc9840998f0530 + zh: 2601671ec694a78d +/agent-note-canonical-tool-output-contract/decision: + en: db088b8225a4bf3d + zh: bfb0caa015b2b7df +/agent-note-canonical-tool-output-contract/alternatives-considered: + en: d82a0ac0461ab120 + zh: bedea17fb4fb4f51 +/agent-note-canonical-tool-output-contract/consequences: + en: 32724ff8f6b3b03f + zh: bc7512ff05d00157 diff --git a/.agents/notes/implemented/architecture/2026-07-20-routed-model-context-and-compaction-policy.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-20-routed-model-context-and-compaction-policy.i18n.yaml index 081f618b1a..a21bb41371 100644 --- a/.agents/notes/implemented/architecture/2026-07-20-routed-model-context-and-compaction-policy.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-20-routed-model-context-and-compaction-policy.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-20-routed-model-context-and-compaction-policy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-20-routed-model-context-and-compaction-policy.md -2026-07-20-routed-model-context-and-compaction-policy.md: d276354cb21f45eaec1c4e3202c7be1770745efb -2026-07-20-routed-model-context-and-compaction-policy.zh.md: b6e2a0b914f78e19675d80b86d8d962e8ba8c80f +/agent-note-routed-model-context-and-compaction-policy: + en: eca190695d4857f5 + zh: f9d6411b8a8612ae +/agent-note-routed-model-context-and-compaction-policy/problem: + en: f7d1f343e487d725 + zh: c7f736180e44d586 +/agent-note-routed-model-context-and-compaction-policy/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-routed-model-context-and-compaction-policy/decision/adapters-own-exact-route-capacity: + en: 7bcf0ae2c74a0eb7 + zh: bc0e04a25492d5ba +/agent-note-routed-model-context-and-compaction-policy/decision/token-measurement-remains-model-agnostic: + en: 51d1b39d06407320 + zh: 85c88f6b5d8508d6 +/agent-note-routed-model-context-and-compaction-policy/decision/compact-basic-resolves-a-target-spec: + en: d8827f9fa70aa65f + zh: a9d29e05dcb0cfdb +/agent-note-routed-model-context-and-compaction-policy/decision/target-specific-pressure-failures-preserve-optional-composition: + en: 1bd81ae0a1409e24 + zh: 635c2937d5a94df7 +/agent-note-routed-model-context-and-compaction-policy/testing: + en: 1ac13596df50571f + zh: 8605a6f0de049dfc +/agent-note-routed-model-context-and-compaction-policy/alternatives-considered: + en: 0ca0a4b1318188ec + zh: de98cd4494a6c0d0 +/agent-note-routed-model-context-and-compaction-policy/consequences: + en: d00f83e85ba5e431 + zh: 32665480f0cdc4ea diff --git a/.agents/notes/implemented/architecture/2026-07-20-unified-json-value-schema-dsl.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-20-unified-json-value-schema-dsl.i18n.yaml index 152bae16ac..bf011b57b9 100644 --- a/.agents/notes/implemented/architecture/2026-07-20-unified-json-value-schema-dsl.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-20-unified-json-value-schema-dsl.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-20-unified-json-value-schema-dsl.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-20-unified-json-value-schema-dsl.md -2026-07-20-unified-json-value-schema-dsl.md: 5de3523eab15a91ea32dc09e2e239146fadea6f1 -2026-07-20-unified-json-value-schema-dsl.zh.md: 0dc38dc289a32269c0f9e545ae53a8098ba02189 +/agent-note-unified-json-value-schema-dsl: + en: 8ba380205c472f4e + zh: de92e20dc90e8037 +/agent-note-unified-json-value-schema-dsl/problem: + en: 5c7e79e37c007896 + zh: 759f5803141b0960 +/agent-note-unified-json-value-schema-dsl/decision: + en: 8f08bbafc8939a46 + zh: 2ed8255c1e2b812b +/agent-note-unified-json-value-schema-dsl/alternatives-considered: + en: 1d32d6195d6fca08 + zh: ea3a30126dca95f7 +/agent-note-unified-json-value-schema-dsl/consequences: + en: 14d0a6a337503e80 + zh: c7ffec8760a710af diff --git a/.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.i18n.yaml index f633a831d3..eeeda135fe 100644 --- a/.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.i18n.yaml @@ -1,6 +1,46 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-22-slot-type-chain-implementation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.md -2026-07-22-slot-type-chain-implementation.md: 98585a42f71844594da4ada19d7438a7d8321702 -2026-07-22-slot-type-chain-implementation.zh.md: d1093537ccbc5ee5ff2dc18c234233ffca39879d +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat: + en: 43ed5b2dfd8043fc + zh: 04b6fdd0435a265a +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/problem: + en: 4f8d6891a8ba7061 + zh: 5a619e562e00458d +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/decision: + en: a81cddbebc1a97a3 + zh: aa57738c9f08c07e +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/decision/root-is-the-only-a-priori-slot: + en: 43b856b4a8cf371f + zh: cde298ab8b8a3815 +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/decision/register-is-the-single-api-children-declaration-authorization-runtime-spec: + en: ce28268021a38b89 + zh: 7802540e4ef04752 +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/decision/component-props-four-shares-each-from-its-own-source-of-truth: + en: f3fca569fa0c5168 + zh: 647a82662f6a887d +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/decision/the-chain-kind-entries-self-nominate-first-match-renders: + en: 56278be7f3688805 + zh: 16602ffbf4baef85 +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/decision/the-store-seat-framework-engine-registrant-schema: + en: 2645acc9d29c20ec + zh: a8a2fd293ef5da04 +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/decision/inject-the-registrant-s-business-face-on-its-own-ctx: + en: 66b311fad441400a + zh: 34f031e7f04d29e6 +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/decision/data-boundary-discipline: + en: 07b919360c8f65be + zh: 4c8a9915a2ed20af +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/decision/tree-context-and-the-renderer-contract: + en: d77ebd3f6b166194 + zh: 57ba9fe864908d46 +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/decision/type-chain-implementation-rulings: + en: 752bc30428dad374 + zh: 3d729646468ecfde +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/consequences: + en: 07228332f3d3c227 + zh: 32525e1972acf156 +/agent-note-the-slot-system-standard-single-register-four-props-shares-and-the-framework-store-seat/alternatives-considered: + en: 2bd28715f741ac04 + zh: 8d6a0cb78a006533 diff --git a/.agents/notes/implemented/architecture/2026-07-23-client-plugin-loading-model.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-23-client-plugin-loading-model.i18n.yaml index 608fe717d5..142497a1d9 100644 --- a/.agents/notes/implemented/architecture/2026-07-23-client-plugin-loading-model.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-23-client-plugin-loading-model.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-23-client-plugin-loading-model.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-23-client-plugin-loading-model.md -2026-07-23-client-plugin-loading-model.md: b8c23108a7a1cf3a04ded373d8705bae626c70c2 -2026-07-23-client-plugin-loading-model.zh.md: efaea843120e5b023bbc8f59663ea47468944c71 +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload: + en: 874618fd5ad1d06a + zh: a5e4bfad490fab34 +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload/problem: + en: 46c4b208707e024e + zh: b6f86a6374b251da +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload/decision: + en: a15c7c13f167e5ac + zh: a15c7c13f167e5ac +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload/decision/package-membership-and-module-requests: + en: 6af228b03e5e533f + zh: 276a522af6be5d7a +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload/decision/one-module-system-one-plugin-governor: + en: 575aad62490f32e9 + zh: a6c18eb63965fc1e +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload/decision/combo-external-script-arrival-and-source-maps: + en: 0a4240d88cca240a + zh: 8f5f1527caf571cd +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload/decision/the-loading-flow-end-to-end: + en: 7dac236d6add3c3c + zh: 2a43a923a0646bb0 +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload/decision/live-graph-reconciliation: + en: 37e2fa1fe5cb2b95 + zh: 80e513db87709cb4 +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload/decision/hot-reload-one-driver-plugin-self-watched-bundles: + en: f8b591d4c41ef492 + zh: bc70f1cd540b7753 +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload/package-ownership: + en: 94ca0d09e6fd1e3a + zh: d5949a2bdec795ba +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload/consequences: + en: 6a96d9ac06c222e5 + zh: b2814ab58348e831 +/agent-note-client-plugin-loading-lazy-factories-cordis-lifecycle-and-hot-reload/alternatives-considered: + en: b8f036f50cff7cd8 + zh: 6d623c4a1f4314b1 diff --git a/.agents/notes/implemented/architecture/2026-07-24-project-session-directories.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-24-project-session-directories.i18n.yaml index 95adf4e6c5..28f986327b 100644 --- a/.agents/notes/implemented/architecture/2026-07-24-project-session-directories.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-24-project-session-directories.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-24-project-session-directories.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-24-project-session-directories.md -2026-07-24-project-session-directories.md: 0074c8b31304e6a7d32199b7461575356e406448 -2026-07-24-project-session-directories.zh.md: 3a1d348255588fd120221dc277a2841359c0a038 +/agent-note-project-grouped-session-directories: + en: c8960daf61fa50fa + zh: d8c7c844180fcaae +/agent-note-project-grouped-session-directories/problem: + en: 7df6078347bd7176 + zh: bb769760d7abc903 +/agent-note-project-grouped-session-directories/decision: + en: cdefd1f4d9d0a55a + zh: 5916d456f3faab2b +/agent-note-project-grouped-session-directories/alternatives-considered: + en: ba4657ba95479806 + zh: 5c53c5c964efa932 +/agent-note-project-grouped-session-directories/consequences: + en: 228c46a599899be1 + zh: 265a233cd41b5c05 diff --git a/.agents/notes/implemented/architecture/2026-07-24-separate-context-injection-from-turn-execution.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-24-separate-context-injection-from-turn-execution.i18n.yaml index b192622981..7e61625e6d 100644 --- a/.agents/notes/implemented/architecture/2026-07-24-separate-context-injection-from-turn-execution.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-24-separate-context-injection-from-turn-execution.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-24-separate-context-injection-from-turn-execution.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-24-separate-context-injection-from-turn-execution.md -2026-07-24-separate-context-injection-from-turn-execution.md: d22d3966767ae9888f2140141b1c7743792184c0 -2026-07-24-separate-context-injection-from-turn-execution.zh.md: 2c567511b21891ada3e0027f666d1163861fb090 +/agent-note-separate-context-injection-from-turn-execution: + en: f0090d5d271cbd9d + zh: 7ff28e03f1273093 +/agent-note-separate-context-injection-from-turn-execution/problem: + en: 2eefc25e17f62a90 + zh: 81bc7ff2649b2704 +/agent-note-separate-context-injection-from-turn-execution/decision: + en: 83dba9117127cbb4 + zh: 2b6b428a1c97d3b1 +/agent-note-separate-context-injection-from-turn-execution/injection-lifecycle: + en: 16005492be54cb4f + zh: db460e0ebf838d54 +/agent-note-separate-context-injection-from-turn-execution/extension-and-caller-semantics: + en: e184d8cd9676e24f + zh: 22465b570ae35f59 +/agent-note-separate-context-injection-from-turn-execution/alternatives-considered: + en: 0efad389c38dfe95 + zh: 13dd73de20226540 +/agent-note-separate-context-injection-from-turn-execution/verification: + en: 3f3db450a3fc5848 + zh: b2027393d570339d +/agent-note-separate-context-injection-from-turn-execution/consequences: + en: 71079e4dede5e12f + zh: deb46b5a4f151678 diff --git a/.agents/notes/implemented/architecture/2026-07-24-single-harness-home-resolver.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-24-single-harness-home-resolver.i18n.yaml index 83d23518ec..8622ce8f91 100644 --- a/.agents/notes/implemented/architecture/2026-07-24-single-harness-home-resolver.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-24-single-harness-home-resolver.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-24-single-harness-home-resolver.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-24-single-harness-home-resolver.md -2026-07-24-single-harness-home-resolver.md: 1191c52bfa222b807e9aa301b250d2efcc8b0953 -2026-07-24-single-harness-home-resolver.zh.md: cefa124b7cb46bab92157af34576f59d3053da9f +/agent-note-one-harness-home-resolver: + en: 4177acbdd51411da + zh: 53f10d4c54b431b2 +/agent-note-one-harness-home-resolver/problem: + en: fa4d3622fb18dd58 + zh: 2b98640594c8344b +/agent-note-one-harness-home-resolver/decision: + en: bbab99c7a1aae2fc + zh: 87453b98ca265699 +/agent-note-one-harness-home-resolver/alternatives-considered: + en: b1c9535540171d47 + zh: 7df816d42945db94 +/agent-note-one-harness-home-resolver/consequences: + en: 7d0f569b98feadf5 + zh: 5c84624e7cc8d1d4 diff --git a/.agents/notes/implemented/architecture/2026-07-24-web-config-tree-boot-and-transport-layering.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-24-web-config-tree-boot-and-transport-layering.i18n.yaml index 4951fbfe77..63949a5c87 100644 --- a/.agents/notes/implemented/architecture/2026-07-24-web-config-tree-boot-and-transport-layering.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-24-web-config-tree-boot-and-transport-layering.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-24-web-config-tree-boot-and-transport-layering.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-24-web-config-tree-boot-and-transport-layering.md -2026-07-24-web-config-tree-boot-and-transport-layering.md: c8a1db3cd7bd715d8912b22a0b41a9ef660c1316 -2026-07-24-web-config-tree-boot-and-transport-layering.zh.md: 41fcf65b06829199c203faa806bd17a310b68bcf +/agent-note-dsh-web-config-tree-boot-and-the-web-transport-layering: + en: 2d06ffcaaeb373e7 + zh: 01822cfd7339167f +/agent-note-dsh-web-config-tree-boot-and-the-web-transport-layering/problem: + en: e5d603f77bff9dd7 + zh: c9e9a64f0a4db3c9 +/agent-note-dsh-web-config-tree-boot-and-the-web-transport-layering/decision: + en: 866ebaaf4fe1e0d1 + zh: 8075a708c9042941 +/agent-note-dsh-web-config-tree-boot-and-the-web-transport-layering/consequences: + en: 47f8a6beba1f320b + zh: 5f444699dc52cabf +/agent-note-dsh-web-config-tree-boot-and-the-web-transport-layering/alternatives-considered: + en: bf6fbf972eab0700 + zh: 0f3449e5e6ace7e2 diff --git a/.agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.i18n.yaml index da98873480..cc78be86f5 100644 --- a/.agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.i18n.yaml @@ -1,6 +1,43 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-25-web-client-session-scope-and-provide-channel.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.md -2026-07-25-web-client-session-scope-and-provide-channel.md: 76561bc0e330b3e3a26607569ae327217d0a0b67 -2026-07-25-web-client-session-scope-and-provide-channel.zh.md: d5d92b2ca53ba78929dd8591a6ded7028e4fed24 +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide: + en: 64d8701a9f2574bd + zh: 938991d424943547 +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/problem: + en: 1738c071cb9824bc + zh: 7af7770739d5430a +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/decision: + en: a397a3f2e0bd7c21 + zh: a179a646c148ecc1 +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/decision/the-parity-model-client-and-host-share-one-root-state-axis: + en: e117f541a2f55c07 + zh: c6a5cf9c9d6b7692 +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/decision/agent-scope-the-actx-is-the-sole-session-carrier-in-the-client-side-cordis-world: + en: 6e6488b3eab757c2 + zh: 4ee3d1cc415234df +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/decision/scope-lifecycle-anchored-to-explicit-references: + en: e2ed0052678a2b9b + zh: e0fe1b87dc3766af +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/decision/the-blank-bit-the-empty-session-s-visible-projection-conversion-and-reuse: + en: ee88908c085b80c5 + zh: 5ddb65bbac371f02 +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/decision/connectworkspace-the-sole-entry-point-of-new-session: + en: 833df42c5a87afbd + zh: 82d789a99fd2b968 +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/decision/per-session-provisioning-the-uisession-provide-standard-kit-channel: + en: 3c739c21ea490f09 + zh: 5508153f313a86d9 +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/decision/input-delivery: + en: 2073e96f851d1e6e + zh: f0433bf5dfd0a23d +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/decision/host-wire-smalls: + en: 5d1339b5a243812a + zh: a4be4d3c30056f42 +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/alternatives-considered: + en: 2a69d71f4bdf0f76 + zh: dd768c273728d354 +/agent-note-web-client-agent-scope-parity-model-and-the-provisioning-channel-agents-scope-blank-reuse-provide/consequences: + en: 6750378aca400a75 + zh: 6eba20215ff255a1 diff --git a/.agents/notes/implemented/architecture/2026-07-27-compiler-independent-typert-model.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-27-compiler-independent-typert-model.i18n.yaml index 1709d91e34..50fa27df10 100644 --- a/.agents/notes/implemented/architecture/2026-07-27-compiler-independent-typert-model.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-27-compiler-independent-typert-model.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-27-compiler-independent-typert-model.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-27-compiler-independent-typert-model.md -2026-07-27-compiler-independent-typert-model.md: 5083c55176b2f4d342d14d0c1cf2a7f0c2c14b3c -2026-07-27-compiler-independent-typert-model.zh.md: 70d6954fae0fcb48e76137231168d5f2417668bf +/agent-note-compiler-independent-typert-type-model: + en: 6943b47c9de69922 + zh: 2fb08c1de4e6ea63 +/agent-note-compiler-independent-typert-type-model/problem: + en: 77713a6c0d15207e + zh: 2dc30d4c0182d8ba +/agent-note-compiler-independent-typert-type-model/decision: + en: 9ecb064f733f9f1b + zh: 471aee71053174cd +/agent-note-compiler-independent-typert-type-model/verification-contract: + en: c02d3f09e54f9a32 + zh: c14c15ffb7316b07 +/agent-note-compiler-independent-typert-type-model/alternatives-considered: + en: fa503dcfaa6f438f + zh: 26052212a124e133 +/agent-note-compiler-independent-typert-type-model/consequences: + en: 4a472acf377f8361 + zh: cb83602b123a4aae diff --git a/.agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.i18n.yaml index d4ca06ac71..a102c752b0 100644 --- a/.agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-28-api-browser-trust-boundary.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.md -2026-07-28-api-browser-trust-boundary.md: 397c93e084f84579ce3f90654f514428e696ffcd -2026-07-28-api-browser-trust-boundary.zh.md: 6d3896fd2c1fd6c607b9d92376eee76ab03df3c7 +/agent-note-one-carrier-level-browser-trust-boundary-for-all-api-routes: + en: 491d0faf230d0278 + zh: 40c8eef7719fe354 +/agent-note-one-carrier-level-browser-trust-boundary-for-all-api-routes/problem: + en: c25db2ef111b2276 + zh: 557891ca9e030ae5 +/agent-note-one-carrier-level-browser-trust-boundary-for-all-api-routes/decision: + en: 1a1af1e8125ba4b0 + zh: dd6c282651a06af5 +/agent-note-one-carrier-level-browser-trust-boundary-for-all-api-routes/alternatives-considered: + en: 1a4b0ae8072e8e50 + zh: d469553ad3b5d112 +/agent-note-one-carrier-level-browser-trust-boundary-for-all-api-routes/consequences: + en: 8acf5e6f55a747c2 + zh: bbd0b10927302965 diff --git a/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.i18n.yaml index 56d5cea939..d7661445ba 100644 --- a/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-28-identified-immutable-message-values.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-28-identified-immutable-message-values.md -2026-07-28-identified-immutable-message-values.md: 73c9c14479117cf654d10b3da23d155cca77054d -2026-07-28-identified-immutable-message-values.zh.md: 7a5b9d6524beff01ac8a9e2020f75093271b7ab3 +/agent-note-create-every-message-as-an-identified-immutable-value: + en: 0bb4f6acecd9b6f1 + zh: 11e17fde272119f1 +/agent-note-create-every-message-as-an-identified-immutable-value/problem: + en: 9334a7a325a88fda + zh: c21c8cee318c6a35 +/agent-note-create-every-message-as-an-identified-immutable-value/decision: + en: a4434de753a41d41 + zh: f16e5cd634245f0e +/agent-note-create-every-message-as-an-identified-immutable-value/alternatives-considered: + en: bf73901dd2b977ed + zh: 5ba5d4d05051b1da +/agent-note-create-every-message-as-an-identified-immutable-value/consequences: + en: 9f2c40ccfcf03ee1 + zh: 0e8ba6c97f2e32af +/agent-note-create-every-message-as-an-identified-immutable-value/related: + en: 7c476f1a5195dff9 + zh: c878154dbf766e82 diff --git a/.agents/notes/implemented/architecture/2026-07-28-portable-execution-world-consumers.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-28-portable-execution-world-consumers.i18n.yaml index 7aec04b3d6..babbdf4b6f 100644 --- a/.agents/notes/implemented/architecture/2026-07-28-portable-execution-world-consumers.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-28-portable-execution-world-consumers.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-28-portable-execution-world-consumers.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-28-portable-execution-world-consumers.md -2026-07-28-portable-execution-world-consumers.md: 5a687a552f322f3929b3f3937caf36c3373c05e7 -2026-07-28-portable-execution-world-consumers.zh.md: 6bc0e20bd29d0b0a01068c004655cc90ac3b6699 +/agent-note-portable-consumers-over-filesystem-and-subprocess-execution-worlds: + en: 42609904ffe19d80 + zh: fcacbf7912df216c +/agent-note-portable-consumers-over-filesystem-and-subprocess-execution-worlds/problem: + en: 959a378a04f28e89 + zh: ff496169735b4d7b +/agent-note-portable-consumers-over-filesystem-and-subprocess-execution-worlds/decision: + en: 23eca65b89ae572a + zh: 630d844a7c6438df +/agent-note-portable-consumers-over-filesystem-and-subprocess-execution-worlds/remote-provider-ownership: + en: bde2e1fa8f3aeee0 + zh: 42a13bb4cf540d6d +/agent-note-portable-consumers-over-filesystem-and-subprocess-execution-worlds/verification: + en: b34540c3548ea98f + zh: 79e53bda3981802c +/agent-note-portable-consumers-over-filesystem-and-subprocess-execution-worlds/alternatives-considered: + en: a5f455ad35d0615c + zh: df4f501a6d723838 +/agent-note-portable-consumers-over-filesystem-and-subprocess-execution-worlds/consequences: + en: 3e8426e4a6788505 + zh: 143b8c07d21d95d1 diff --git a/.agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.i18n.yaml index cabffaebf6..7bd5c73590 100644 --- a/.agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-29-dsh-source-launch-tsx-esm.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.md -2026-07-29-dsh-source-launch-tsx-esm.md: 700577cb9b137d67f20baeb639f99f4c0877011d -2026-07-29-dsh-source-launch-tsx-esm.zh.md: 4d322d3dcf49442ee62f82203f17bd2ab16467fe +/agent-note-dsh-source-launch-through-the-tsx-esm-hook: + en: 55846ac57e07eeda + zh: 3de03730d4b28863 +/agent-note-dsh-source-launch-through-the-tsx-esm-hook/problem: + en: 68385f7e47d3ac1f + zh: 285ca290832e2939 +/agent-note-dsh-source-launch-through-the-tsx-esm-hook/decision: + en: 12adf8ed56b4d5c3 + zh: fbbb9add935730c0 +/agent-note-dsh-source-launch-through-the-tsx-esm-hook/alternatives-considered: + en: c6eec3d899a61df1 + zh: 128edd753d49c0da +/agent-note-dsh-source-launch-through-the-tsx-esm-hook/consequences: + en: 7c8eb105520ccae3 + zh: 9dc85ecda408de5a diff --git a/.agents/notes/implemented/architecture/2026-07-29-projected-token-usage-and-request-context.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-29-projected-token-usage-and-request-context.i18n.yaml index a5d41c6bca..22d12f0aab 100644 --- a/.agents/notes/implemented/architecture/2026-07-29-projected-token-usage-and-request-context.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-29-projected-token-usage-and-request-context.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-29-projected-token-usage-and-request-context.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-29-projected-token-usage-and-request-context.md -2026-07-29-projected-token-usage-and-request-context.md: 10056ac8ef85562035d4fc4591e90aec603a7dd8 -2026-07-29-projected-token-usage-and-request-context.zh.md: 0e4cd68791f0ee65dd700b64493be3c33b78a920 +/agent-note-projected-token-usage-and-context-occupancy: + en: 293fcae41011ed29 + zh: 9a018a07b6491173 +/agent-note-projected-token-usage-and-context-occupancy/problem: + en: 081098cb08ca80aa + zh: f829b6630a68fc3c +/agent-note-projected-token-usage-and-context-occupancy/decision: + en: 231a6f4a4c00dca6 + zh: e90c76e425826ca0 +/agent-note-projected-token-usage-and-context-occupancy/context-occupancy-is-approximate-and-that-is-the-decision: + en: 9df83c0a48f462d2 + zh: 94c2ad19af4b13fc +/agent-note-projected-token-usage-and-context-occupancy/alternatives-considered: + en: 50272313b4f061cc + zh: 1cfd7374e4bdfed9 +/agent-note-projected-token-usage-and-context-occupancy/consequences: + en: c7a407dc3964fb9d + zh: b1ac7c53abb5cb09 diff --git a/.agents/notes/implemented/architecture/2026-07-29-terminal-llm-stream-failures.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-29-terminal-llm-stream-failures.i18n.yaml index 04a5f80eec..ddc9c2bc46 100644 --- a/.agents/notes/implemented/architecture/2026-07-29-terminal-llm-stream-failures.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-29-terminal-llm-stream-failures.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-29-terminal-llm-stream-failures.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-29-terminal-llm-stream-failures.md -2026-07-29-terminal-llm-stream-failures.md: c5d160c5dffe6171dd79714f2402f3bd6ca4d3fc -2026-07-29-terminal-llm-stream-failures.zh.md: 297898d8f94ae4f00ab1c5fef192ce633aee99cd +/agent-note-terminal-llm-stream-failures: + en: 6195cb1d9b4dd423 + zh: 0c93d3a39e2bc1f4 +/agent-note-terminal-llm-stream-failures/problem: + en: 41363fca57ae20e6 + zh: 1d05eeeecaafa7f3 +/agent-note-terminal-llm-stream-failures/decision: + en: c3bfde5f736f8b27 + zh: f51ebb4089df6406 +/agent-note-terminal-llm-stream-failures/alternatives-considered: + en: 46153a92b2135aae + zh: 0b8fdaf1f7edeb77 +/agent-note-terminal-llm-stream-failures/consequences: + en: 9bf05473682c5cef + zh: b93f32470eb08cf4 diff --git a/.agents/notes/implemented/architecture/2026-07-30-credential-boundaries-and-atomic-registration.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-30-credential-boundaries-and-atomic-registration.i18n.yaml index ccbabe4e0d..a4c259b654 100644 --- a/.agents/notes/implemented/architecture/2026-07-30-credential-boundaries-and-atomic-registration.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-30-credential-boundaries-and-atomic-registration.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-30-credential-boundaries-and-atomic-registration.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-30-credential-boundaries-and-atomic-registration.md -2026-07-30-credential-boundaries-and-atomic-registration.md: 0e65bb1093bb21c3a0dbee71b4e80ba4276b9d00 -2026-07-30-credential-boundaries-and-atomic-registration.zh.md: cbc66efa26065beb54ee1deea0f69221ebd92337 +/agent-note-credential-boundaries-whole-snapshot-requests-and-atomic-route-registration: + en: 0b33f9d64be7149a + zh: 365ea54cf9fd4924 +/agent-note-credential-boundaries-whole-snapshot-requests-and-atomic-route-registration/problem: + en: 6228c81e4965b688 + zh: 04b702be0cfbf195 +/agent-note-credential-boundaries-whole-snapshot-requests-and-atomic-route-registration/decision: + en: d2aa88cf1e9ec97b + zh: da9422723fc9ac93 +/agent-note-credential-boundaries-whole-snapshot-requests-and-atomic-route-registration/alternatives-considered: + en: 90c5883b247f7301 + zh: 6d2a660d8653f805 +/agent-note-credential-boundaries-whole-snapshot-requests-and-atomic-route-registration/consequences: + en: 99b678779110e0d1 + zh: 5790590caab41e0c diff --git a/.agents/notes/implemented/architecture/2026-07-30-followup-enqueue-and-owned-runs.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-30-followup-enqueue-and-owned-runs.i18n.yaml index b729d9dd5b..91a956e428 100644 --- a/.agents/notes/implemented/architecture/2026-07-30-followup-enqueue-and-owned-runs.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-30-followup-enqueue-and-owned-runs.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-30-followup-enqueue-and-owned-runs.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-30-followup-enqueue-and-owned-runs.md -2026-07-30-followup-enqueue-and-owned-runs.md: c9b3b992dffb39c94b476cd6541b8ec9e2256047 -2026-07-30-followup-enqueue-and-owned-runs.zh.md: 7f272484cad4f9d0fd918e5c1b05fb8fcb0384c0 +/agent-note-follow-up-enqueue-and-owned-run-boundaries: + en: 30b533c813f80a2c + zh: 5f56ae990ca597f2 +/agent-note-follow-up-enqueue-and-owned-run-boundaries/problem: + en: 33387f4ed29e967b + zh: b61ab718327d4cc9 +/agent-note-follow-up-enqueue-and-owned-run-boundaries/decision: + en: 9d68149d8090d355 + zh: d3efa8ac850603bf +/agent-note-follow-up-enqueue-and-owned-run-boundaries/alternatives-considered: + en: 70a57101ffa08e81 + zh: 36c3539ee9c759af +/agent-note-follow-up-enqueue-and-owned-run-boundaries/verification: + en: 4c65688fc0bc1f6c + zh: 04f1fd160e38a69d +/agent-note-follow-up-enqueue-and-owned-run-boundaries/consequences: + en: 7de608183c0bd34d + zh: 598eeb85cfd2993b diff --git a/.agents/notes/implemented/architecture/2026-07-30-session-end-seed-log-boundary.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-30-session-end-seed-log-boundary.i18n.yaml index 01690045bd..18ab603d7b 100644 --- a/.agents/notes/implemented/architecture/2026-07-30-session-end-seed-log-boundary.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-30-session-end-seed-log-boundary.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-30-session-end-seed-log-boundary.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-30-session-end-seed-log-boundary.md -2026-07-30-session-end-seed-log-boundary.md: 9cf7c7f20701688208e8b1c343904f2a9f2cab9e -2026-07-30-session-end-seed-log-boundary.zh.md: fdf4ec9de610f17e792de98334dd5d37f5e4c355 +/agent-note-the-end-seed-log-boundary: + en: 0f53ca9c0166d7ad + zh: e16b2376c2afb1bc +/agent-note-the-end-seed-log-boundary/problem: + en: e7192f854b24129c + zh: 74a38ee95988e338 +/agent-note-the-end-seed-log-boundary/decision: + en: 519aa4faadd01960 + zh: 1430cc9bd81e7df9 +/agent-note-the-end-seed-log-boundary/persistence-needs-no-changes: + en: 5df69ed0156e50c8 + zh: 9ad6caad6d33b183 +/agent-note-the-end-seed-log-boundary/scope-of-the-guarantee: + en: 31c23e4e25640fb1 + zh: d207c2a8aa7d936c +/agent-note-the-end-seed-log-boundary/alternatives-considered: + en: cd1ed7dfa77722ae + zh: 4ad834f3cf3b5443 +/agent-note-the-end-seed-log-boundary/consequences: + en: 69eb86480b191135 + zh: 51ef88fb78701b1f diff --git a/.agents/notes/implemented/architecture/2026-07-31-claimed-pre-step-inbox-lifecycle.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-31-claimed-pre-step-inbox-lifecycle.i18n.yaml index 049fbfff18..7151c1e20c 100644 --- a/.agents/notes/implemented/architecture/2026-07-31-claimed-pre-step-inbox-lifecycle.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-31-claimed-pre-step-inbox-lifecycle.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-31-claimed-pre-step-inbox-lifecycle.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-31-claimed-pre-step-inbox-lifecycle.md -2026-07-31-claimed-pre-step-inbox-lifecycle.md: 3ebb73279e49c2aaffa05bea647fa3f93ba6a36f -2026-07-31-claimed-pre-step-inbox-lifecycle.zh.md: 809470e5b52b29cdcbe7b4d81bb584b476f5cfce +/agent-note-claim-inbox-input-before-one-pre-step-decision: + en: 4ee4c56f27c9bf27 + zh: 72321b4c735e106f +/agent-note-claim-inbox-input-before-one-pre-step-decision/problem: + en: f2a920b8770c2f99 + zh: 1c111f175131714e +/agent-note-claim-inbox-input-before-one-pre-step-decision/decision: + en: 2e58afbd8ffbce60 + zh: 40e0c0e3d24fc7ad +/agent-note-claim-inbox-input-before-one-pre-step-decision/alternatives-considered: + en: 03496db1c0547f71 + zh: c0932cfcb5d5d93b +/agent-note-claim-inbox-input-before-one-pre-step-decision/verification: + en: 007a79d6db18cbab + zh: 611306fcb5edfda0 +/agent-note-claim-inbox-input-before-one-pre-step-decision/consequences: + en: ba68c3ce7ed64bcc + zh: 8fe29186526b258a diff --git a/.agents/notes/implemented/architecture/2026-07-31-goal-owned-durable-events.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-31-goal-owned-durable-events.i18n.yaml index aecb82c585..18c1983fdb 100644 --- a/.agents/notes/implemented/architecture/2026-07-31-goal-owned-durable-events.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-31-goal-owned-durable-events.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-31-goal-owned-durable-events.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-31-goal-owned-durable-events.md -2026-07-31-goal-owned-durable-events.md: 0d3e632ba275f38e48fdf1f9ee6747f4bc460aab -2026-07-31-goal-owned-durable-events.zh.md: fd29a6f36eed42f5ba26a46a32acb165d1e42873 +/agent-note-goal-owned-durable-events: + en: a8fca44de335547c + zh: e0cc7072f2247a19 +/agent-note-goal-owned-durable-events/problem: + en: 882023626c792880 + zh: 1966501718e96f92 +/agent-note-goal-owned-durable-events/decision: + en: cc99d9ce1f6ebb9a + zh: 34e519f16d8d5e3e +/agent-note-goal-owned-durable-events/alternatives-considered: + en: 7d79dfa834d9168f + zh: 0b3e82a7d0ef71b9 +/agent-note-goal-owned-durable-events/consequences: + en: 0e4513ea5e3e1e2e + zh: 69d81ba52ee2f4b6 diff --git a/.agents/notes/implemented/architecture/2026-07-31-ptc-runtime-python-fd3-protocol.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-31-ptc-runtime-python-fd3-protocol.i18n.yaml index aaa0f005af..85084f80cb 100644 --- a/.agents/notes/implemented/architecture/2026-07-31-ptc-runtime-python-fd3-protocol.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-31-ptc-runtime-python-fd3-protocol.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-31-ptc-runtime-python-fd3-protocol.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-31-ptc-runtime-python-fd3-protocol.md -2026-07-31-ptc-runtime-python-fd3-protocol.md: 097bcfd55f333a0973084f378a6c97cb630a4bec -2026-07-31-ptc-runtime-python-fd3-protocol.zh.md: ac656e421bd822994c50c33d0dfaf65ae46aa817 +/agent-note-the-ptc-runtime-python-fd-3-frame-protocol: + en: fc43bcfc72cc4476 + zh: c81279cb0da1481c +/agent-note-the-ptc-runtime-python-fd-3-frame-protocol/problem: + en: 2c36946bbff637b7 + zh: f290de0866ba7caa +/agent-note-the-ptc-runtime-python-fd-3-frame-protocol/decision: + en: 1f93159850fc7f48 + zh: dcc2a4788e3254f7 +/agent-note-the-ptc-runtime-python-fd-3-frame-protocol/wire-contract: + en: 913f9465320dc191 + zh: f8e0338645d6c204 +/agent-note-the-ptc-runtime-python-fd-3-frame-protocol/mirror-alignment: + en: 26128b65f2763920 + zh: df24359faebcbfed +/agent-note-the-ptc-runtime-python-fd-3-frame-protocol/alternatives-considered: + en: cc42636bd7793305 + zh: e196f980daec3037 +/agent-note-the-ptc-runtime-python-fd-3-frame-protocol/consequences: + en: 16df6efd46d71e85 + zh: 4062475bec04ab5f diff --git a/.agents/notes/implemented/architecture/2026-08-02-typert-remote-method-calls.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-02-typert-remote-method-calls.i18n.yaml index 279482f67a..b86fbe45fb 100644 --- a/.agents/notes/implemented/architecture/2026-08-02-typert-remote-method-calls.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-02-typert-remote-method-calls.i18n.yaml @@ -1,6 +1,76 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-02-typert-remote-method-calls.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-02-typert-remote-method-calls.md -2026-08-02-typert-remote-method-calls.md: 2a12aaf78f638d8af786d2ca817a3fee07a2c614 -2026-08-02-typert-remote-method-calls.zh.md: bf4a7b0179b4dc878a0a53c7076c02e6f1bf0273 +/agent-note-typert-gateway-targeted-method-calls: + en: 4d77bacdc36f246b + zh: b884bf274df490af +/agent-note-typert-gateway-targeted-method-calls/problem: + en: 14a83a0440499136 + zh: 15587f8e821c5a17 +/agent-note-typert-gateway-targeted-method-calls/decision: + en: 44d946b53496974c + zh: 403447c25a5b2d7c +/agent-note-typert-gateway-targeted-method-calls/components-and-cordis-services: + en: aa7f509189ade32e + zh: ef2841bc793f31b2 +/agent-note-typert-gateway-targeted-method-calls/business-declarations: + en: c6b70d442b137d2e + zh: 6d0dbefe89937ef1 +/agent-note-typert-gateway-targeted-method-calls/decorators-and-the-explicit-gateway-facet: + en: 155afbe4b8af600b + zh: 14705698a9cdbd84 +/agent-note-typert-gateway-targeted-method-calls/lookup-and-remote-scope-registration: + en: 9f7448898cf5cadc + zh: 419573c589ed6f7d +/agent-note-typert-gateway-targeted-method-calls/invocationdescriptor: + en: aad682229b400d49 + zh: 60c2857fca1f4b2b +/agent-note-typert-gateway-targeted-method-calls/typert-runtime-registry: + en: 14ad652e20e699ca + zh: 9272bc04a35e3c6a +/agent-note-typert-gateway-targeted-method-calls/canonical-types-symbols-and-zod: + en: a244f6a88fdabf3d + zh: e4feedb7297f4865 +/agent-note-typert-gateway-targeted-method-calls/three-artifact-kinds-and-two-typescript-programs: + en: 6ea4bddcf35a834d + zh: 4af474c6818b1cf0 +/agent-note-typert-gateway-targeted-method-calls/the-remote-package-entry: + en: 75e977fe0fb71d59 + zh: 00760c79da173cb7 +/agent-note-typert-gateway-targeted-method-calls/strict-consumer-api-types: + en: 983f55c0ed4a8edc + zh: 5a736e00e4b57e6a +/agent-note-typert-gateway-targeted-method-calls/client-typert-and-the-api-gateway-client-face: + en: 9dc732c13ffaee63 + zh: 4977aaef0856956d +/agent-note-typert-gateway-targeted-method-calls/cross-environment-isomorphism-constraints: + en: 5d14e1b7afc53efb + zh: e2f4b5814083738f +/agent-note-typert-gateway-targeted-method-calls/src-and-lib-operating-modes: + en: 1e366dcfab74831b + zh: 14199f25f20a9352 +/agent-note-typert-gateway-targeted-method-calls/host-gateway-resolution: + en: 88a95d7ab4621caf + zh: 89b63fb6440fca79 +/agent-note-typert-gateway-targeted-method-calls/the-shared-api-call-chain: + en: 391a59d0ba24cb34 + zh: b7294d6bb5f9d297 +/agent-note-typert-gateway-targeted-method-calls/connection-and-protocol-boundaries: + en: e8f9d48c42e27fb6 + zh: 445bc192d67c71f1 +/agent-note-typert-gateway-targeted-method-calls/package-boundaries: + en: df2c448d3a0680eb + zh: 47327d4d26ec5887 +/agent-note-typert-gateway-targeted-method-calls/shipped-scope-and-deferred-work: + en: b1c0c3dd77c56ce8 + zh: 769ffd4aeefd949c +/agent-note-typert-gateway-targeted-method-calls/alternatives-considered: + en: 0d68c499b7780f4f + zh: bdd1e57232b996e2 +/agent-note-typert-gateway-targeted-method-calls/verification: + en: 7433bdb522bb2083 + zh: 545c17613b636f00 +/agent-note-typert-gateway-targeted-method-calls/consequences: + en: c3459afdb606cfbe + zh: ec69f2bb39170a7c diff --git a/.agents/notes/implemented/architecture/2026-08-04-configuration-source-ownership.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-04-configuration-source-ownership.i18n.yaml index 67681ae7a7..9cd1ebd5f3 100644 --- a/.agents/notes/implemented/architecture/2026-08-04-configuration-source-ownership.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-04-configuration-source-ownership.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-04-configuration-source-ownership.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-04-configuration-source-ownership.md -2026-08-04-configuration-source-ownership.md: b8c146ed76e500fcde3affd92bc5188b83083223 -2026-08-04-configuration-source-ownership.zh.md: 22afc15aec97a40829655fcb8179ad90a369bf0c +/agent-note-one-ordering-for-configuration-sources-and-what-a-discovered-file-may-not-decide: + en: 1f6ee603f36c2e09 + zh: e08197958663219c +/agent-note-one-ordering-for-configuration-sources-and-what-a-discovered-file-may-not-decide/problem: + en: d94bb81479bfa4a1 + zh: af44ceaecf84ee51 +/agent-note-one-ordering-for-configuration-sources-and-what-a-discovered-file-may-not-decide/decision: + en: aea80ece13f2905b + zh: a880bc1a7839cf12 +/agent-note-one-ordering-for-configuration-sources-and-what-a-discovered-file-may-not-decide/consequences: + en: 640b7ee4e8c57ed0 + zh: 1c17b3fba16861a8 +/agent-note-one-ordering-for-configuration-sources-and-what-a-discovered-file-may-not-decide/alternatives-considered: + en: ac43499cfe7b8495 + zh: e5ab599e7d3ed753 diff --git a/.agents/notes/implemented/architecture/2026-08-04-draft-provider-endpoint-interrogation.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-04-draft-provider-endpoint-interrogation.i18n.yaml index 17747b2942..0e07d79d52 100644 --- a/.agents/notes/implemented/architecture/2026-08-04-draft-provider-endpoint-interrogation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-04-draft-provider-endpoint-interrogation.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-04-draft-provider-endpoint-interrogation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-04-draft-provider-endpoint-interrogation.md -2026-08-04-draft-provider-endpoint-interrogation.md: 469ab38b0f5609808a9df03237d4d21c0080d843 -2026-08-04-draft-provider-endpoint-interrogation.zh.md: 74c6bc7ed73572d5e99ea973c9ea94d22319cbdf +/agent-note-interrogating-a-draft-provider-endpoint: + en: a465a218bbc2f74e + zh: 60d1eae3c79337a0 +/agent-note-interrogating-a-draft-provider-endpoint/problem: + en: c50e44492b4b30a2 + zh: 74a17b3d3ec6cf0d +/agent-note-interrogating-a-draft-provider-endpoint/decision: + en: dc323940d59008f4 + zh: fc94284fcda71542 +/agent-note-interrogating-a-draft-provider-endpoint/decision/why-not-pi-ai-s-own-refresh-machinery: + en: a9654499e32c91b3 + zh: cfb5a76500b6fe1a +/agent-note-interrogating-a-draft-provider-endpoint/alternatives-considered: + en: 3b4b4c33401d862a + zh: bb79062a431576f1 +/agent-note-interrogating-a-draft-provider-endpoint/consequences: + en: a4911a205e713f60 + zh: 04adc6be1f4f34c7 +/agent-note-interrogating-a-draft-provider-endpoint/testing: + en: 40cf0cf6141eba6e + zh: 54a6097cf125b846 diff --git a/.agents/notes/implemented/architecture/2026-08-05-profile-plugin-bundles.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-05-profile-plugin-bundles.i18n.yaml index c58f37c2b3..943fa4e6af 100644 --- a/.agents/notes/implemented/architecture/2026-08-05-profile-plugin-bundles.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-05-profile-plugin-bundles.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-05-profile-plugin-bundles.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-05-profile-plugin-bundles.md -2026-08-05-profile-plugin-bundles.md: 0607f1c9a2414cc16515967b4520da8a325853fd -2026-08-05-profile-plugin-bundles.zh.md: 9d25d3bea6337c472d161c721e44a66dca8470c9 +/agent-note-profile-plugin-bundles-replace-the-fixed-surface-overlays: + en: 178252acff6e206f + zh: 2e5785ca3485f1e7 +/agent-note-profile-plugin-bundles-replace-the-fixed-surface-overlays/problem: + en: 504dd5f06475d707 + zh: 6557fd5649f48944 +/agent-note-profile-plugin-bundles-replace-the-fixed-surface-overlays/decision: + en: 4c58d379cd59d879 + zh: a6b6322fe82d7b6a +/agent-note-profile-plugin-bundles-replace-the-fixed-surface-overlays/alternatives-considered: + en: d906d7a421c6b5c0 + zh: b230cd58c1b7ac79 +/agent-note-profile-plugin-bundles-replace-the-fixed-surface-overlays/consequences: + en: 1aef147a0f31dfaf + zh: f0a8c6cbb9f0506b diff --git a/.agents/notes/implemented/architecture/2026-08-09-client-conversation-node-assembly.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-09-client-conversation-node-assembly.i18n.yaml index 56f2e6e156..171cfb3f1e 100644 --- a/.agents/notes/implemented/architecture/2026-08-09-client-conversation-node-assembly.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-09-client-conversation-node-assembly.i18n.yaml @@ -1,6 +1,94 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-09-client-conversation-node-assembly.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-09-client-conversation-node-assembly.md -2026-08-09-client-conversation-node-assembly.md: c8773b77fe761c3a566e02f0bd6aeb18f26e0a89 -2026-08-09-client-conversation-node-assembly.zh.md: 076ad35178996e01eae26b3909feae8d967414c1 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots: + en: 32abbd757c29e1ee + zh: ea0b9de97fd04196 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/problem: + en: ebdd3ce57ca5b24d + zh: 1aa034b4c3ed515f +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision: + en: af502b4eb9c09d33 + zh: a20cd538e66d3a4b +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/responsibility-layers: + en: 36b54ef989c331af + zh: 58cad4e07a800ba9 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract: + en: 74f17ca7ae05af83 + zh: 591fbc6c98f90262 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract/kind-business-id-and-context-key: + en: 3081736d55350c67 + zh: bfa89f127c16c59f +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract/match-event: + en: 5c97a2a4e91325a7 + zh: d29e52647b699810 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract/conversationmatch: + en: 616c50e24ab990d1 + zh: 2c4a6d129f491046 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract/conversationnodecontext: + en: 7d1ce8db92084e90 + zh: 7b7e6bf3840f6986 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract/start-context-match-reader: + en: 1167bbc860581e33 + zh: 549896c06507ce57 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract/reader-previous-kind: + en: 48e127652f2dab8d + zh: 35f48d4cefc8ce52 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract/update-context-match: + en: 66bd752825ad2c41 + zh: 1cec352eb3d7ab28 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract/publication-match: + en: 43be4c019d79e37a + zh: 54978ef8317e777b +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract/buildlocationdata-context-scope: + en: 8c2b8eab071f5f7b + zh: d3207b1fcfff0a4b +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract/buildviewnode-context-target: + en: c8091375cf986eaa + zh: 0c3226e3f42e51e4 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/overall-conversationnodedefinition-contract/no-generic-end: + en: d5a57346207b0da3 + zh: cb4a4f22ce237c34 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/decision/location-is-a-first-class-engine-fact: + en: c66d870529588ea6 + zh: c9af12feb1e3fae2 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/three-input-window-paths: + en: cc8d60a4ceba6f41 + zh: 552220db9f839429 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/three-input-window-paths/initial-history-tail-and-logical-backward-scanning: + en: a777deacfd73ed3f + zh: 2a9c75dd0aeedcd5 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/three-input-window-paths/prepending-a-newly-loaded-older-page: + en: 3aa4c0a9006b35e8 + zh: 9627f4aaa18c8066 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/three-input-window-paths/forward-live-append: + en: 484172cce965aad7 + zh: 15fffdd32c66cc95 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/three-input-window-paths/consistency-across-replace-prepend-and-append: + en: a9cf356610f46a53 + zh: abc1149bf06b230e +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/how-built-in-businesses-use-definitions: + en: 2a7cae3607dcbc1a + zh: 86f6d8eb7871e253 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/how-built-in-businesses-use-definitions/matching-id-and-state: + en: 130f5db917574545 + zh: 9bf13c96abdc3a4e +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/how-built-in-businesses-use-definitions/chat-node-and-history-live-behavior: + en: 0c52c9ae98f84a86 + zh: d1c7587ad427d8fc +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/view-builder-and-react-identity: + en: ced7ab385e5a81a8 + zh: 5c319ed7ca40e5b8 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/runtime-and-render-path: + en: 114ca8db361d22e5 + zh: 37b6d474e855c187 +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/verification: + en: cf36507c86d1139c + zh: 1fcdd4e2c2cc106b +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/alternatives-considered: + en: e150870d4e2525ed + zh: 34eafb435036af9a +/agent-note-client-conversation-business-node-assembly-and-keyed-chat-snapshots/consequences: + en: 0da343d3b6b29da3 + zh: d7b3774a23be7311 diff --git a/.agents/notes/implemented/architecture/2026-08-10-cancelled-stream-prefix-finalize.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-10-cancelled-stream-prefix-finalize.i18n.yaml index b471d553d6..a592660ac7 100644 --- a/.agents/notes/implemented/architecture/2026-08-10-cancelled-stream-prefix-finalize.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-10-cancelled-stream-prefix-finalize.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-10-cancelled-stream-prefix-finalize.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-10-cancelled-stream-prefix-finalize.md -2026-08-10-cancelled-stream-prefix-finalize.md: 1e6fe59bcc1b323941b69d0e9232f0bcf9e56f53 -2026-08-10-cancelled-stream-prefix-finalize.zh.md: 7aa81f179b80925ef47a8820f8a80c1ef37ec5ea +/agent-note-cancelled-streams-finalize-their-delivered-prefix: + en: d727a01958e5724c + zh: b2d11741f70caf24 +/agent-note-cancelled-streams-finalize-their-delivered-prefix/problem: + en: 142c716d174403a5 + zh: bbb906ca25d7c9f4 +/agent-note-cancelled-streams-finalize-their-delivered-prefix/decision: + en: 28e166977c0dffde + zh: d7c6b175984627fc +/agent-note-cancelled-streams-finalize-their-delivered-prefix/alternatives-considered: + en: ca4363e11e8eff48 + zh: 834152cbe57e1f3e +/agent-note-cancelled-streams-finalize-their-delivered-prefix/consequences: + en: 2d58504acfc4fffe + zh: a6a7ca872c003099 +/agent-note-cancelled-streams-finalize-their-delivered-prefix/testing: + en: 241507aff996c16a + zh: 599eed3162f3ba8d diff --git a/.agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.i18n.yaml index 44a8fbf89f..9ac900a05f 100644 --- a/.agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-10-fork-children-stay-one-shot.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.md -2026-08-10-fork-children-stay-one-shot.md: 0edf6ca9347dcf57313365e570daed22589f69fd -2026-08-10-fork-children-stay-one-shot.zh.md: c2e3504bd21ec6dd6b3feba4ed8abdaec3ee45a4 +/agent-note-forked-children-preserve-the-parent-request-prefix: + en: 5254ea4573dedd96 + zh: ba4ab4517dad0d9f +/agent-note-forked-children-preserve-the-parent-request-prefix/problem: + en: 1fe344c95a0de36d + zh: 656c3e0f1117f64e +/agent-note-forked-children-preserve-the-parent-request-prefix/decision: + en: 7461852090348b34 + zh: ad6c9e0ce65a3e85 +/agent-note-forked-children-preserve-the-parent-request-prefix/alternatives-considered: + en: 80504ffd8331e6c5 + zh: 193261bdde24b4bb +/agent-note-forked-children-preserve-the-parent-request-prefix/consequences: + en: 54c4ce3ee0fee4d2 + zh: 8a63fb3486c76551 +/agent-note-forked-children-preserve-the-parent-request-prefix/consequences/accepted-risks: + en: f634caa9973eaedb + zh: 820291096c8e7352 diff --git a/.agents/notes/implemented/architecture/2026-08-10-host-plane-ownership-after-presets.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-10-host-plane-ownership-after-presets.i18n.yaml index 4cc71b035b..93f0597f19 100644 --- a/.agents/notes/implemented/architecture/2026-08-10-host-plane-ownership-after-presets.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-10-host-plane-ownership-after-presets.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-10-host-plane-ownership-after-presets.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-10-host-plane-ownership-after-presets.md -2026-08-10-host-plane-ownership-after-presets.md: daf48f27c2228b71319d6f5410e6cabe3bc02b39 -2026-08-10-host-plane-ownership-after-presets.zh.md: 56babf5e715584b4ee061a334158d46e59b0d350 +/agent-note-what-stays-host-plane-once-presets-own-the-agent-plane: + en: 4b22d7def09af6eb + zh: 89b43fb2761cb17b +/agent-note-what-stays-host-plane-once-presets-own-the-agent-plane/problem: + en: 5a5d4de7d40ed86b + zh: abfae08f9c291c54 +/agent-note-what-stays-host-plane-once-presets-own-the-agent-plane/decision: + en: 60be2f515ff5f46d + zh: ee8514deadb08260 +/agent-note-what-stays-host-plane-once-presets-own-the-agent-plane/testing: + en: a7b7ca354607dd21 + zh: f88356bfc7dc770e +/agent-note-what-stays-host-plane-once-presets-own-the-agent-plane/alternatives-considered: + en: eac46307265e647d + zh: acfad02f8ca1dc3f +/agent-note-what-stays-host-plane-once-presets-own-the-agent-plane/consequences: + en: d8576d7db9dea547 + zh: 428bb5a7e609d170 diff --git a/.agents/notes/implemented/architecture/2026-08-10-remote-event-delivery.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-10-remote-event-delivery.i18n.yaml index 7606190f02..b0f473168f 100644 --- a/.agents/notes/implemented/architecture/2026-08-10-remote-event-delivery.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-10-remote-event-delivery.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-10-remote-event-delivery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-10-remote-event-delivery.md -2026-08-10-remote-event-delivery.md: 3eaa26fb92c40b3a20cab11d4522bcf68b8a207f -2026-08-10-remote-event-delivery.zh.md: d41589f1b800da98342210d2e429a2b67b6c61f2 +/agent-note-remote-event-delivery-ctx-remote-on: + en: 4b64b9fab76b5185 + zh: 57a11b8a480a49dd +/agent-note-remote-event-delivery-ctx-remote-on/problem: + en: d3016e40cefe047f + zh: 83e83c25a13383e5 +/agent-note-remote-event-delivery-ctx-remote-on/decision: + en: 83f6f48ce1fc517b + zh: abcfcd1c0eb777ea +/agent-note-remote-event-delivery-ctx-remote-on/decision/consumer-contract-dsh-typert-protocol: + en: 8f30b121dd59a3a3 + zh: 92a5e0e63936c393 +/agent-note-remote-event-delivery-ctx-remote-on/decision/the-allowlist-one-declaration-read-by-both-faces: + en: ce8c2e030baf7049 + zh: bb6beb40228e40ae +/agent-note-remote-event-delivery-ctx-remote-on/decision/wire-protocol-api-gateway-remote-mux: + en: 5c89d238a469e79f + zh: d0cf485f0d245e7d +/agent-note-remote-event-delivery-ctx-remote-on/decision/the-apps-web-browser-e2e-belongs-to-the-host-face: + en: a29e07b8013f7f9f + zh: 4f066efa96f2d22f +/agent-note-remote-event-delivery-ctx-remote-on/decision/change-inventory: + en: 49fc44d242a87b69 + zh: 42c4c36296849a88 +/agent-note-remote-event-delivery-ctx-remote-on/alternatives-considered: + en: b75743ab277c1557 + zh: e8e05f41ce1bc2f3 +/agent-note-remote-event-delivery-ctx-remote-on/verification: + en: 4ec0e1c76da8d3b6 + zh: 23de66f8fc659c15 +/agent-note-remote-event-delivery-ctx-remote-on/consequences: + en: c50a0968e3f65df7 + zh: 786f33cf1e95dae4 +/agent-note-remote-event-delivery-ctx-remote-on/related: + en: b64e771dafa6c05b + zh: 4c2f47884f5a2d19 diff --git a/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.i18n.yaml index 9a020189ec..e33e7f556d 100644 --- a/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-10-session-log-version-mechanism.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md -2026-08-10-session-log-version-mechanism.md: 9cb0940f767aa27d5a5106fb78b528c1e3e2695b -2026-08-10-session-log-version-mechanism.zh.md: e1424f24e5dd74b243fe1f0aebceb5d420b9b8c3 +/agent-note-session-log-versioning-one-integer-an-upgrade-chain-and-a-per-event-ignorable-marker: + en: a3c7418dfaa328a8 + zh: e702faa662f821ae +/agent-note-session-log-versioning-one-integer-an-upgrade-chain-and-a-per-event-ignorable-marker/problem: + en: c11f54e24be6cc3b + zh: c1c274fbb161a57b +/agent-note-session-log-versioning-one-integer-an-upgrade-chain-and-a-per-event-ignorable-marker/decision: + en: 084bcb4de484ef32 + zh: 1edf1445913ac7b1 +/agent-note-session-log-versioning-one-integer-an-upgrade-chain-and-a-per-event-ignorable-marker/decision/writer-and-publication-authority: + en: 461eaa03c6a4f441 + zh: 7e5b131326dc702c +/agent-note-session-log-versioning-one-integer-an-upgrade-chain-and-a-per-event-ignorable-marker/consequences: + en: 8ce6dcec183fab88 + zh: a43e9315ad147b15 +/agent-note-session-log-versioning-one-integer-an-upgrade-chain-and-a-per-event-ignorable-marker/alternatives-considered: + en: 2a1580516406ae53 + zh: 7a650804eb520be0 diff --git a/.agents/notes/implemented/architecture/2026-08-13-credential-records-and-authorization-flows.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-13-credential-records-and-authorization-flows.i18n.yaml index b54dd0639b..94fd1f56d0 100644 --- a/.agents/notes/implemented/architecture/2026-08-13-credential-records-and-authorization-flows.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-13-credential-records-and-authorization-flows.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-13-credential-records-and-authorization-flows.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-13-credential-records-and-authorization-flows.md -2026-08-13-credential-records-and-authorization-flows.md: 6bf65761c98689d62935d6e36a040e05c38aa653 -2026-08-13-credential-records-and-authorization-flows.zh.md: 72ec310c2ff0141f83096c805d5ccd60fe5cd57e +/agent-note-credential-records-and-authorization-flows: + en: f624412adde88819 + zh: ac1adbc505394ca2 +/agent-note-credential-records-and-authorization-flows/problem: + en: 7be98011b76b2376 + zh: e01cd9f1039c7875 +/agent-note-credential-records-and-authorization-flows/decision: + en: 57e30c6b56664fee + zh: ab1c7354b47f503e +/agent-note-credential-records-and-authorization-flows/decision/two-mechanisms-the-seams-needed-underneath: + en: e4d5663533e566a2 + zh: 212a1722b78ee727 +/agent-note-credential-records-and-authorization-flows/alternatives-considered: + en: bb484a8d612a43cd + zh: 2a85ba010ed083e1 +/agent-note-credential-records-and-authorization-flows/consequences: + en: ef7c5f6fa346c1d8 + zh: 439b0d8394015f1e +/agent-note-credential-records-and-authorization-flows/testing: + en: 6c8c01f75e6f916b + zh: 7c5c7491f64f2936 diff --git a/.agents/notes/implemented/architecture/2026-08-15-client-shells-and-dynamic-packages.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-15-client-shells-and-dynamic-packages.i18n.yaml index 57e892121c..3afca5571b 100644 --- a/.agents/notes/implemented/architecture/2026-08-15-client-shells-and-dynamic-packages.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-15-client-shells-and-dynamic-packages.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-15-client-shells-and-dynamic-packages.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-15-client-shells-and-dynamic-packages.md -2026-08-15-client-shells-and-dynamic-packages.md: ad2bb26b84253e859e567775eec3b06d73b0003b -2026-08-15-client-shells-and-dynamic-packages.zh.md: 70563962b3c613caa611c61a0c690d2e0e777def +/agent-note-client-shell-layering-and-dynamic-package-boundaries: + en: c8976de4e5547fdd + zh: 3d1bcb3273993af4 +/agent-note-client-shell-layering-and-dynamic-package-boundaries/problem: + en: bd5f38c7aba648dc + zh: 3c28670556b3b34d +/agent-note-client-shell-layering-and-dynamic-package-boundaries/decision: + en: a15c7c13f167e5ac + zh: a15c7c13f167e5ac +/agent-note-client-shell-layering-and-dynamic-package-boundaries/decision/layers-and-build-forms: + en: a1750de2d48551af + zh: ffea0b75c292f186 +/agent-note-client-shell-layering-and-dynamic-package-boundaries/decision/shared-module-requests: + en: cedddcca8a7bae6d + zh: a568a1130229f48c +/agent-note-client-shell-layering-and-dynamic-package-boundaries/decision/parser-preloading-and-react-handoff: + en: 4b503618b271fc28 + zh: e2148f44efa769d2 +/agent-note-client-shell-layering-and-dynamic-package-boundaries/decision/dependency-declarations: + en: 47c332b836c2933b + zh: ed190dbb14b98911 +/agent-note-client-shell-layering-and-dynamic-package-boundaries/alternatives-considered: + en: 2257178f8f474757 + zh: 7da85b5899b91520 +/agent-note-client-shell-layering-and-dynamic-package-boundaries/consequences: + en: c7653b12059aebd7 + zh: a79b63f28d18f8c4 diff --git a/.agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.i18n.yaml index 8a7e75ad27..c0aa66e83f 100644 --- a/.agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-18-experimental-agent-teams-packages.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-18-experimental-agent-teams-packages.md -2026-08-18-experimental-agent-teams-packages.md: 92eba148b328135301b196c9a17e49ee23ddb3f6 -2026-08-18-experimental-agent-teams-packages.zh.md: 6f4d004a78e32e2c27ad65648c446b3cd54c07ad +/agent-note-publish-agent-teams-under-experimental-package-names: + en: 4c772309d60d4ccc + zh: 91bf0acc208e5167 +/agent-note-publish-agent-teams-under-experimental-package-names/problem: + en: e45938d278a6c12d + zh: 93c790d466f7bd12 +/agent-note-publish-agent-teams-under-experimental-package-names/decision: + en: a2555b0c5a6f6f53 + zh: f7082ceb8542b0fb +/agent-note-publish-agent-teams-under-experimental-package-names/alternatives-considered: + en: 869decdfbc7b3466 + zh: b51f5ab731d1a84a +/agent-note-publish-agent-teams-under-experimental-package-names/consequences: + en: f827547f976bf92b + zh: d94e17b8fa2e8304 diff --git a/.agents/notes/implemented/architecture/2026-08-18-session-history-and-event-transport.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-18-session-history-and-event-transport.i18n.yaml index 3b16c5a3d9..478f9b70b4 100644 --- a/.agents/notes/implemented/architecture/2026-08-18-session-history-and-event-transport.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-18-session-history-and-event-transport.i18n.yaml @@ -1,6 +1,58 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-18-session-history-and-event-transport.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-18-session-history-and-event-transport.md -2026-08-18-session-history-and-event-transport.md: db5c403562101bca76c0d39a037a199b2ca164f3 -2026-08-18-session-history-and-event-transport.zh.md: 41ff3ea2dd538edb457e0db3108a900bab220e47 +/agent-note-session-history-control-state-and-remote-event-transport: + en: 79e15a9da0b4053b + zh: fb9719cd520abf7b +/agent-note-session-history-control-state-and-remote-event-transport/problem: + en: b40a730a4cd03535 + zh: 10d5a61824b53443 +/agent-note-session-history-control-state-and-remote-event-transport/decision: + en: bbe86a1833ab5547 + zh: 987a2ade8b4cb909 +/agent-note-session-history-control-state-and-remote-event-transport/decision/connection-generation-and-physical-connections: + en: c4342f89bf96a63b + zh: f8749f02bcfccc4e +/agent-note-session-history-control-state-and-remote-event-transport/decision/general-remote-stream-model: + en: fb2c7bcde3b1672a + zh: a05bd30be07e5413 +/agent-note-session-history-control-state-and-remote-event-transport/decision/general-remote-stream-model/remotestream: + en: d55c2ce88400e448 + zh: 344d510ab946bb9f +/agent-note-session-history-control-state-and-remote-event-transport/decision/general-remote-stream-model/remotesnapshotstream: + en: f2c1d2b00d9554fd + zh: c3e85cf344f7ef24 +/agent-note-session-history-control-state-and-remote-event-transport/decision/general-remote-stream-model/remotejournalstream: + en: d5d0d6a57a4fa581 + zh: 265973b157f957d9 +/agent-note-session-history-control-state-and-remote-event-transport/decision/session-controller: + en: e338ac27490a380f + zh: 12600011ec742e5b +/agent-note-session-history-control-state-and-remote-event-transport/decision/session-controller/activation-policy: + en: 534dcc62a26d305e + zh: 03d64abc0a46bbec +/agent-note-session-history-control-state-and-remote-event-transport/decision/session-controller/session-journal: + en: bb710f8cf35f2028 + zh: aae2cfb8cd848069 +/agent-note-session-history-control-state-and-remote-event-transport/decision/session-controller/session-live-control: + en: a11d627cd68650c3 + zh: 9aff565b9f712853 +/agent-note-session-history-control-state-and-remote-event-transport/decision/workspace-controller: + en: ce0c3fcff169412d + zh: 7076182817358dff +/agent-note-session-history-control-state-and-remote-event-transport/decision/remote-event: + en: c76291bf39999882 + zh: 76f032664fb91ead +/agent-note-session-history-control-state-and-remote-event-transport/decision/api-proxy-s-remaining-boundary: + en: 457408013eb78636 + zh: 126e9d263225d7c4 +/agent-note-session-history-control-state-and-remote-event-transport/alternatives-considered: + en: 22a77c3afd4df0d6 + zh: 661cf8d02d741f1d +/agent-note-session-history-control-state-and-remote-event-transport/verification: + en: 7328f28ba3e32f4c + zh: 2150f20437a473af +/agent-note-session-history-control-state-and-remote-event-transport/consequences: + en: 808ce6d1310876a2 + zh: d9e8fe2aa5cda617 diff --git a/.agents/notes/implemented/architecture/2026-08-19-session-projection-mandatory-seam.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-19-session-projection-mandatory-seam.i18n.yaml index 4830f124d8..24f76c7cb0 100644 --- a/.agents/notes/implemented/architecture/2026-08-19-session-projection-mandatory-seam.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-19-session-projection-mandatory-seam.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-19-session-projection-mandatory-seam.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-19-session-projection-mandatory-seam.md -2026-08-19-session-projection-mandatory-seam.md: e1c6835311228fcaf7a22140f1db8da748603186 -2026-08-19-session-projection-mandatory-seam.zh.md: 5d6a5169a556febae3f5c960b2d519c324d99863 +/agent-note-session-projections-as-a-required-reader-seam: + en: 41f30d473ff53ce2 + zh: 6851c4414f5331c1 +/agent-note-session-projections-as-a-required-reader-seam/problem: + en: c0c779c717cad546 + zh: 5d2916ac86bf5d84 +/agent-note-session-projections-as-a-required-reader-seam/decision: + en: a1c50d2f43334a88 + zh: d7736994733454b4 +/agent-note-session-projections-as-a-required-reader-seam/alternatives-considered: + en: aea3da939c90d240 + zh: 21e91c481cdd23b7 +/agent-note-session-projections-as-a-required-reader-seam/consequences: + en: 73325513ec70fbb2 + zh: 610bf34b9f9db420 diff --git a/.agents/notes/implemented/architecture/2026-08-20-client-session-conversation-ownership.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-20-client-session-conversation-ownership.i18n.yaml index d406110a99..a1044d0181 100644 --- a/.agents/notes/implemented/architecture/2026-08-20-client-session-conversation-ownership.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-20-client-session-conversation-ownership.i18n.yaml @@ -1,6 +1,151 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-20-client-session-conversation-ownership.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-20-client-session-conversation-ownership.md -2026-08-20-client-session-conversation-ownership.md: 0d2f19cff1d4625d678a25c87bcc55fc3f2bfad4 -2026-08-20-client-session-conversation-ownership.zh.md: fdb2420efff88e0a5a33dba79bebf0d072280453 +/agent-note-client-session-conversation-and-ui-ownership-layers: + en: 24e6b5894fbcdc97 + zh: 1fe37f9234be5ff4 +/agent-note-client-session-conversation-and-ui-ownership-layers/problem: + en: 87d3188b6f534c2a + zh: e805eb702d3f0f7f +/agent-note-client-session-conversation-and-ui-ownership-layers/decision: + en: 0db1b673e3486661 + zh: ce9fdf739a211943 +/agent-note-client-session-conversation-and-ui-ownership-layers/layering-principles: + en: 8fa111a6c0477c2c + zh: 89bfc65c4986c521 +/agent-note-client-session-conversation-and-ui-ownership-layers/layering-principles/controllers-are-react-free-logic-owners: + en: 821989170ad76994 + zh: 0ed142bea166fc3a +/agent-note-client-session-conversation-and-ui-ownership-layers/layering-principles/ui-adapters-own-react-integration: + en: 4d032e048364fb97 + zh: 82a435531efdaa78 +/agent-note-client-session-conversation-and-ui-ownership-layers/layering-principles/slot-scopes-and-standard-props-are-separate: + en: b6f585ca87e1fc6f + zh: 53fd58c3e93cf17c +/agent-note-client-session-conversation-and-ui-ownership-layers/package-ownership: + en: 2fc4b50a651b1847 + zh: 7dceeecb9c58e838 +/agent-note-client-session-conversation-and-ui-ownership-layers/overall-data-flow: + en: e7c11e82db080dd4 + zh: 5a8a501a128366d6 +/agent-note-client-session-conversation-and-ui-ownership-layers/session-controller-client: + en: b88f651b1bfb8b5e + zh: b88f651b1bfb8b5e +/agent-note-client-session-conversation-and-ui-ownership-layers/session-controller-client/scope-of-sessionsnapshot: + en: 0abb8da3074137f6 + zh: 92a0074930bb63b6 +/agent-note-client-session-conversation-and-ui-ownership-layers/session-controller-client/three-read-faces: + en: 87f83e04ee6bfe38 + zh: 9bf3548897e80e45 +/agent-note-client-session-conversation-and-ui-ownership-layers/session-controller-client/sessioneventsource: + en: 377ec73183b2e461 + zh: 6f24c1f723d20938 +/agent-note-client-session-conversation-and-ui-ownership-layers/session-controller-client/session-binding-lifecycle: + en: d03dd92afa683183 + zh: b9b7ae5d845bf472 +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-session: + en: 860315b96703371d + zh: 860315b96703371d +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-session/service-responsibilities: + en: d075ba28fd37bff2 + zh: e2d430d1f3e89b15 +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-session/standard-source-registration: + en: e4be6d4b1d79b342 + zh: 7cb0e8c0f6358b50 +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-session/scope-binding: + en: 84c20cce96035340 + zh: d1cc2a2e5f86f86b +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-session/sessionprovider: + en: 5d9bdb1f784f97f2 + zh: a4b3de7a21b84fce +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-session/pending-interactions: + en: 85e358a03ffac4ba + zh: 54b1d5ed6197f2c2 +/agent-note-client-session-conversation-and-ui-ownership-layers/workspace-controller-and-ui-workspace: + en: 45e5f41550e62a3d + zh: d4e6d8f5b397bb51 +/agent-note-client-session-conversation-and-ui-ownership-layers/workspace-controller-and-ui-workspace/scope-of-workspacesnapshot: + en: db0bb2a43bbdbbcc + zh: a064d7ffc42bb4a1 +/agent-note-client-session-conversation-and-ui-ownership-layers/workspace-controller-and-ui-workspace/ui-workspace-composition-responsibilities: + en: cb73b43d8b485bd0 + zh: 134538a67bf6da0d +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-conversation: + en: b23aedfa06639f39 + zh: b23aedfa06639f39 +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-conversation/assembly-core: + en: c004ba2b21b22344 + zh: ae66652c239ec213 +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-conversation/definition-and-view-registries: + en: d35b868d88cff47d + zh: 0e718ca3efdbf224 +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-conversation/conversation-react-adapter: + en: 913a8f9b4f481bff + zh: ca18aa731f15250f +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-conversation/input-and-composer: + en: 0a38e5b9f71f06f9 + zh: 40077352131fae48 +/agent-note-client-session-conversation-and-ui-ownership-layers/chat-and-trajectory-targets: + en: 8ad17fee25bef35f + zh: b5e3d07111cdde7a +/agent-note-client-session-conversation-and-ui-ownership-layers/chat-and-trajectory-targets/chat-owner: + en: 43a4a38d9500ebd4 + zh: 2df24d5530ab11a7 +/agent-note-client-session-conversation-and-ui-ownership-layers/chat-and-trajectory-targets/trajectory-owner: + en: c8d48f4e7ac3a6f2 + zh: a65f680c30f6123c +/agent-note-client-session-conversation-and-ui-ownership-layers/approval-and-question: + en: 45e1a7d1a4f8b73a + zh: 712e01e736199846 +/agent-note-client-session-conversation-and-ui-ownership-layers/approval-and-question/stable-registration: + en: 877881c5ae993245 + zh: 6098103c5414c6e9 +/agent-note-client-session-conversation-and-ui-ownership-layers/approval-and-question/one-waterfall-request: + en: b1ff0285ab378448 + zh: 9acc318381df9cce +/agent-note-client-session-conversation-and-ui-ownership-layers/approval-and-question/one-pending-projection: + en: 4cbfb31b44db8d6e + zh: 110e5067c82bbce3 +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-renderer-and-store: + en: d8de1632a217da9f + zh: 32e68fc042041f42 +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-renderer-and-store/ui-renderer: + en: 928e5816ad6430ea + zh: b3e658f276d4e572 +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-renderer-and-store/store: + en: bf24926000a4fc38 + zh: 702ecdb4aab9dc12 +/agent-note-client-session-conversation-and-ui-ownership-layers/ui-renderer-and-store/registration-and-release-order: + en: 7f9a4b5da9c857a4 + zh: 6e5d5c870fcea214 +/agent-note-client-session-conversation-and-ui-ownership-layers/composition-and-dependency-direction: + en: 6ec1176913cdabab + zh: b0a0c8f443e51d33 +/agent-note-client-session-conversation-and-ui-ownership-layers/developer-guidance: + en: 53c7e08a0e422d7e + zh: 57a1417c0a4d5dd5 +/agent-note-client-session-conversation-and-ui-ownership-layers/developer-guidance/choose-the-data-owner-first: + en: e16f4903a20d477c + zh: bfe217c7d93314ed +/agent-note-client-session-conversation-and-ui-ownership-layers/developer-guidance/add-session-scoped-data: + en: e5e6831f726d1e68 + zh: 1a12311f64b7da5c +/agent-note-client-session-conversation-and-ui-ownership-layers/developer-guidance/add-a-conversation-target: + en: a5ecfa4225fa559b + zh: e1da4db4f80e246b +/agent-note-client-session-conversation-and-ui-ownership-layers/developer-guidance/add-a-pending-interaction-domain: + en: 19985324015f1b4a + zh: 3055d88e1173a2db +/agent-note-client-session-conversation-and-ui-ownership-layers/developer-guidance/review-checks: + en: 2800c6393a75210d + zh: 7bdf8911d3f0bb22 +/agent-note-client-session-conversation-and-ui-ownership-layers/verification: + en: 04c54874beafe7ff + zh: e13dffa5d952069a +/agent-note-client-session-conversation-and-ui-ownership-layers/alternatives-considered: + en: 83dce7fe89397a9f + zh: 8076ebb1d61ba6bf +/agent-note-client-session-conversation-and-ui-ownership-layers/consequences: + en: 307497e3f0eb2158 + zh: c7189a9811edb4a2 diff --git a/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.i18n.yaml index 1d5d4521cf..9de76f79b1 100644 --- a/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-21-deepseek-llm-api-request-extensions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.md -2026-08-21-deepseek-llm-api-request-extensions.md: 7a3609a3f7d8b2aa6edb634643ef234b7e3e8c07 -2026-08-21-deepseek-llm-api-request-extensions.zh.md: 69426df3cc85851e448b98dc51af79555b8cbafc +/agent-note-deepseek-llm-api-request-extensions-for-session-logs-and-plugin-packages: + en: bbb93b705960a21b + zh: 0fc6fc150215f08f +/agent-note-deepseek-llm-api-request-extensions-for-session-logs-and-plugin-packages/problem: + en: 4945ce54f66df55c + zh: 9fbd833c1d8122a7 +/agent-note-deepseek-llm-api-request-extensions-for-session-logs-and-plugin-packages/decision: + en: 2388519a1afaac92 + zh: 6bf758f0560e29a5 +/agent-note-deepseek-llm-api-request-extensions-for-session-logs-and-plugin-packages/incremental-session-log-field: + en: 4e3138fbdd94259b + zh: 8fda801522045b88 +/agent-note-deepseek-llm-api-request-extensions-for-session-logs-and-plugin-packages/plugin-package-field: + en: 0e51b8d8a1bd60fc + zh: dd18fd176c3f101f +/agent-note-deepseek-llm-api-request-extensions-for-session-logs-and-plugin-packages/deferred-inventory-caching: + en: eb69576e756f4aa1 + zh: 5c1923159da3f7a2 +/agent-note-deepseek-llm-api-request-extensions-for-session-logs-and-plugin-packages/verification: + en: 0bda0074b5e11b44 + zh: 4989c1bb840c78ce +/agent-note-deepseek-llm-api-request-extensions-for-session-logs-and-plugin-packages/alternatives-considered: + en: 5faf7699272f99b4 + zh: 7a402e24c80131cf +/agent-note-deepseek-llm-api-request-extensions-for-session-logs-and-plugin-packages/alternatives-considered/why-not-request-relative-message-references: + en: 3f03c2028adf5814 + zh: c50f7f7b0af04655 +/agent-note-deepseek-llm-api-request-extensions-for-session-logs-and-plugin-packages/alternatives-considered/why-not-omit-assistant-chunks-or-overlapping-event-data: + en: b6eff63f49220dcc + zh: 8e4a6c785ed2256a +/agent-note-deepseek-llm-api-request-extensions-for-session-logs-and-plugin-packages/consequences: + en: 144fc01ad3b2b9bd + zh: 0acff935bd7835de diff --git a/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.md b/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.md index 7a3609a3f7..15dc88a3b6 100644 --- a/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.md +++ b/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.md @@ -14,13 +14,13 @@ Both values belong only on the official DeepSeek adapter path. Adding them to `G ## Decision -`@deepseek-ai/dsh-deepseek-llm-api-extensions` registers `ctx.deepseekLlmApiExtensions`, an additive registry of top-level fields for `deepseek-official` request bodies. A contributor claims one declaration-merged field with `register()`. The adapter invokes `prepare()` after serializing the exact wire messages, passes the request cancellation signal, rejects preparation or base-field collision before HTTP, merges the detached fields, and calls the captured `accept()` transaction after HTTP 2xx. The registry stops awaiting preparation after cancellation even if a contributor ignores the signal. Acceptance failures remain request failures under `REQUEST_EXTENSION`; transport and non-2xx failures never accept a contribution. A composition without the registry retains the reusable base adapter. Shipped compositions mount the registry and both contributors: both package metadata and Session-log upload are enabled by default; `session-log-deepseek.enabled: false` disables log upload under the [default-upload decision](2026-09-14-session-log-upload-default.md). Keyless `deepseek-official` replay invokes preparation with a synthetic empty base body and the same acceptance transaction before its first recorded chunk, preserving post-2xx extension side effects rather than field bytes. +`@deepseek-ai/dsh-deepseek-llm-api-extensions` registers `ctx.deepseekLlmApiExtensions`, an additive registry of top-level fields for `deepseek-official` request bodies. A contributor claims one declaration-merged field with `register()`. The adapter invokes `prepare()` after serializing the exact wire messages, passes the request cancellation signal, rejects preparation or base-field collision before HTTP, merges the detached fields, and calls the captured `accept()` transaction after HTTP 2xx. A merged body that fails to serialize is sent without extension fields or acceptance under the [bounded-upload decision](2026-09-24-bounded-session-log-upload.md). The registry stops awaiting preparation after cancellation even if a contributor ignores the signal. Acceptance failures remain request failures under `REQUEST_EXTENSION`; transport and non-2xx failures never accept a contribution. A composition without the registry retains the reusable base adapter. Shipped compositions mount the registry and both contributors: both package metadata and Session-log upload are enabled by default; `session-log-deepseek.enabled: false` disables log upload under the [default-upload decision](2026-09-14-session-log-upload-default.md). Keyless `deepseek-official` replay invokes preparation with a synthetic empty base body and the same acceptance transaction before its first recorded chunk, preserving post-2xx extension side effects rather than field bytes. The provider-neutral `llm` package and `llm-pi-ai` contain no extension type, service lookup, field merge, or acceptance call. ## Incremental session-log field -`@deepseek-ai/dsh-session-log-deepseek` owns the default-on `dsh_session_log` field. When enabled, each request carrying a live Session id sends the contiguous canonical event suffix after the greatest durable `session-log-deepseek/delivery-accepted` watermark for that same Session identity. The field includes the immutable Session header and complete event envelopes. A 2xx appends a new watermark for the transmitted `throughSeq`; that event enters the following request's suffix. Forked logs retain parent watermark ids, so a child starts from sequence zero under its own identity. Concurrent acceptances may arrive out of order, and the maximum watermark remains authoritative. A process-local fold scans each Session event once and incrementally consumes later appends; a new Session object or HMR generation rebuilds the fold from durable history. +`@deepseek-ai/dsh-session-log-deepseek` owns the default-on `dsh_session_log` field. When enabled, each request carrying a live Session id sends the longest contiguous canonical event run after the greatest durable `session-log-deepseek/delivery-accepted` watermark for that same Session identity that fits the `maxBytes` limit of the [bounded-upload decision](2026-09-24-bounded-session-log-upload.md). The field includes the immutable Session header and complete event envelopes. A 2xx appends a new watermark for the transmitted `throughSeq`; that event enters the following request's suffix. Forked logs retain parent watermark ids, so a child starts from sequence zero under its own identity. Concurrent acceptances may arrive out of order, and the maximum watermark remains authoritative. A process-local fold scans each Session event once and incrementally consumes later appends; a new Session object or HMR generation rebuilds the fold from durable history. The failure direction is at least once. A transport or provider rejection records no watermark. A crash after remote acceptance but before the watermark persists causes replay after resume, never a skipped sequence. Existing session checkpoints persist the event; the upload plugin owns no second store. @@ -85,7 +85,7 @@ About 98% of the measured v1 real-session events were `assistant/chunk`. Omittin ## Consequences -Official DeepSeek requests carry active package versions to their resolved `baseURL`, including configured gateways. Unless Session-log upload is disabled, each eligible request also carries the complete newly unaccepted Session suffix. The fields are model-hidden and add no prompt tokens or KV-cache changes, but can substantially increase HTTP body size. Manifest resolution, field collision, acceptance logging, or provider schema rejection fails the model request rather than silently dropping metadata. +Official DeepSeek requests carry active package versions to their resolved `baseURL`, including configured gateways. Unless Session-log upload is disabled, each eligible request also carries newly unaccepted Session events, up to `maxBytes` per request. The fields are model-hidden and add no prompt tokens or KV-cache changes, but can substantially increase HTTP body size. Manifest resolution, field collision, acceptance logging, or provider schema rejection fails the model request rather than silently dropping metadata. A merged body that fails to serialize is the exception: the request proceeds without extension fields and logs a warning. The `delivery-accepted` event becomes part of the canonical log and is itself delivered on a later request. Crash recovery can duplicate a suffix but does not infer acceptance from assistant output or create a second local cursor store. Direct calls without a live Session omit the session field; host package inventory remains available. diff --git a/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.zh.md b/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.zh.md index 69426df3cc..4358e0f86e 100644 --- a/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.zh.md +++ b/.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.zh.md @@ -14,13 +14,13 @@ Status: implemented ## 决策 -`@deepseek-ai/dsh-deepseek-llm-api-extensions` 注册 `ctx.deepseekLlmApiExtensions`,即 `deepseek-official` 请求正文顶层字段的增量注册表。贡献方通过 `register()` 认领一个经声明合并的字段。适配器在序列化确切协议消息后调用 `prepare()`、传入请求取消信号,在 HTTP 前拒绝准备失败或基础字段冲突,合并分离字段,并在 HTTP 2xx 后调用捕获的 `accept()` 事务。即使贡献方忽略信号,注册表也会在取消后停止等待准备。接受失败仍以 `REQUEST_EXTENSION` 使请求失败;传输失败与非 2xx 失败绝不会接受贡献。未挂载注册表的组合会保留可复用基础适配器。随附组合会挂载注册表与两个贡献方:插件包元数据和会话日志上传均默认开启;按[默认上传决策](2026-09-14-session-log-upload-default.zh.md),设置 `session-log-deepseek.enabled: false` 可关闭日志上传。无密钥 `deepseek-official` 回放会使用合成的空基础正文执行准备,并在第一个已记录分片前调用同一接受事务;它保持的是 2xx 后扩展副作用,而非字段字节。 +`@deepseek-ai/dsh-deepseek-llm-api-extensions` 注册 `ctx.deepseekLlmApiExtensions`,即 `deepseek-official` 请求正文顶层字段的增量注册表。贡献方通过 `register()` 认领一个经声明合并的字段。适配器在序列化确切协议消息后调用 `prepare()`、传入请求取消信号,在 HTTP 前拒绝准备失败或基础字段冲突,合并分离字段,并在 HTTP 2xx 后调用捕获的 `accept()` 事务。合并后的正文无法序列化时,按[有上限上传决策](2026-09-24-bounded-session-log-upload.zh.md)不带扩展字段发送,也不执行接受。即使贡献方忽略信号,注册表也会在取消后停止等待准备。接受失败仍以 `REQUEST_EXTENSION` 使请求失败;传输失败与非 2xx 失败绝不会接受贡献。未挂载注册表的组合会保留可复用基础适配器。随附组合会挂载注册表与两个贡献方:插件包元数据和会话日志上传均默认开启;按[默认上传决策](2026-09-14-session-log-upload-default.zh.md),设置 `session-log-deepseek.enabled: false` 可关闭日志上传。无密钥 `deepseek-official` 回放会使用合成的空基础正文执行准备,并在第一个已记录分片前调用同一接受事务;它保持的是 2xx 后扩展副作用,而非字段字节。 提供方无关的 `llm` 包与 `llm-pi-ai` 不包含任何扩展类型、服务查找、字段合并或接受调用。 ## 增量会话日志字段 -`@deepseek-ai/dsh-session-log-deepseek` 拥有默认开启的 `dsh_session_log` 字段。启用后,每个携带存活会话 id 的请求都会发送该确切会话身份最大持久 `session-log-deepseek/delivery-accepted` 水位之后的连续权威事件后缀。该字段包含不可变会话 header 与完整事件信封。2xx 会为已发送的 `throughSeq` 追加新水位;该事件会进入下一次请求的后缀。Fork 日志会保留父级水位 id,因此子会话会在自己的身份下从序列零开始。并发接受可能乱序到达,最大水位仍保持权威。进程内 fold 会让每条会话事件只被扫描一次,并增量消费后续追加;新的会话对象或 HMR generation 会从持久历史重建该 fold。 +`@deepseek-ai/dsh-session-log-deepseek` 拥有默认开启的 `dsh_session_log` 字段。启用后,每个携带存活会话 id 的请求都会发送该确切会话身份最大持久 `session-log-deepseek/delivery-accepted` 水位之后、能放进[有上限上传决策](2026-09-24-bounded-session-log-upload.zh.md)中 `maxBytes` 上限的最长连续权威事件段。该字段包含不可变会话 header 与完整事件信封。2xx 会为已发送的 `throughSeq` 追加新水位;该事件会进入下一次请求的后缀。Fork 日志会保留父级水位 id,因此子会话会在自己的身份下从序列零开始。并发接受可能乱序到达,最大水位仍保持权威。进程内 fold 会让每条会话事件只被扫描一次,并增量消费后续追加;新的会话对象或 HMR generation 会从持久历史重建该 fold。 失败方向为至少一次。传输失败或提供方拒绝不会记录水位。远端接受后、水位持久化前发生崩溃,会在恢复后触发重放,绝不会跳过序列。现有会话检查点会持久化该事件;上传插件不拥有第二份存储。 @@ -85,7 +85,7 @@ Status: implemented ## 后果 -DeepSeek 官方请求会把存活包版本发送到解析后的 `baseURL`,包括已配置 gateway。除非关闭会话日志上传,否则符合条件的请求还会携带完整的未接受会话新后缀。这些字段对模型不可见,不增加提示词 token,也不改变 KV Cache,但可能显著增大 HTTP 正文。Manifest 解析、字段冲突、接受记录或提供方 schema 拒绝会使模型请求失败,而不会静默丢弃元数据。 +DeepSeek 官方请求会把存活包版本发送到解析后的 `baseURL`,包括已配置 gateway。除非关闭会话日志上传,否则符合条件的请求还会携带新的未接受会话事件,每次最多 `maxBytes`。这些字段对模型不可见,不增加提示词 token,也不改变 KV Cache,但可能显著增大 HTTP 正文。Manifest 解析、字段冲突、接受记录或提供方 schema 拒绝会使模型请求失败,而不会静默丢弃元数据。合并后的正文无法序列化是例外:请求不带扩展字段继续发送,并记录一条告警。 `delivery-accepted` 事件会成为权威日志的一部分,并在后续请求中自行交付。崩溃恢复可能重复后缀,但不会根据 assistant 输出推断接受,也不会创建第二份本地游标存储。缺少存活会话的直接调用会省略会话字段;宿主包清单仍然可用。 diff --git a/.agents/notes/implemented/architecture/2026-08-22-single-dsh-application-launcher.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-22-single-dsh-application-launcher.i18n.yaml index 0094a4b396..2390a9244b 100644 --- a/.agents/notes/implemented/architecture/2026-08-22-single-dsh-application-launcher.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-22-single-dsh-application-launcher.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-22-single-dsh-application-launcher.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-22-single-dsh-application-launcher.md -2026-08-22-single-dsh-application-launcher.md: 46a627eed652a0a0edaf7b900510b5d369efcdf0 -2026-08-22-single-dsh-application-launcher.zh.md: b7fa0f2b35c2fbf6c3a28f463b73170c84547a40 +/agent-note-one-dsh-launcher-for-application-profiles: + en: c0b608af89f3a9b4 + zh: 2995eef6243889d5 +/agent-note-one-dsh-launcher-for-application-profiles/problem: + en: 34b82725480cf15b + zh: 83cff42d5a38e64f +/agent-note-one-dsh-launcher-for-application-profiles/decision: + en: a15c7c13f167e5ac + zh: a15c7c13f167e5ac +/agent-note-one-dsh-launcher-for-application-profiles/decision/launch-scope: + en: 9cea027468d5d37c + zh: 359c6cb7842b8b7f +/agent-note-one-dsh-launcher-for-application-profiles/decision/profile-applications: + en: 44028538e06420d3 + zh: 71cf992b7847d822 +/agent-note-one-dsh-launcher-for-application-profiles/decision/typescript-sdk-customization: + en: 8ee88035cf64eeb3 + zh: 6184e50fc4d47348 +/agent-note-one-dsh-launcher-for-application-profiles/decision/python-runtime: + en: e154533170f1cdb6 + zh: 20f8f0d5e111f447 +/agent-note-one-dsh-launcher-for-application-profiles/decision/enforcement: + en: 9ce8d86b65064f38 + zh: 27b8ad426cb319a2 +/agent-note-one-dsh-launcher-for-application-profiles/existing-decisions-and-supersession: + en: 71599a4df773fe78 + zh: d12ae1625d11cc9c +/agent-note-one-dsh-launcher-for-application-profiles/alternatives-considered: + en: 763d9f86e10af3db + zh: e87b35f1f7425da7 +/agent-note-one-dsh-launcher-for-application-profiles/verification: + en: 0b883651974d3ac3 + zh: 8ed0bb3ee97a25f8 +/agent-note-one-dsh-launcher-for-application-profiles/consequences: + en: 8453d34835bf6ada + zh: 86308a497c969b81 diff --git a/.agents/notes/implemented/architecture/2026-08-23-client-derived-tool-presentation.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-23-client-derived-tool-presentation.i18n.yaml index dcadb91f94..d09a4b6a82 100644 --- a/.agents/notes/implemented/architecture/2026-08-23-client-derived-tool-presentation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-23-client-derived-tool-presentation.i18n.yaml @@ -1,6 +1,229 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-23-client-derived-tool-presentation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-23-client-derived-tool-presentation.md -2026-08-23-client-derived-tool-presentation.md: 931276fa6d4c0590746b6c59eeae9f998f05629c -2026-08-23-client-derived-tool-presentation.zh.md: b930f98da17a1cb6ecbf605e3a9f37255ba75fc9 +/agent-note-client-derived-presentation-from-raw-session-tool-events: + en: de8d02e979715600 + zh: 1db4d0364c30a7e3 +/agent-note-client-derived-presentation-from-raw-session-tool-events/problem: + en: 9f34c53e647c69ca + zh: 551776c7cc9618b5 +/agent-note-client-derived-presentation-from-raw-session-tool-events/decision: + en: 5c8de416b8fa0fb1 + zh: 1662926ba8e17405 +/agent-note-client-derived-presentation-from-raw-session-tool-events/decision/goals-and-non-goals: + en: 4ff7b07cb79bc9de + zh: a74ec6e7ebbede0a +/agent-note-client-derived-presentation-from-raw-session-tool-events/terminology: + en: 021106dd41176715 + zh: 131caff7bd37251b +/agent-note-client-derived-presentation-from-raw-session-tool-events/architecture-and-ownership: + en: 5cc496057205b298 + zh: 160158394dfa2df3 +/agent-note-client-derived-presentation-from-raw-session-tool-events/architecture-and-ownership/tool-execution-and-persistence: + en: 675a1da36b918a3b + zh: 88b8d338e9cfcd79 +/agent-note-client-derived-presentation-from-raw-session-tool-events/architecture-and-ownership/host-journal-reads: + en: 36345a3eb5801cdf + zh: 498fd14beaaadd9c +/agent-note-client-derived-presentation-from-raw-session-tool-events/architecture-and-ownership/client-data-and-presentation: + en: 72e14ba086d89e90 + zh: a451a63c3ab9e5d8 +/agent-note-client-derived-presentation-from-raw-session-tool-events/architecture-and-ownership/production-consumer-audit: + en: 5351e75c1e417359 + zh: b14b28c44f723de5 +/agent-note-client-derived-presentation-from-raw-session-tool-events/data-flow: + en: 357a34a2f7796545 + zh: 671b1ef7b2c64cec +/agent-note-client-derived-presentation-from-raw-session-tool-events/data-flow/layer-responsibilities: + en: f6c95424849ed9c8 + zh: 0c7ef9254d9f20c0 +/agent-note-client-derived-presentation-from-raw-session-tool-events/remote-and-durable-data-contracts: + en: 6d865d0eb0c5e003 + zh: 1eb0fb7acfb30975 +/agent-note-client-derived-presentation-from-raw-session-tool-events/remote-and-durable-data-contracts/sessionevententry: + en: 178513914d9c931c + zh: 23b39e82c90a247e +/agent-note-client-derived-presentation-from-raw-session-tool-events/remote-and-durable-data-contracts/durable-log: + en: 6a0aa4dac1cf48d7 + zh: 23753410e5056612 +/agent-note-client-derived-presentation-from-raw-session-tool-events/remote-and-durable-data-contracts/presentationmeta: + en: 51f99cfca9c4c808 + zh: ce95bab241d306f7 +/agent-note-client-derived-presentation-from-raw-session-tool-events/host-design: + en: 16fd2b3e545ede21 + zh: 4d28f52132495441 +/agent-note-client-derived-presentation-from-raw-session-tool-events/host-design/performance-constraints: + en: 102b14e3eb9367ff + zh: d391099dbc41db24 +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-session-and-conversation: + en: 46a772ac51da43a2 + zh: 8709a7e3e6a872f1 +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-session-and-conversation/root-and-ptc-dispatch-subcalls: + en: 2c8ff511a5527a72 + zh: 3eeddc9686ff1709 +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-session-and-conversation/missing-call-head: + en: b9efc339173e546e + zh: c7639861b3b96e83 +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-session-and-conversation/argument-and-metadata-narrowing: + en: 1ec566ca574374c7 + zh: 4bab6b7050a57afa +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-card-model-design: + en: f40f0a8ee8c055c0 + zh: 6957b7372956113c +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-card-model-design/generic-tool-row: + en: 20ff82b092325c5c + zh: 1afd5441a9816117 +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-card-model-design/terminal-card: + en: eab7f366df331b6e + zh: d82499e2a982206f +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-card-model-design/diff-card: + en: ea384415c94f82da + zh: 5f146c6cb534e1db +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-card-model-design/read-card: + en: 0fd9413ae837a36d + zh: 0e421eb162021983 +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-card-model-design/search-card: + en: 5a655646431ad75b + zh: 67cafcbead983495 +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-card-model-design/web-card: + en: bc6415353d231ae0 + zh: a4614630b60d1dc1 +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-card-model-design/renderers-already-using-raw-blocks: + en: b8fc7a1a4dbdd45e + zh: ea97490599b29481 +/agent-note-client-derived-presentation-from-raw-session-tool-events/deliverables: + en: f1769a479af834d4 + zh: 083397eeed5263b8 +/agent-note-client-derived-presentation-from-raw-session-tool-events/fixtures-and-test-data: + en: e5b42aa311079bd7 + zh: ec4cf97037ece7e0 +/agent-note-client-derived-presentation-from-raw-session-tool-events/presentation-equivalence-matrix: + en: 30915c26728eeafe + zh: eea04dea7b4604a5 +/agent-note-client-derived-presentation-from-raw-session-tool-events/client-extension-contract: + en: 96619dfd5ef299cf + zh: 253df98eb42ad75e +/agent-note-client-derived-presentation-from-raw-session-tool-events/failures-and-fallback: + en: 4cca3e16a9f2d13b + zh: 6952abf98801837d +/agent-note-client-derived-presentation-from-raw-session-tool-events/same-named-host-providers: + en: 12b3304157f058ad + zh: 497fa0defe1bd2cd +/agent-note-client-derived-presentation-from-raw-session-tool-events/shipped-scope: + en: 25ddd2f604230fd0 + zh: 7f3b1b5863252635 +/agent-note-client-derived-presentation-from-raw-session-tool-events/shipped-scope/session-controller: + en: 23ff740eb2e5245f + zh: 72c9907849e56656 +/agent-note-client-derived-presentation-from-raw-session-tool-events/shipped-scope/session-controller-client: + en: 57d3babfb1ce3429 + zh: 80284ebf7ad31446 +/agent-note-client-derived-presentation-from-raw-session-tool-events/shipped-scope/ui-conversation-chat-and-trajectory: + en: dafc7a3c08c1823a + zh: 426ef3358597c64a +/agent-note-client-derived-presentation-from-raw-session-tool-events/shipped-scope/ui-tool-and-deliverables: + en: 9e090419d542afe8 + zh: 8e1b743d750bd402 +/agent-note-client-derived-presentation-from-raw-session-tool-events/shipped-scope/fixtures-documentation-and-generated-artifacts: + en: 99f628433b484f98 + zh: 65536e9b4c3dacc4 +/agent-note-client-derived-presentation-from-raw-session-tool-events/verification-matrix: + en: 5fae53c1eaed3f11 + zh: bbce23df01398151 +/agent-note-client-derived-presentation-from-raw-session-tool-events/verification-matrix/host: + en: 0150b57068fef08a + zh: 5fe2e638b0fd1aa8 +/agent-note-client-derived-presentation-from-raw-session-tool-events/verification-matrix/client-conversation: + en: b04bf4f1c89917b5 + zh: 8757c90691c48712 +/agent-note-client-derived-presentation-from-raw-session-tool-events/verification-matrix/client-card-model: + en: 7d57f2e54d287fce + zh: 6b96d4fa8e4a6b0f +/agent-note-client-derived-presentation-from-raw-session-tool-events/verification-matrix/deliverables: + en: 434f4f269d9b0858 + zh: 3eeb8ac42364fb25 +/agent-note-client-derived-presentation-from-raw-session-tool-events/verification-matrix/assembly-and-browser: + en: 5c43e9a729a57a4f + zh: aef26f6ef83f1fe1 +/agent-note-client-derived-presentation-from-raw-session-tool-events/verification-matrix/static-and-documentation: + en: d25ffb1f8f60e04c + zh: 3a105c9669a9b978 +/agent-note-client-derived-presentation-from-raw-session-tool-events/verification-commands: + en: f562776ceda2ac53 + zh: 24c833727dc5c260 +/agent-note-client-derived-presentation-from-raw-session-tool-events/shipped-invariants: + en: 3377510eb7639807 + zh: 1d7cdf2a67cf9bde +/agent-note-client-derived-presentation-from-raw-session-tool-events/alternatives-considered: + en: 6119e2aff3b6be5a + zh: 6119e2aff3b6be5a +/agent-note-client-derived-presentation-from-raw-session-tool-events/alternatives-considered/optimize-only-backscanargs-and-retain-views: + en: a478eeddf0f47cf7 + zh: e9943194d90cf793 +/agent-note-client-derived-presentation-from-raw-session-tool-events/alternatives-considered/add-a-presenter-registry-to-the-client: + en: 96a616a8296de2ad + zh: 988b7f46698aed1c +/agent-note-client-derived-presentation-from-raw-session-tool-events/alternatives-considered/have-the-conversation-tool-definition-produce-one-unified-view: + en: 088a7896e8967523 + zh: da6f8ddaaf2923a7 +/agent-note-client-derived-presentation-from-raw-session-tool-events/alternatives-considered/delete-presentationmeta: + en: 41c11f4e2c14917f + zh: f06d53dbd7170557 +/agent-note-client-derived-presentation-from-raw-session-tool-events/alternatives-considered/persist-canonical-tool-results: + en: a6b1064482cb48c5 + zh: 3fe58419d0aec36d +/agent-note-client-derived-presentation-from-raw-session-tool-events/alternatives-considered/delete-host-presenter-apis: + en: 6bfc4306addf18d4 + zh: f03c6460d4207e83 +/agent-note-client-derived-presentation-from-raw-session-tool-events/alternatives-considered/import-host-tool-implementations-into-the-client: + en: d709f38059905c10 + zh: f216be6b8cb18938 +/agent-note-client-derived-presentation-from-raw-session-tool-events/alternatives-considered/query-presentation-from-the-host-per-result: + en: bc8905288acaa820 + zh: ff551936bd5ea93f +/agent-note-client-derived-presentation-from-raw-session-tool-events/alternatives-considered/allow-presentation-enhancements: + en: fc270977e320fd0a + zh: bb77a11ec6973d03 +/agent-note-client-derived-presentation-from-raw-session-tool-events/alternatives-considered/accept-temporary-generic-degradation: + en: 1a8fd108d32bd199 + zh: 5cd1c7adf3fe824d +/agent-note-client-derived-presentation-from-raw-session-tool-events/consequences: + en: fc74ce3d77d3f6f1 + zh: 5bf52b18d86ea925 +/agent-note-client-derived-presentation-from-raw-session-tool-events/consequences/client-and-host-logic-drift: + en: 9314413ed5b41d10 + zh: 0cca0d80eb421b9c +/agent-note-client-derived-presentation-from-raw-session-tool-events/consequences/same-named-providers-lack-stable-identity: + en: 81e3e790bb32e2b2 + zh: 2b0f0194ee22e414 +/agent-note-client-derived-presentation-from-raw-session-tool-events/consequences/metadata-is-unknown-json: + en: 631d7726c1bfb908 + zh: 52e58e2e0aae1610 +/agent-note-client-derived-presentation-from-raw-session-tool-events/consequences/preset-owned-projection-availability: + en: c12c5a464eefe88a + zh: d184c0cefbbabfee +/agent-note-client-derived-presentation-from-raw-session-tool-events/consequences/two-targets-must-stay-synchronized: + en: 9ee330e015d9b569 + zh: 11d50bce62b91298 +/agent-note-client-derived-presentation-from-raw-session-tool-events/consequences/deliverables-has-a-hidden-dependency: + en: c9f4fc5ce7c0e6cc + zh: bb1b73b7313112e2 +/agent-note-client-derived-presentation-from-raw-session-tool-events/consequences/fixtures-can-create-false-confidence: + en: 5f21119c0a360eaa + zh: f656f35d802ec74a +/agent-note-client-derived-presentation-from-raw-session-tool-events/consequences/incorrectly-refreshing-snapshots: + en: aeab59c94afe3c5f + zh: 77378f5aa76e9056 +/agent-note-client-derived-presentation-from-raw-session-tool-events/consequences/documentation-drift: + en: 4c724d879b27bd5d + zh: 63b58c6ab26d7934 +/agent-note-client-derived-presentation-from-raw-session-tool-events/consequences/remote-protocol-narrowing: + en: d7e581086940fafa + zh: d452320fee6ef875 +/agent-note-client-derived-presentation-from-raw-session-tool-events/relationship-to-existing-decisions: + en: f7501cfad1c94062 + zh: 2574582ee86c3c4a +/agent-note-client-derived-presentation-from-raw-session-tool-events/deferred: + en: dcd92bc33fbb1885 + zh: 3d1ea8a6b3f3f3a7 diff --git a/.agents/notes/implemented/architecture/2026-08-23-locale-owned-client-ui-copy.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-23-locale-owned-client-ui-copy.i18n.yaml index 1aa080d1fe..49f6adf176 100644 --- a/.agents/notes/implemented/architecture/2026-08-23-locale-owned-client-ui-copy.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-23-locale-owned-client-ui-copy.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-23-locale-owned-client-ui-copy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-23-locale-owned-client-ui-copy.md -2026-08-23-locale-owned-client-ui-copy.md: bc4d8efbce1f246f712e3afe6af40d1518e8cb17 -2026-08-23-locale-owned-client-ui-copy.zh.md: ce996a4aafc392e739bec2eccd8714cfeff7d8e9 +/agent-note-locale-owned-client-ui-copy: + en: 048ebc19d489b40d + zh: 681d1c4167f0101f +/agent-note-locale-owned-client-ui-copy/problem: + en: b007d31d9998b878 + zh: 857921e0d57288f9 +/agent-note-locale-owned-client-ui-copy/decision: + en: 8a5e0abec93fcb91 + zh: bf9fe95e48fc7eb6 +/agent-note-locale-owned-client-ui-copy/verification: + en: bc9daa07456e8496 + zh: 9edeae0d970cc6b2 +/agent-note-locale-owned-client-ui-copy/alternatives-considered: + en: b04fd6aaa9b4fff5 + zh: 7551d86cad9a862a +/agent-note-locale-owned-client-ui-copy/consequences: + en: fd435e249b7409e1 + zh: e0b147cfcb565516 diff --git a/.agents/notes/implemented/architecture/2026-08-24-browser-token-authentication.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-24-browser-token-authentication.i18n.yaml index af52bdcb23..a67b37efe1 100644 --- a/.agents/notes/implemented/architecture/2026-08-24-browser-token-authentication.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-24-browser-token-authentication.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-24-browser-token-authentication.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-24-browser-token-authentication.md -2026-08-24-browser-token-authentication.md: 47d6afe1bf4cd8169eb4e8ec92a30bf0fee32c8a -2026-08-24-browser-token-authentication.zh.md: 13ecf55e41c7bb1455177bdd6a87a3a83d94ca6f +/agent-note-browser-launch-token-authentication: + en: 7ab4daa548c2b5a7 + zh: 33a76129efc2079a +/agent-note-browser-launch-token-authentication/problem: + en: 01293500639c9d79 + zh: 6d19e4843955c811 +/agent-note-browser-launch-token-authentication/decision: + en: 063f9698b8a94287 + zh: 848b2c1134b7a100 +/agent-note-browser-launch-token-authentication/verification: + en: 189b36d0fc5f3a17 + zh: 08993cb585204fc0 +/agent-note-browser-launch-token-authentication/alternatives-considered: + en: 5275c87f19fe6eee + zh: ccb922367c4bb3e2 +/agent-note-browser-launch-token-authentication/consequences: + en: 0714a8a7cc74918a + zh: 0f3878b09463ab2e diff --git a/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.i18n.yaml index 6a9b597434..7dc21e59f4 100644 --- a/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.i18n.yaml @@ -1,6 +1,46 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-25-electron-desktop-packaging-and-updates.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.md -2026-08-25-electron-desktop-packaging-and-updates.md: a985e1c91a1ccdb9c4aab0bc519974f9b6fafd4a -2026-08-25-electron-desktop-packaging-and-updates.zh.md: 17ace865477d4fae3650b56d6725be07c7bd0e0f +/agent-note-package-and-update-the-electron-desktop-application: + en: eb6e843bc5a11195 + zh: b245e9a3615e01f0 +/agent-note-package-and-update-the-electron-desktop-application/problem: + en: 5a39322836f06cd9 + zh: 7a7ab48fe38a5788 +/agent-note-package-and-update-the-electron-desktop-application/decision: + en: bd6d1e19da0d5a87 + zh: f194ae90331a27ea +/agent-note-package-and-update-the-electron-desktop-application/ownership: + en: 50e16f318c5d0e1a + zh: 84b2ba8f1a6932b0 +/agent-note-package-and-update-the-electron-desktop-application/filesystem-layout: + en: 4990a8ba137e28f0 + zh: b12f68d30a5d18fa +/agent-note-package-and-update-the-electron-desktop-application/installation-and-resolution: + en: 29def175ab33b7d6 + zh: 87e55ec28c20c7c1 +/agent-note-package-and-update-the-electron-desktop-application/updates-and-recovery: + en: 9c9e8a54a11bec8b + zh: 305cf1f6ed374d0b +/agent-note-package-and-update-the-electron-desktop-application/security-and-release-policy: + en: 4fb110927a3ed7a9 + zh: 5a263577f097490a +/agent-note-package-and-update-the-electron-desktop-application/implementation: + en: 041a6d35ed61b149 + zh: 617c6b90a6f4fa4d +/agent-note-package-and-update-the-electron-desktop-application/alternatives-considered: + en: 10b1b0a8afe38def + zh: 0a4df988f72b8d11 +/agent-note-package-and-update-the-electron-desktop-application/consequences: + en: 44dc044cfcd6ec17 + zh: 5e978dec54783b4e +/agent-note-package-and-update-the-electron-desktop-application/review-decisions: + en: 54c4c2a4bcdfa834 + zh: c280351bb3bf085f +/agent-note-package-and-update-the-electron-desktop-application/risks: + en: af59c819ae700ee1 + zh: 6c0b4b80690fc6a2 +/agent-note-package-and-update-the-electron-desktop-application/related-proposals: + en: b6c0cbd39966f1ec + zh: 5c7a919abec643ba diff --git a/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.i18n.yaml index f53d8aec09..bd2626e850 100644 --- a/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.i18n.yaml @@ -1,6 +1,58 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-25-session-observations-and-projection-owned-client-state.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.md -2026-08-25-session-observations-and-projection-owned-client-state.md: 8573ea89fae6f52a9d28cc75261aea529df4f075 -2026-08-25-session-observations-and-projection-owned-client-state.zh.md: 55c477e994df72ef8f6b6e4bb97b8b35e5783c9b +/agent-note-session-observations-and-projection-owned-client-state: + en: 00b84161c373744e + zh: 7243e7f32ae1fa3f +/agent-note-session-observations-and-projection-owned-client-state/problem: + en: af1f72affe6ae77e + zh: 3d76b6310bc572b1 +/agent-note-session-observations-and-projection-owned-client-state/decision: + en: 00e13f9c63b7820a + zh: b043556c3b8d9f50 +/agent-note-session-observations-and-projection-owned-client-state/decision/data-flow: + en: 480284ae1a6ce210 + zh: d42c72ada9f019f8 +/agent-note-session-observations-and-projection-owned-client-state/decision/observation-is-the-point-read-unit: + en: fac92f8547482a49 + zh: 60240c47fbe4611f +/agent-note-session-observations-and-projection-owned-client-state/decision/source-resolution-and-lifetime: + en: e550ae9892474276 + zh: fb6a2d9e91ebd4d9 +/agent-note-session-observations-and-projection-owned-client-state/decision/projection-execution-boundary: + en: 148de86941b90f41 + zh: c065a8e96e28b9d7 +/agent-note-session-observations-and-projection-owned-client-state/decision/read-audiences: + en: 888f62659f4d868d + zh: e74491e8c85046ee +/agent-note-session-observations-and-projection-owned-client-state/decision/replayable-client-facts-are-projection-owned: + en: efded09f0cd30a8e + zh: 5e16580a39ff3359 +/agent-note-session-observations-and-projection-owned-client-state/decision/client-merge-rules: + en: fb8740be674e4708 + zh: 7dc0c89558f51792 +/agent-note-session-observations-and-projection-owned-client-state/decision/domain-applications: + en: 4dcae9e00148b11e + zh: acfd1b6831cf50fe +/agent-note-session-observations-and-projection-owned-client-state/decision/failure-and-readiness-boundaries: + en: 0f90a8bccedf9e71 + zh: 8452dfdf0af00fb3 +/agent-note-session-observations-and-projection-owned-client-state/decision/ownership-matrix: + en: 4f25ea5ac5b18fb3 + zh: 30af4b15936fc455 +/agent-note-session-observations-and-projection-owned-client-state/decision/extension-rules: + en: 110ca8005f618ad1 + zh: 8f3e83d59334b278 +/agent-note-session-observations-and-projection-owned-client-state/decision/relationship-to-existing-decisions: + en: 8d699dfc22ab5c5f + zh: 8dcd9fc6bd1594db +/agent-note-session-observations-and-projection-owned-client-state/verification: + en: df17217023668428 + zh: 88f7da4deffc6bf9 +/agent-note-session-observations-and-projection-owned-client-state/alternatives-considered: + en: a25138b4298cda16 + zh: 92799a9bd8867d47 +/agent-note-session-observations-and-projection-owned-client-state/consequences: + en: e1f8bd8fa68de603 + zh: 5afcd06f2611bc1e diff --git a/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.md b/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.md index 8573ea89fa..523122c9ae 100644 --- a/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.md +++ b/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.md @@ -25,8 +25,7 @@ flowchart LR List["list / search"] --> Corpus["SessionQuery corpus"] Follow["follow"] --> Observe["observeSession"] Page["page / attachment / fork"] --> Observe - Subagent["subagent list / continuation"] --> Corpus - Subagent --> Observe + Subagent["subagent list / continuation"] --> Observe Corpus --> Cache["projection cache hints"] Cache --> ClientList["Client Session list"] Cache -->|"small miss"| Observe @@ -71,7 +70,7 @@ The registry owns fold state; each domain owns its `init`, `apply`, `view`, sche `view` remains an uncached synchronous conversion over folded state. Its cost is bounded by the registered projection units and is paid at snapshot publication; introducing a second cache would add invalidation states without reducing event replay. -Corpus listing remains a separate lightweight operation. `listSessions()` returns live-preferred headers without materializing every log. Session list and subagent list first use live projection state or durable projection-cache rows. Session list may take one complete observation for an individually stored artifact within its configured small-log limit when cached metadata cannot establish whether it is blank; a large or unreadable cache miss remains visible with unknown hints. +Corpus listing remains a separate lightweight operation. `listSessions()` returns live-preferred headers without materializing every log. Session list first uses live projection state or durable projection-cache rows. Subagent discovery reads parent-catalog projections through exact observations. Session list may take one complete observation for an individually stored artifact within its configured small-log limit when cached metadata cannot establish whether it is blank; a large or unreadable cache miss remains visible with unknown hints. `session.follow` publishes a required opening snapshot containing header, cursor, the initial event window, and a complete projection baseline. Reconnect replaces the previous generation from another complete snapshot. `session.page` is reserved for older-history reads and gap repair. Observation-only reads never activate an Agent; only an ordinary follow may retain its prepared observation and request promotion after the opening snapshot has been delivered. @@ -86,7 +85,7 @@ Each public operation chooses one query and projection policy. The choice is par | `session.follow` | One exact observation | All, carried in the opening snapshot | Ordinary cold Session only, after snapshot delivery | | `session.page` | One exact observation | None, except projection-backed subagent authorization | Never | | Attachment and fork source | One exact observation | None unless authorization requires it | Never for the source | -| Subagent list and continuation | Corpus plus live/cache/observation resolution | All on a cold fallback; audience consumes identity or inherited values | Never for listing; continuation follows its explicit command semantics | +| Subagent list and continuation | Parent-catalog observations for listing; target observations for continuation | All; listing consumes catalog values, continuation consumes identity and inherited values | Never for listing; continuation follows its explicit command semantics | ### Replayable Client facts are projection-owned @@ -123,7 +122,7 @@ Client-local interaction state also remains local: loading and error status, an - **Title and list metadata.** Cached projection hints may render an existing title and determine blankness or recency. Missing hints leave those facts unknown; only the bounded small-log policy may resolve them during listing. The Client reconciles list rows with the current metadata projection: nonblank evidence excludes a Session from blank reuse, and the later prompt timestamp supplies recency. Projection stores outlive lazy Client Session instances, so instantiation reads retained metadata even before a list row is available. A stale list response cannot override a newer history or control projection. - **Model selection.** `model/selection` records a complete provider, model, and optional reasoning effort. `modelSelection` distinguishes the last request's route from a later selection pending consumption by a request header. - **Agent preset.** The projection initializes from immutable Session metadata and advances on preset-selection events. A missing or `null` value is not replaced with the deployment default for an existing Session. -- **Subagent identity.** The `subagent` unit remains the sole descriptor interpreter. Listing obtains candidates from the shared corpus and resolves values through live state, projection cache, or an observation rather than scanning events itself. +- **Subagent identity.** The `subagent` unit remains the sole descriptor interpreter for continuation and history authorization. Listing derives membership, mode, and label from the `subagentCatalog` projection through parent observations; descendant discovery recursively reads reachable catalogs ([parent-catalog decision](2026-09-01-parent-owned-subagent-catalog.md)). - **Subagent presentation.** Opening projection values establish timing and identity before the Client declares the child interactive or offline, so transport loading does not masquerade as a durable state. These migrations remove special-case Client state without making projection own provider catalogs or interaction mechanics. A domain still owns mutations and commands; projection owns only their replayable Session result. @@ -167,14 +166,14 @@ These rules apply to new Session-derived Client state even when a direct event s - [Reusable Session preparation](../../archived/architecture/2026-08-05-session-preparation.md) owns cold materialization, repair, reservation, and publication. Observation adds a shared read lease over that prepared object; it does not move preparation into SessionQuery. - [Session history and Remote event transport](2026-08-18-session-history-and-event-transport.md) owns stream generations and replacement semantics. This decision supplies the exact snapshot that opens each journal generation. - [Projection state and Client views](../../archived/architecture/2026-08-19-session-projection-state-and-client-views.md) owns the distinction between Host fold state and Client values. This decision governs where those values are consumed and how partial list hints differ from a complete baseline. -- [Subagent identity projection](../../archived/architecture/2026-08-06-subagent-list-identity-projection.md) continues to own descriptor folding, the serializable `null` sentinel, and the own-suffix sequence check. This decision supersedes only its independent corpus merge and direct cold-inspection path: listing now uses SessionQuery's corpus and observation. +- [The parent-catalog decision](2026-09-01-parent-owned-subagent-catalog.md) owns subagent discovery. Descriptor folding, the serializable `null` sentinel, and the own-suffix sequence check remain relevant to continuation and history authorization, not catalog identity. - The broader [session projection and command-log proposal](../../proposed/architecture/2026-07-27-session-projection-and-command-log.md) remains proposed for the portions not represented by shipped code. This decision records the shipped observation and Client-ownership subset. ## Verification Persistence and SessionQuery tests pin shared cold loading, cancellation, live-source races, retained observations, disposal, and all-or-none projection calculation. Session Controller and Gateway tests pin snapshot-first opening, replacement reconnect, older-page reads, gap repair, list-cache hints, bounded small-log fallback, and promotion after snapshot delivery. -Client tests pin higher-sequence-wins projection storage, title updates, model catalog and selection readiness, preset roster refresh and Session-specific selection, and subagent loading without transient offline presentation. Subagent tests pin corpus enumeration, cache and observation fallback, lifecycle witnesses, bounded cold reads, and no Agent activation during listing. +Client tests pin higher-sequence-wins projection storage, title updates, model catalog and selection readiness, preset roster refresh and Session-specific selection, and subagent loading without transient offline presentation. Subagent tests pin parent-catalog order, recursive traversal, branch diagnostics, cancellation, fork isolation, and no Agent activation during listing. ## Alternatives considered diff --git a/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.zh.md b/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.zh.md index 55c477e994..6639047731 100644 --- a/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.zh.md +++ b/.agents/notes/implemented/architecture/2026-08-25-session-observations-and-projection-owned-client-state.zh.md @@ -25,8 +25,7 @@ flowchart LR List["list / search"] --> Corpus["SessionQuery corpus"] Follow["follow"] --> Observe["observeSession"] Page["page / attachment / fork"] --> Observe - Subagent["subagent list / continuation"] --> Corpus - Subagent --> Observe + Subagent["subagent list / continuation"] --> Observe Corpus --> Cache["projection cache hints"] Cache --> ClientList["Client Session list"] Cache -->|"small miss"| Observe @@ -71,7 +70,7 @@ Registry 拥有 fold state;各领域拥有自己的 `init`、`apply`、`view` `view` 保持为 folded state 上无 cache 的同步转换。其成本由已注册 projection unit 数量界定,并在 snapshot 发布时支付;引入第二层 cache 只会增加 invalidation 状态,无法减少 event replay。 -语料库 list 仍是独立的轻量操作。`listSessions()` 返回 live-preferred header,而不物化每份日志。Session list 与 subagent list 先读取 live projection 状态或持久 projection-cache row。当 cache 无法判断 Session 是否为空,且该 Session 拥有的独立产物未超过配置的小日志限制时,Session list 可以执行一次完整 observation;大型或不可读的 cache miss 仍以 hints 未知但 row 可见的方式返回。 +语料库 list 仍是独立的轻量操作。`listSessions()` 返回 live-preferred header,而不物化每份日志。Session list 先读取 live projection 状态或持久 projection-cache row。Subagent 发现通过精确 observation 读取父目录 projection。当 cache 无法判断 Session 是否为空,且该 Session 拥有的独立产物未超过配置的小日志限制时,Session list 可以执行一次完整 observation;大型或不可读的 cache miss 仍以 hints 未知但 row 可见的方式返回。 `session.follow` 发布必需的 opening snapshot,其中包含 header、cursor、首个事件窗口和完整 projection baseline。重连使用另一份完整 snapshot 替换上一 generation。`session.page` 仅用于旧历史读取与 gap repair。只读 observation 不激活 Agent;只有普通 follow 可以保留 prepared observation,并在 opening snapshot 已交付后请求 promotion。 @@ -86,7 +85,7 @@ Registry 拥有 fold state;各领域拥有自己的 `init`、`apply`、`view` | `session.follow` | 一份精确 observation | 全算,并由 opening snapshot 携带 | 仅普通 cold Session,且在 snapshot 交付后 | | `session.page` | 一份精确 observation | 不计算,但 projection-backed subagent 鉴权除外 | 从不 | | Attachment 与 fork source | 一份精确 observation | 鉴权不要求时不计算 | source 从不激活 | -| Subagent list 与 continuation | Corpus 加 live/cache/observation 解析 | cold fallback 全算;audience 只消费 identity 或继承值 | Listing 从不;continuation 遵循显式命令语义 | +| Subagent list 与 continuation | Listing 观察父目录;continuation 观察目标 | 全算;listing 消费目录值,continuation 消费身份与继承值 | Listing 从不;continuation 遵循显式命令语义 | ### 可回放的 Client 事实归 projection 所有 @@ -123,7 +122,7 @@ Client 本地交互状态也继续留在本地:loading 和 error 状态、打 - **Title 与 list metadata。** Cached projection hints 可以渲染已有 title,并判断 blankness 或 recency。Hints 缺失时这些事实保持未知;listing 期间只有有界小日志策略可以解析它们。Client 使用当前 metadata projection 对账列表行:非空白事实会将 Session 排除在空白复用之外,较晚的 prompt 时间用于最近活动排序。Projection store 的生命周期长于惰性创建的 Client Session 实例,因此实例化时即使尚无列表行,也会读取已保留的元数据。过期列表响应不能覆盖较新的 history 或 control projection。 - **Model selection。** `model/selection` 记录完整 provider、model 和可选 reasoning effort。`modelSelection` 区分上一请求使用的 route,以及等待 request header 消费的较晚 selection。 - **Agent preset。** Projection 从不可变 Session metadata 初始化,并随 preset-selection event 推进。对于现有 Session,缺失或 `null` 值不会替换成部署默认值。 -- **Subagent identity。** `subagent` unit 仍是唯一 descriptor interpreter。Listing 从共享 corpus 获得 candidate,并通过 live state、projection cache 或 observation 解析值,不自行扫描 event。 +- **Subagent identity。** `subagent` unit 仍是继续执行与历史授权的唯一 descriptor interpreter。Listing 通过父级 observation 从 `subagentCatalog` projection 派生成员关系、模式与标签;后代发现递归读取可达目录([父目录决策](2026-09-01-parent-owned-subagent-catalog.zh.md))。 - **Subagent presentation。** Opening projection value 在 Client 宣布 child 可交互或离线前建立 timing 与 identity,因此 transport loading 不会伪装成 durable state。 这些迁移删除特殊 Client state,但不会让 projection 接管 provider catalog 或交互机制。领域仍拥有 mutation 和 command;projection 只拥有其可回放 Session 结果。 @@ -167,14 +166,14 @@ Client 本地交互状态也继续留在本地:loading 和 error 状态、打 - [可复用 Session preparation](../../archived/architecture/2026-08-05-session-preparation.md)拥有冷物化、修复、reservation 和发布。Observation 在该 prepared object 之上增加共享读取 lease,并未把 preparation 移入 SessionQuery。 - [Session 历史与 Remote event transport](2026-08-18-session-history-and-event-transport.zh.md)拥有 stream generation 与 replacement 语义。本决策提供每个日志 generation 的精确 opening snapshot。 - [Projection state 与 Client view](../../archived/architecture/2026-08-19-session-projection-state-and-client-views.md)拥有 Host fold state 和 Client value 的区分。本决策规定这些值在哪里消费,以及部分 list hints 与完整 baseline 的差别。 -- [Subagent identity projection](../../archived/architecture/2026-08-06-subagent-list-identity-projection.md)继续拥有 descriptor folding、可序列化 `null` sentinel 和 own-suffix sequence 检查。本决策只取代其中独立 corpus merge 和直接 cold inspection 路径:listing 改为使用 SessionQuery corpus 和 observation。 +- [父目录决策](2026-09-01-parent-owned-subagent-catalog.zh.md)拥有 subagent 发现机制。Descriptor folding、可序列化 `null` sentinel 和 own-suffix sequence 检查仍用于继续执行与历史授权,不用于目录身份。 - 更广泛的 [session projection 与 command-log 提案](../../proposed/architecture/2026-07-27-session-projection-and-command-log.zh.md)仍为 proposed,其中尚未由已交付代码体现的部分不受影响。本决策记录已经交付的 observation 与 Client ownership 子集。 ## 验证 Persistence 与 SessionQuery 测试固定共享冷加载、取消、live-source race、retained observation、dispose 和 all-or-none projection 计算。Session Controller 与 Gateway 测试固定 snapshot-first opening、replacement reconnect、旧分页读取、gap repair、list-cache hints、小日志有界 fallback,以及 snapshot 交付后的 promotion。 -Client 测试固定 higher-sequence-wins projection store、title 更新、model catalog 与 selection readiness、preset roster refresh 与 Session 专属选择,以及不会短暂展示离线状态的 subagent loading。Subagent 测试固定 corpus 枚举、cache 与 observation fallback、lifecycle witness、有界冷读,以及 listing 期间不激活 Agent。 +Client 测试固定 higher-sequence-wins projection store、title 更新、model catalog 与 selection readiness、preset roster refresh 与 Session 专属选择,以及不会短暂展示离线状态的 subagent loading。Subagent 测试固定父目录顺序、递归遍历、分支诊断、取消、fork 隔离,以及 listing 期间不激活 Agent。 ## 考虑过的替代方案 diff --git a/.agents/notes/implemented/architecture/2026-08-27-adjacent-agent-steer-messaging.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-27-adjacent-agent-steer-messaging.i18n.yaml index bc7d37ce4c..231ee0bf64 100644 --- a/.agents/notes/implemented/architecture/2026-08-27-adjacent-agent-steer-messaging.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-27-adjacent-agent-steer-messaging.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-27-adjacent-agent-steer-messaging.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-27-adjacent-agent-steer-messaging.md -2026-08-27-adjacent-agent-steer-messaging.md: 47d9bd05c24871a14f78ebfa0afb8c13a6c2754d -2026-08-27-adjacent-agent-steer-messaging.zh.md: 1fd0fc39b937287ac34a2862c7cb9cde90256c09 +/agent-note-adjacent-agents-share-one-steer-send-message-operation: + en: 758d31ae04ce0d4f + zh: 112475efbd52b9f6 +/agent-note-adjacent-agents-share-one-steer-send-message-operation/problem: + en: c988b8a3be4e6f19 + zh: b58011fd8d2e878e +/agent-note-adjacent-agents-share-one-steer-send-message-operation/decision: + en: 1188c699ce6e6ca2 + zh: 4d5b974cd1216f06 +/agent-note-adjacent-agents-share-one-steer-send-message-operation/decision/one-model-tool-and-one-return-instruction: + en: 8a4be155a4984ca8 + zh: 00c2a61da2443530 +/agent-note-adjacent-agents-share-one-steer-send-message-operation/decision/complete-removal-and-reintroduction-condition: + en: 5a9ec6478cf7430c + zh: f4c2f067cc72040e +/agent-note-adjacent-agents-share-one-steer-send-message-operation/alternatives-considered: + en: 1f62d5d938144666 + zh: dec0f30228c5b7a7 +/agent-note-adjacent-agents-share-one-steer-send-message-operation/consequences: + en: 6a01449bef67c9ab + zh: 9ed7184a4d48038c diff --git a/.agents/notes/implemented/architecture/2026-08-27-handle-based-session-persistence.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-27-handle-based-session-persistence.i18n.yaml index 0521855ea8..29242480fe 100644 --- a/.agents/notes/implemented/architecture/2026-08-27-handle-based-session-persistence.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-27-handle-based-session-persistence.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-27-handle-based-session-persistence.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-27-handle-based-session-persistence.md -2026-08-27-handle-based-session-persistence.md: e2f07856b7ef8ffd8180ed7ff515210c95dde29b -2026-08-27-handle-based-session-persistence.zh.md: 472a1024887ecca67245de27f52c68ec0b34caa1 +/agent-note-handle-based-session-persistence: + en: ca49a1cfae00a590 + zh: f1fe21b5dbaf0d68 +/agent-note-handle-based-session-persistence/problem: + en: e4a62db37d44cc11 + zh: 860058651d2817de +/agent-note-handle-based-session-persistence/decision: + en: 52184217a0939497 + zh: 404783efc001e6cc +/agent-note-handle-based-session-persistence/alternatives-considered: + en: f3f7a3abe905c97d + zh: 28018bc45290a455 +/agent-note-handle-based-session-persistence/consequences: + en: 5917a573cbdc5fa4 + zh: 3c3769070539a0a9 +/agent-note-handle-based-session-persistence/related: + en: 07a1b7d5a0f9b0f7 + zh: 9bfa134b62ff3df7 diff --git a/.agents/notes/implemented/architecture/2026-08-27-outbound-proxy-policy.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-27-outbound-proxy-policy.i18n.yaml index 0f7fcde21b..0d30f02d4f 100644 --- a/.agents/notes/implemented/architecture/2026-08-27-outbound-proxy-policy.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-27-outbound-proxy-policy.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-27-outbound-proxy-policy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-27-outbound-proxy-policy.md -2026-08-27-outbound-proxy-policy.md: e588ff751fd18762fbe5e24aa17f9bbbc4ff8deb -2026-08-27-outbound-proxy-policy.zh.md: 57faea256120f5f76ecc4dab1bd8709003672fd0 +/agent-note-one-outbound-proxy-policy-installed-before-anything-can-request: + en: b19652a0e1cc1826 + zh: 4d3511e4f0db5b9d +/agent-note-one-outbound-proxy-policy-installed-before-anything-can-request/problem: + en: 70e5f3ed33010c98 + zh: 5437d943953f5a40 +/agent-note-one-outbound-proxy-policy-installed-before-anything-can-request/decision: + en: efe23161a54f70c5 + zh: e24ee097918b2724 +/agent-note-one-outbound-proxy-policy-installed-before-anything-can-request/alternatives-considered: + en: df44eb15557b95fe + zh: b757e53da4c0a99f +/agent-note-one-outbound-proxy-policy-installed-before-anything-can-request/consequences: + en: 6a4acbab915f1bd1 + zh: 2c8ffd62ba74ff96 +/agent-note-one-outbound-proxy-policy-installed-before-anything-can-request/testing: + en: 0d7eaa666c94a5cd + zh: 210fa098f154d137 diff --git a/.agents/notes/implemented/architecture/2026-08-28-ctx-remote-failure-vocabulary.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-28-ctx-remote-failure-vocabulary.i18n.yaml index 5952b7afe6..2e76fba547 100644 --- a/.agents/notes/implemented/architecture/2026-08-28-ctx-remote-failure-vocabulary.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-28-ctx-remote-failure-vocabulary.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-28-ctx-remote-failure-vocabulary.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-28-ctx-remote-failure-vocabulary.md -2026-08-28-ctx-remote-failure-vocabulary.md: 7238ae23b4581ab645b2bc9a780b77dc4a59d574 -2026-08-28-ctx-remote-failure-vocabulary.zh.md: db0b2969bc94c3d9c848b187a0521ce5ec387492 +/agent-note-one-remote-failure-vocabulary-for-ctx-remote: + en: 3aca057ba2c3ae29 + zh: 3d54024d40265a2a +/agent-note-one-remote-failure-vocabulary-for-ctx-remote/problem: + en: 990d46f713fb6303 + zh: 592cd6128a9640b1 +/agent-note-one-remote-failure-vocabulary-for-ctx-remote/decision: + en: 120e2fb97ac765d8 + zh: 5d5f110db4a9b717 +/agent-note-one-remote-failure-vocabulary-for-ctx-remote/code-ownership: + en: cc1d8b88f7349b77 + zh: 70f010e3310e2667 +/agent-note-one-remote-failure-vocabulary-for-ctx-remote/discrimination-by-code: + en: 8ca8ea2f3236569f + zh: ffca80a5157af245 +/agent-note-one-remote-failure-vocabulary-for-ctx-remote/fixed-host-facts: + en: 0dfb0ca5cf67b296 + zh: baaa890425996fb3 +/agent-note-one-remote-failure-vocabulary-for-ctx-remote/what-the-wire-carries: + en: 346e655fe98b95bd + zh: 24185f170ef97811 +/agent-note-one-remote-failure-vocabulary-for-ctx-remote/alternatives-considered: + en: d92f46d0827ad0d1 + zh: 640f223d3a27559b +/agent-note-one-remote-failure-vocabulary-for-ctx-remote/consequences: + en: 20d2d65d555ef680 + zh: f8a3de3ce72058c7 diff --git a/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.i18n.yaml index bfe7ee764b..76b43c4348 100644 --- a/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-28-subprocess-native-containment.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-28-subprocess-native-containment.md -2026-08-28-subprocess-native-containment.md: 88acee2d41fab878a0e50380cbb87eaece8e7296 -2026-08-28-subprocess-native-containment.zh.md: 53406f99531953a0330abf08be150da845f37aab +/agent-note-native-owners-contain-escaped-subprocess-descendants: + en: 161c05f390ea3f51 + zh: 1c1c83ad4f9780dd +/agent-note-native-owners-contain-escaped-subprocess-descendants/problem: + en: a88b160c6c1f57e5 + zh: 0b1a7cb68e9aaabd +/agent-note-native-owners-contain-escaped-subprocess-descendants/decision: + en: 0469a956a95bccdf + zh: 2c5ea38a2841e1ae +/agent-note-native-owners-contain-escaped-subprocess-descendants/decision/linux-scope-and-one-shot-bootstrap: + en: 582e6f5f5f7cc940 + zh: b47cee599d22aaa2 +/agent-note-native-owners-contain-escaped-subprocess-descendants/decision/windows-runner-and-job: + en: a6401ee73bb173b7 + zh: 45b9cc7fea6f7921 +/agent-note-native-owners-contain-escaped-subprocess-descendants/decision/private-dispatch-and-protocol: + en: bf25e4b385bf9299 + zh: 6ed1062fbe49f3cf +/agent-note-native-owners-contain-escaped-subprocess-descendants/decision/fallback-and-cleanup: + en: 19da14bf2234744f + zh: 8f723b1c9c8a3a58 +/agent-note-native-owners-contain-escaped-subprocess-descendants/existing-decisions-and-supersession: + en: 8f24a2276aff4bd2 + zh: a3a36dd28f3ab0e0 +/agent-note-native-owners-contain-escaped-subprocess-descendants/verification: + en: 900e10a3f9cd3b67 + zh: efc5d9f09a0e8e5a +/agent-note-native-owners-contain-escaped-subprocess-descendants/alternatives-considered: + en: 12bbc028fbb14667 + zh: 9fea4359308337bd +/agent-note-native-owners-contain-escaped-subprocess-descendants/consequences: + en: 0151145ee6281267 + zh: 5bd2e53ad58107e9 diff --git a/.agents/notes/implemented/architecture/2026-08-30-retain-ignorable-external-session-events.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-30-retain-ignorable-external-session-events.i18n.yaml index 0d29ace9ff..63a2bfdc06 100644 --- a/.agents/notes/implemented/architecture/2026-08-30-retain-ignorable-external-session-events.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-30-retain-ignorable-external-session-events.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-30-retain-ignorable-external-session-events.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-30-retain-ignorable-external-session-events.md -2026-08-30-retain-ignorable-external-session-events.md: e085e429a6ad49cf742694cec7dda05770a5b8a1 -2026-08-30-retain-ignorable-external-session-events.zh.md: 1fe4f81441503287961b993eae444fa4385f4803 +/agent-note-retain-ignorable-session-events-for-external-plugins: + en: 09f4f7ee764601c3 + zh: af6ead8e96015e51 +/agent-note-retain-ignorable-session-events-for-external-plugins/problem: + en: d2df1eb3602af45d + zh: fd162b1c214f1494 +/agent-note-retain-ignorable-session-events-for-external-plugins/decision: + en: a4162e65cf6768f3 + zh: bb700d9630642e7e +/agent-note-retain-ignorable-session-events-for-external-plugins/alternatives-considered: + en: 30ec097e3ba4e951 + zh: 3e90fc035d04b09b +/agent-note-retain-ignorable-session-events-for-external-plugins/consequences: + en: 5f65bfb81f172d49 + zh: 069d41d6bda9f8af diff --git a/.agents/notes/implemented/architecture/2026-08-31-alpha-historical-unknown-event-refusal.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-31-alpha-historical-unknown-event-refusal.i18n.yaml index c976a60147..4453d0d171 100644 --- a/.agents/notes/implemented/architecture/2026-08-31-alpha-historical-unknown-event-refusal.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-31-alpha-historical-unknown-event-refusal.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-31-alpha-historical-unknown-event-refusal.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-31-alpha-historical-unknown-event-refusal.md -2026-08-31-alpha-historical-unknown-event-refusal.md: c63b36f63206e0992416239483d908b0645a98c2 -2026-08-31-alpha-historical-unknown-event-refusal.zh.md: 231c46c11486b05a69a200b857a0ea6df35b6e79 +/agent-note-alpha-session-migration-refuses-every-unknown-historical-event: + en: 4c7472b402f5dd38 + zh: 1d7aa8233d13a083 +/agent-note-alpha-session-migration-refuses-every-unknown-historical-event/problem: + en: 8864f28d0139c490 + zh: 2aa7b6eceb5510c0 +/agent-note-alpha-session-migration-refuses-every-unknown-historical-event/decision: + en: 62afb095b98209a6 + zh: 55b3eae2a6f64989 +/agent-note-alpha-session-migration-refuses-every-unknown-historical-event/consequences: + en: 8416322aefd92a3d + zh: 6e06f732ae2f48fc +/agent-note-alpha-session-migration-refuses-every-unknown-historical-event/alternatives-considered: + en: 3adeafa6fb02ab56 + zh: daf6c67c43804da7 diff --git a/.agents/notes/implemented/architecture/2026-08-31-explicit-agent-runtime-identity.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-31-explicit-agent-runtime-identity.i18n.yaml index 4fac92ed8c..c28606ddd1 100644 --- a/.agents/notes/implemented/architecture/2026-08-31-explicit-agent-runtime-identity.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-31-explicit-agent-runtime-identity.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-31-explicit-agent-runtime-identity.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-31-explicit-agent-runtime-identity.md -2026-08-31-explicit-agent-runtime-identity.md: f52b8ec116c312a27306fe73dc0bd5b99fcd9039 -2026-08-31-explicit-agent-runtime-identity.zh.md: 6b6fd2f2ea1f1645069264f09fd53c3f71e1d02f +/agent-note-explicit-agent-identity-at-runtime-boundaries: + en: f5e76516df025fc5 + zh: 462fe05b46e6c1ea +/agent-note-explicit-agent-identity-at-runtime-boundaries/problem: + en: 0b737a098e4e19ce + zh: 97b4254c4533114f +/agent-note-explicit-agent-identity-at-runtime-boundaries/decision: + en: dfee8c7c574e0001 + zh: 3894ffa7beba4348 +/agent-note-explicit-agent-identity-at-runtime-boundaries/verification: + en: 85130faaa171036b + zh: 06e5e9fab32dbfb4 +/agent-note-explicit-agent-identity-at-runtime-boundaries/alternatives-considered: + en: 2c41456509d54d21 + zh: 5704ee9a2274e300 +/agent-note-explicit-agent-identity-at-runtime-boundaries/consequences: + en: 08ab86b89fc3ec6f + zh: 3866e6557858543a diff --git a/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.i18n.yaml index 008e706bbf..38dbc1ec40 100644 --- a/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.i18n.yaml @@ -1,6 +1,67 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-31-released-session-format-migrations.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md -2026-08-31-released-session-format-migrations.md: 00672af920cf8369022b4274c1c50552f5407a7e -2026-08-31-released-session-format-migrations.zh.md: 9404d8f454b7c17be69ae064c405c4dcc0794f88 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages: + en: 1a1d3bd9c2311ed6 + zh: 366eded1272efd63 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/problem: + en: a1f71d6123b80d10 + zh: 8e05da34ba92686a +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/problem/whole-artifact-performance-failure: + en: 85ba92c98dd97591 + zh: c464cdd860add9c7 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/problem/the-interfaces-prevented-local-fixes-from-composing: + en: e582758acd683242 + zh: c5a5a27af1f33af7 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/decision: + en: 8756dc3c6235ba0b + zh: 8089fde062466c5c +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/decision/stage-and-context-protocol: + en: ed34c76e1a2c0a42 + zh: 0efe92c6c9ea314e +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/decision/adjacent-version-ownership: + en: 31e5b2e26604110e + zh: 18d27da9b4661702 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/decision/physical-codecs-and-packed-runs: + en: 42e8d5405375cba7 + zh: efd201181e47d579 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/decision/jsonl-integration: + en: 662859038e888672 + zh: a1646f3ff5710e8d +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/decision/durable-format-and-publication-rules: + en: 6e2a76ae14612199 + zh: 3c90fd32d292f9d0 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/problem-to-solution-mapping: + en: 65968c18c3d1b7e9 + zh: 2e43d7ce1391d554 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/problem-to-solution-mapping/parent-catalog-prerequisites: + en: 81b40660b49dbfb0 + zh: 67cfa3f43b6eb53e +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/problem-to-solution-mapping/catalog-scan-measurements: + en: 6b7a79fb81e58bac + zh: 51fc00eaf3a0c3dc +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/verification: + en: 061a112f789c9966 + zh: e78b0b1a83837eae +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/verification/benchmark-input-and-meanings: + en: 3cbcde15a46b4136 + zh: fe899549758f8ee3 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/verification/physical-decode: + en: 1c79e71ee17a156f + zh: 7563d24c9f2befe8 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/verification/historical-file-cold-open: + en: 09fe5e0aa4f57c6e + zh: a103dc631d1b0b79 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/verification/current-format-cold-open: + en: 60f7de284f6ded10 + zh: 877b300503a4615d +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/verification/streaming-serial-migration-breakdown: + en: b9183e6c34a960dd + zh: d64ffecb289e7b74 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/consequences: + en: fa005a93cc0b0906 + zh: 248a08f307d4c1b7 +/agent-note-released-session-formats-migrate-through-stateful-streaming-stages/alternatives-considered: + en: b70193af15b1a2ea + zh: d8a23e47e6b9cf88 diff --git a/.agents/notes/implemented/architecture/2026-09-01-jobs-absorb-activity-record.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-01-jobs-absorb-activity-record.i18n.yaml index 497481e7d2..dcd4dd469f 100644 --- a/.agents/notes/implemented/architecture/2026-09-01-jobs-absorb-activity-record.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-01-jobs-absorb-activity-record.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-01-jobs-absorb-activity-record.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-01-jobs-absorb-activity-record.md -2026-09-01-jobs-absorb-activity-record.md: 508608f7eb694bf131bad9a25e856d32c7079559 -2026-09-01-jobs-absorb-activity-record.zh.md: 2c157d951042f1cd6f8a3a66129773bc99cd5b02 +/agent-note-the-job-registry-absorbs-the-observation-record-the-standalone-activity-seam-is-removed: + en: f407477a58d20fb6 + zh: b65bc22b9e1e21c3 +/agent-note-the-job-registry-absorbs-the-observation-record-the-standalone-activity-seam-is-removed/problem: + en: a4008f3bcd1e3bd0 + zh: fa8432ddc47003c4 +/agent-note-the-job-registry-absorbs-the-observation-record-the-standalone-activity-seam-is-removed/decision: + en: c7ada6a40d92daf4 + zh: bd16a02f295c4ae2 +/agent-note-the-job-registry-absorbs-the-observation-record-the-standalone-activity-seam-is-removed/alternatives-considered: + en: 00067552f2fcb740 + zh: aa23082899db1a1a +/agent-note-the-job-registry-absorbs-the-observation-record-the-standalone-activity-seam-is-removed/review-corrections: + en: 93db5342c848587a + zh: d4e67a47d573eb39 +/agent-note-the-job-registry-absorbs-the-observation-record-the-standalone-activity-seam-is-removed/consequences: + en: c1df52910a1ee554 + zh: 50fd15ed06f07f76 diff --git a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.i18n.yaml index 59e3f84862..dbb198ca69 100644 --- a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-01-parent-owned-subagent-catalog.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md -2026-09-01-parent-owned-subagent-catalog.md: 536ec33148bd675a974622b98ee23de812691dc0 -2026-09-01-parent-owned-subagent-catalog.zh.md: ec78ff9e4b7d54a7309baf21c383ec5ff83a19c8 +/agent-note-parent-owned-subagent-catalog-events: + en: 3fc04c5406fdcf8a + zh: a103082ae858dff3 +/agent-note-parent-owned-subagent-catalog-events/problem: + en: 5a991fec31578cea + zh: 13b75aa36eb22907 +/agent-note-parent-owned-subagent-catalog-events/decision: + en: 198354f20b5d0a42 + zh: 7a6b4392117a60b5 +/agent-note-parent-owned-subagent-catalog-events/alternatives-considered: + en: 7a3d4b9f69c243d8 + zh: 82b03d16ccc94dd2 +/agent-note-parent-owned-subagent-catalog-events/consequences: + en: d582273d5102d617 + zh: 7f05590581b1df88 diff --git a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md index 536ec33148..27582937d8 100644 --- a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md +++ b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md @@ -44,6 +44,6 @@ Current-writer snapshot expectations include catalog facts even when replay inpu ## Consequences -Session observations and client snapshots expose the direct-child list through `projections.values.subagentCatalog`. The projection change feed publishes a complete list when catalog state changes. Each view costs O(D), so D creations can incur O(D²) cumulative view work; this follows the existing projection mechanism. `listChildren()` reads the parent projection through one live-preferred Session observation; descendant listing uses the Session corpus and child identity projection. [Web projection consumption](../simplification/2026-09-08-web-subagent-catalog-projections.md) owns browser loading and synchronization. +Session observations and client snapshots expose the direct-child list through `projections.values.subagentCatalog`. The projection change feed publishes a complete list when catalog state changes. Each view costs O(D), so D creations can incur O(D²) cumulative view work; this follows the existing projection mechanism. `listChildren()` reads the parent projection through one live-preferred Session observation; descendant listing recursively calls the same reader in catalog order. Reachable catalog facts supply identity and membership without a global Session scan or a separate child-identity cache path. Unreadable branches remain diagnostics; uncataloged Sessions are outside discovery. [Web projection consumption](../simplification/2026-09-08-web-subagent-catalog-projections.md) owns browser loading and synchronization. [Creation metadata exclusion](../simplification/2026-09-16-subagent-catalog-membership-only.md) records why model configuration is absent from catalog facts. diff --git a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md index ec78ff9e4b..982dab234e 100644 --- a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md @@ -44,6 +44,6 @@ snapshot normalizer 会把 `childCreatedAt` 归零,因为它来自 process clo ## 后果 -Session observation 与 client snapshot 通过 `projections.values.subagentCatalog` 暴露直接子级列表。目录状态变化时,projection change feed 发布完整列表。每次 view 的成本为 O(D),因此 D 次创建可能累计产生 O(D²) 的 view 工作量;这沿用现有 projection 机制。`listChildren()` 通过一次 live-preferred Session observation 读取父 projection;后代枚举使用 Session 语料库与子身份 projection。[Web projection 消费决策](../simplification/2026-09-08-web-subagent-catalog-projections.zh.md) 说明浏览器加载与同步。 +Session observation 与 client snapshot 通过 `projections.values.subagentCatalog` 暴露直接子级列表。目录状态变化时,projection change feed 发布完整列表。每次 view 的成本为 O(D),因此 D 次创建可能累计产生 O(D²) 的 view 工作量;这沿用现有 projection 机制。`listChildren()` 通过一次 live-preferred Session observation 读取父 projection;后代枚举按目录顺序递归调用同一读取函数。可达目录事实提供身份和成员关系,无需全局 Session 扫描或独立的子身份缓存路径。不可读分支保留为诊断;未进入目录的 Session 不在发现范围内。[Web projection 消费决策](../simplification/2026-09-08-web-subagent-catalog-projections.zh.md) 说明浏览器加载与同步。 [创建元数据排除决策](../simplification/2026-09-16-subagent-catalog-membership-only.zh.md) 说明目录事实为何不包含模型配置。 diff --git a/.agents/notes/implemented/architecture/2026-09-01-v2-embedded-assistant-streams.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-01-v2-embedded-assistant-streams.i18n.yaml index 3dcffdc51a..c171926d8d 100644 --- a/.agents/notes/implemented/architecture/2026-09-01-v2-embedded-assistant-streams.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-01-v2-embedded-assistant-streams.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-01-v2-embedded-assistant-streams.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-01-v2-embedded-assistant-streams.md -2026-09-01-v2-embedded-assistant-streams.md: 89b494959fcc10a2c9847908adcf13d5eedcd749 -2026-09-01-v2-embedded-assistant-streams.zh.md: 63cb425740cd2243361ec00a6dadad82c38f6f0f +/agent-note-embed-assistant-streams-in-v2-attempt-settlements: + en: ada7ae6629d0d4e4 + zh: cc1f9a43e87d2dee +/agent-note-embed-assistant-streams-in-v2-attempt-settlements/problem: + en: 9e95306554ecd1ca + zh: 40478697fbc94e33 +/agent-note-embed-assistant-streams-in-v2-attempt-settlements/decision: + en: 14558bfaf20998db + zh: d883b1dd6f024b93 +/agent-note-embed-assistant-streams-in-v2-attempt-settlements/decision/live-presentation-and-durable-replay: + en: daf667b45ce34da3 + zh: 25b17f7b3ec14d9e +/agent-note-embed-assistant-streams-in-v2-attempt-settlements/decision/released-v1-to-v2-migration: + en: c1b5a775aa073a9a + zh: 45a16998d636aec1 +/agent-note-embed-assistant-streams-in-v2-attempt-settlements/verification: + en: 64b75fcbb0c3f819 + zh: 6fe01443a7abec72 +/agent-note-embed-assistant-streams-in-v2-attempt-settlements/alternatives-considered: + en: 74cdc6838df6172e + zh: ebca79a08ff3ebe4 +/agent-note-embed-assistant-streams-in-v2-attempt-settlements/consequences: + en: fc745b93d5e92f50 + zh: 4fa418c30e1968b4 diff --git a/.agents/notes/implemented/architecture/2026-09-02-projcache-cross-version-read-compat.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-02-projcache-cross-version-read-compat.i18n.yaml index 87f3b7c351..6a8c9879cf 100644 --- a/.agents/notes/implemented/architecture/2026-09-02-projcache-cross-version-read-compat.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-02-projcache-cross-version-read-compat.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-02-projcache-cross-version-read-compat.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-02-projcache-cross-version-read-compat.md -2026-09-02-projcache-cross-version-read-compat.md: 160c5c796bacc6f672b06acc0df4246d7008c52b -2026-09-02-projcache-cross-version-read-compat.zh.md: cff7742f6c1f887b905a2c139e4157782aef677c +/agent-note-projection-cache-predecessor-recovery-and-session-format-binding-session-projcache-v3-v6-v7: + en: 5744de86025f278d + zh: 5ba2198c13ac54f9 +/agent-note-projection-cache-predecessor-recovery-and-session-format-binding-session-projcache-v3-v6-v7/problem: + en: f8d44a69c7b5fefe + zh: 76a4fb3d87698194 +/agent-note-projection-cache-predecessor-recovery-and-session-format-binding-session-projcache-v3-v6-v7/the-on-disk-generations: + en: 221b8afd2599e139 + zh: ba1de634b87edc71 +/agent-note-projection-cache-predecessor-recovery-and-session-format-binding-session-projcache-v3-v6-v7/decision: + en: 264e40c0fb90cdc1 + zh: 2e986615bbd656cf +/agent-note-projection-cache-predecessor-recovery-and-session-format-binding-session-projcache-v3-v6-v7/decision/v3-v6-v7-disposition: + en: fe188d164c08a7f5 + zh: 30aa9e9201621f35 +/agent-note-projection-cache-predecessor-recovery-and-session-format-binding-session-projcache-v3-v6-v7/decision/upgrade-matrix: + en: 5d515bd3cb34b0ee + zh: 0648563a966759c7 +/agent-note-projection-cache-predecessor-recovery-and-session-format-binding-session-projcache-v3-v6-v7/alternatives-considered: + en: c53e111219c5da0c + zh: 8c69f6fc2e776981 +/agent-note-projection-cache-predecessor-recovery-and-session-format-binding-session-projcache-v3-v6-v7/consequences: + en: ac8b2f4a66c926ea + zh: 5a415436c2fbc4ec +/agent-note-projection-cache-predecessor-recovery-and-session-format-binding-session-projcache-v3-v6-v7/testing: + en: 495058fe5708949d + zh: 67ed95abc946d418 diff --git a/.agents/notes/implemented/architecture/2026-09-02-system-prompt-as-surface-node.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-02-system-prompt-as-surface-node.i18n.yaml index 174aa2592e..6a5de04c23 100644 --- a/.agents/notes/implemented/architecture/2026-09-02-system-prompt-as-surface-node.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-02-system-prompt-as-surface-node.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-02-system-prompt-as-surface-node.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-02-system-prompt-as-surface-node.md -2026-09-02-system-prompt-as-surface-node.md: 1500fd2350f02ab5d8f203c0d62b98832c6c5de5 -2026-09-02-system-prompt-as-surface-node.zh.md: 306f347092caa3e9daf2494fa26d290b1c1ab9a7 +/agent-note-the-system-prompt-is-surface-node-0: + en: 449b745953058cff + zh: 4db99c7d1f06e6b9 +/agent-note-the-system-prompt-is-surface-node-0/problem: + en: 9ff2541082426e31 + zh: d8f0ca49d3548f9b +/agent-note-the-system-prompt-is-surface-node-0/decision: + en: 3911ea80c5466d5e + zh: a0d6844e6f8af462 +/agent-note-the-system-prompt-is-surface-node-0/decision/the-event: + en: 35302b956efc4999 + zh: e45ee0d001b63269 +/agent-note-the-system-prompt-is-surface-node-0/decision/the-operations: + en: a217a08932938062 + zh: 4924d99d55d9c973 +/agent-note-the-system-prompt-is-surface-node-0/decision/ownership-in-the-loop: + en: 88945024c2efe271 + zh: 05dca84a4ce5e614 +/agent-note-the-system-prompt-is-surface-node-0/decision/consumers: + en: 39f9f4acffcccdc6 + zh: 36b23a57e7d28950 +/agent-note-the-system-prompt-is-surface-node-0/decision/v2-to-v3-structural-conversion: + en: 131ae882d0a28735 + zh: ea4bc81f0ba5ddec +/agent-note-the-system-prompt-is-surface-node-0/alternatives-considered: + en: 067e96734ebbce89 + zh: 9f79bc0f4942675d +/agent-note-the-system-prompt-is-surface-node-0/consequences: + en: bccea8236b4c32b3 + zh: a1150784718a6639 +/agent-note-the-system-prompt-is-surface-node-0/testing: + en: f5b21c4863cd92bd + zh: 7d1efed827d55161 diff --git a/.agents/notes/implemented/architecture/2026-09-03-jobs-seam-consolidation.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-03-jobs-seam-consolidation.i18n.yaml index 1d1a4bc731..69dfebb312 100644 --- a/.agents/notes/implemented/architecture/2026-09-03-jobs-seam-consolidation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-03-jobs-seam-consolidation.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-03-jobs-seam-consolidation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-03-jobs-seam-consolidation.md -2026-09-03-jobs-seam-consolidation.md: 2742ff1a80ec4cc4d8e5948f63d306abb9753733 -2026-09-03-jobs-seam-consolidation.zh.md: 1fa61919a27362ce42419b57e0960e9be86ea07e +/agent-note-one-output-ring-one-projection-one-event-stream-for-background-jobs: + en: f4cb113e6501a363 + zh: 55693cca6db201b0 +/agent-note-one-output-ring-one-projection-one-event-stream-for-background-jobs/problem: + en: 2e213085523c8ebe + zh: 28229d752ccc7ec4 +/agent-note-one-output-ring-one-projection-one-event-stream-for-background-jobs/decision: + en: a7e2bd18a7e647f0 + zh: 1d8f5500a3b0502a +/agent-note-one-output-ring-one-projection-one-event-stream-for-background-jobs/alternatives-considered: + en: d5d9d6c2c05e563b + zh: 66b2489d947365fe +/agent-note-one-output-ring-one-projection-one-event-stream-for-background-jobs/consequences: + en: 23b0112bba743396 + zh: 28f38ff246b4525f diff --git a/.agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.i18n.yaml index f62b326074..3793dc362f 100644 --- a/.agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-canonical-feedback-log.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.md -2026-09-05-canonical-feedback-log.md: ce7b705b24cb0a4f7432215e19589095a9afc719 -2026-09-05-canonical-feedback-log.zh.md: 7d970ff7aea4962ea52c764fec5b6c07e3669099 +/agent-note-canonical-feedback-log-and-request-delivery: + en: 7dd56e2d495370cf + zh: 0977ed8b2f45dbe5 +/agent-note-canonical-feedback-log-and-request-delivery/problem: + en: 702e5973c264ec35 + zh: 71b095565593629c +/agent-note-canonical-feedback-log-and-request-delivery/decision: + en: 7ae952bbc9193865 + zh: f120bed1d1782470 +/agent-note-canonical-feedback-log-and-request-delivery/alternatives-considered: + en: 9ddfc84ac3a25f3b + zh: f185250a0ec512ba +/agent-note-canonical-feedback-log-and-request-delivery/consequences: + en: f1f99907cd77bdef + zh: e97b76e4a19c5581 diff --git a/.agents/notes/implemented/architecture/2026-09-05-client-resource-model.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-05-client-resource-model.i18n.yaml index aba709660e..76c55ab2c1 100644 --- a/.agents/notes/implemented/architecture/2026-09-05-client-resource-model.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-05-client-resource-model.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-client-resource-model.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-05-client-resource-model.md -2026-09-05-client-resource-model.md: e6ad8dae331d8a6392585f5dc8eb8fc52150bdc3 -2026-09-05-client-resource-model.zh.md: d716aa8a42f5c3037a329deabd572a56ab1b0537 +/agent-note-client-resource-model: + en: 48276fc837820219 + zh: 2d99ee9eae22e1e0 +/agent-note-client-resource-model/problem: + en: 22aec3ac5b197342 + zh: 0cd0b1f8094addb3 +/agent-note-client-resource-model/decision: + en: 78afa8698a884b98 + zh: b33cfcae7e75660f +/agent-note-client-resource-model/decision/addresses: + en: 180e3e39813a93b1 + zh: 845befb7c760f7e1 +/agent-note-client-resource-model/decision/the-service: + en: f42277e961bb7209 + zh: 9f3f8a50ad55cf4a +/agent-note-client-resource-model/decision/the-hook: + en: 4f082c4f5a44320a + zh: eba5449b7a1fd52e +/agent-note-client-resource-model/decision/frames: + en: bc1c4e9a9e8e9b20 + zh: f80a77ee66943ce4 +/agent-note-client-resource-model/decision/lifecycle: + en: 4c11bfba97a54646 + zh: a07bda77e918d613 +/agent-note-client-resource-model/alternatives-considered: + en: 288b448e7f1de8af + zh: 997e10c66decce34 +/agent-note-client-resource-model/consequences: + en: 3eda54cb5d74ed00 + zh: ce60b6fef04acb9a +/agent-note-client-resource-model/testing: + en: ca2c610e4f0352ac + zh: fbaa69ee8de7e4c1 +/agent-note-client-resource-model/deferred: + en: 312b46f16d88f301 + zh: a530b3940859079c diff --git a/.agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.i18n.yaml index 58f161426a..fcea6899f3 100644 --- a/.agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-nonofficial-feedback-otel.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.md -2026-09-05-nonofficial-feedback-otel.md: 8225d8bea030c4f09b60fd1a228f0425e9489d39 -2026-09-05-nonofficial-feedback-otel.zh.md: e8ea48b3fe2f228ef57ae1a20f92100dfc333f9c +/agent-note-explicit-feedback-only-upload-through-opentelemetry: + en: 96caaaf6a4efc8cf + zh: 2ef629917f3f2567 +/agent-note-explicit-feedback-only-upload-through-opentelemetry/problem: + en: 7849f56f36e297e8 + zh: b98da01a1fd5d974 +/agent-note-explicit-feedback-only-upload-through-opentelemetry/decision: + en: c4558bdfc95ee2f2 + zh: 4fc88ffa4512b66a +/agent-note-explicit-feedback-only-upload-through-opentelemetry/alternatives-considered: + en: 21376ce3ebef2662 + zh: d3168b64bdf093bf +/agent-note-explicit-feedback-only-upload-through-opentelemetry/consequences: + en: 7daf3ebf1bfd2124 + zh: f2cec93e3069a973 diff --git a/.agents/notes/implemented/architecture/2026-09-05-package-manifest-types.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-05-package-manifest-types.i18n.yaml index 1e9e2e658d..1cbd6713ec 100644 --- a/.agents/notes/implemented/architecture/2026-09-05-package-manifest-types.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-05-package-manifest-types.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-package-manifest-types.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-05-package-manifest-types.md -2026-09-05-package-manifest-types.md: dc018ba019028b942a17cd016c8670f2405c3bc7 -2026-09-05-package-manifest-types.zh.md: 8fd323bfe6058a6a062e3834a8630c0181a203fc +/agent-note-package-manifest-declaration-ownership: + en: 26d50551c7d49cf8 + zh: eac4a93af773c945 +/agent-note-package-manifest-declaration-ownership/problem: + en: bdc0fcaf27081889 + zh: 45eb034edd0bed82 +/agent-note-package-manifest-declaration-ownership/decision: + en: da43234e14fa9bd5 + zh: 0389015e086f4e25 +/agent-note-package-manifest-declaration-ownership/alternatives-considered: + en: bf99e75ffab5cb45 + zh: 398f5934858aaca5 +/agent-note-package-manifest-declaration-ownership/consequences: + en: ce7c3df526622bf2 + zh: 91d51dff77371cb0 diff --git a/.agents/notes/implemented/architecture/2026-09-05-read-only-session-migration-preparation.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-05-read-only-session-migration-preparation.i18n.yaml index c71a86687b..93080791e0 100644 --- a/.agents/notes/implemented/architecture/2026-09-05-read-only-session-migration-preparation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-05-read-only-session-migration-preparation.i18n.yaml @@ -1,6 +1,52 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-read-only-session-migration-preparation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-05-read-only-session-migration-preparation.md -2026-09-05-read-only-session-migration-preparation.md: 081044e34d5071ba242792c588f43a3b83adddd5 -2026-09-05-read-only-session-migration-preparation.zh.md: 7406e7cf31112df6c9f6bb0d454f38d0cf7eb6a4 +/agent-note-historical-session-reads-prepare-before-write-publication: + en: 9b0c300b8c4ea348 + zh: fb248e39c7c82d21 +/agent-note-historical-session-reads-prepare-before-write-publication/problem: + en: 1064c02bdd0829f6 + zh: b8804a72c487d7f6 +/agent-note-historical-session-reads-prepare-before-write-publication/problem/serial-readiness-cost: + en: d1a38e3967176a41 + zh: 746d22a7b65bbacf +/agent-note-historical-session-reads-prepare-before-write-publication/problem/a-naive-split-would-break-lifecycle-guarantees: + en: b6c28b36e59cff21 + zh: 7c52d50d332204ad +/agent-note-historical-session-reads-prepare-before-write-publication/decision: + en: b1c9289331cc1b1c + zh: cddc6fba651201b3 +/agent-note-historical-session-reads-prepare-before-write-publication/decision/prepared-generation-api: + en: 70013314a5ab75c2 + zh: dc83dc7254554951 +/agent-note-historical-session-reads-prepare-before-write-publication/decision/preparation-ownership-and-cancellation: + en: 1e0583523a341ec1 + zh: a78b8cac656559e9 +/agent-note-historical-session-reads-prepare-before-write-publication/decision/read-handle-transition: + en: a74f92b2e6224c7e + zh: 0190d524f8c84770 +/agent-note-historical-session-reads-prepare-before-write-publication/decision/write-open-publication: + en: 9d2d50cb76754b74 + zh: 9ceed3652475f18d +/agent-note-historical-session-reads-prepare-before-write-publication/decision/follow-and-agent-promotion: + en: 692c29db3e7ab07e + zh: 7da0cfdbc80f407d +/agent-note-historical-session-reads-prepare-before-write-publication/problem-to-solution-mapping: + en: e067e187cd4d0a8c + zh: b0c79b635a637296 +/agent-note-historical-session-reads-prepare-before-write-publication/verification: + en: b2b07b60141996ac + zh: 5280ee3455b8c953 +/agent-note-historical-session-reads-prepare-before-write-publication/verification/first-opening-of-historical-data: + en: 048ea8684231ac22 + zh: 83591137f214478b +/agent-note-historical-session-reads-prepare-before-write-publication/verification/scheduling-observation-points: + en: a91766778611df3b + zh: 2a38f5a865dcd413 +/agent-note-historical-session-reads-prepare-before-write-publication/consequences: + en: 4482da434feb62a0 + zh: 38bf9bbb99d3e246 +/agent-note-historical-session-reads-prepare-before-write-publication/alternatives-considered: + en: c11bc9a1ad9a8568 + zh: 717da2fad77cff17 diff --git a/.agents/notes/implemented/architecture/2026-09-05-shared-client-control-primitives.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-05-shared-client-control-primitives.i18n.yaml index 55f30d278a..d7f7c0dc3b 100644 --- a/.agents/notes/implemented/architecture/2026-09-05-shared-client-control-primitives.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-05-shared-client-control-primitives.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-shared-client-control-primitives.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-05-shared-client-control-primitives.md -2026-09-05-shared-client-control-primitives.md: db8cb9a8bc515918867b27b216fe8edb50c392db -2026-09-05-shared-client-control-primitives.zh.md: 6d4b04a21bf224eaa32b5fbdfb2bf1c3a2cd804d +/agent-note-shared-client-control-primitives: + en: 53e5c771078f4383 + zh: 59e4cc45d06adbee +/agent-note-shared-client-control-primitives/problem: + en: 7a711c1cafe0be88 + zh: 7275b36fdd5094f6 +/agent-note-shared-client-control-primitives/decision: + en: cc335d6820b9ab1c + zh: e375bababc0fccdb +/agent-note-shared-client-control-primitives/finding-the-duplicates: + en: f50ed2aea00a34c5 + zh: a8a27c1d1e0177a8 +/agent-note-shared-client-control-primitives/what-stays-local: + en: e4fb0a84b9924d5a + zh: 30545265b2159f04 +/agent-note-shared-client-control-primitives/alternatives-considered: + en: f77deaa327bc5395 + zh: be8450b665be04bf +/agent-note-shared-client-control-primitives/testing: + en: 578f6bad674e4c40 + zh: 0a8f2e72bb4d1f61 +/agent-note-shared-client-control-primitives/consequences: + en: f94dd6f669d00276 + zh: a67de4bd3f242232 diff --git a/.agents/notes/implemented/architecture/2026-09-05-sidebar-tab-types-and-navigation.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-05-sidebar-tab-types-and-navigation.i18n.yaml index 577fbe18d0..f7b369d628 100644 --- a/.agents/notes/implemented/architecture/2026-09-05-sidebar-tab-types-and-navigation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-05-sidebar-tab-types-and-navigation.i18n.yaml @@ -1,6 +1,43 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-sidebar-tab-types-and-navigation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-05-sidebar-tab-types-and-navigation.md -2026-09-05-sidebar-tab-types-and-navigation.md: 599ce36ed4bb1dfc2cce063a461903e1a4aeb40e -2026-09-05-sidebar-tab-types-and-navigation.zh.md: e4e8de5a389fea77aae705d63cc4fb16f88af647 +/agent-note-right-sidebar-tab-types-and-navigation: + en: 2860d8acc82e4a85 + zh: 7b09ac61a684e36d +/agent-note-right-sidebar-tab-types-and-navigation/problem: + en: 1db34c36cf2dc2bd + zh: 4d4e8d3f09ac18c6 +/agent-note-right-sidebar-tab-types-and-navigation/decision: + en: 905fd6fbedad540f + zh: 5420c0dff38012d8 +/agent-note-right-sidebar-tab-types-and-navigation/decision/the-type-registry-ctx-sidebarrighttabs: + en: 9c0a993b39b2c92f + zh: 0e0c008e425f47e4 +/agent-note-right-sidebar-tab-types-and-navigation/decision/bodies-and-titles-keyed-slot-seats-under-the-definition-s-id: + en: 9e80f2d213b394fe + zh: 79f2e5c504b9863e +/agent-note-right-sidebar-tab-types-and-navigation/decision/tab-occurrence-information: + en: 774c3bf80a48ffbe + zh: c513245789aa8efd +/agent-note-right-sidebar-tab-types-and-navigation/decision/navigation-ctx-sidebarright: + en: b32bad4c3b8c2cc8 + zh: 57ba7b8d3451e478 +/agent-note-right-sidebar-tab-types-and-navigation/decision/addresses: + en: eeb1e7e7478a2f2c + zh: bddbc5bc78245f63 +/agent-note-right-sidebar-tab-types-and-navigation/decision/entry-points: + en: 6386bde2654f9a0a + zh: 700439be6a01e162 +/agent-note-right-sidebar-tab-types-and-navigation/alternatives-considered: + en: 91fbca006e8de5bc + zh: f48d3ce1dd7b63bf +/agent-note-right-sidebar-tab-types-and-navigation/consequences: + en: 3cdb1159ee55d851 + zh: dcd068005e678a89 +/agent-note-right-sidebar-tab-types-and-navigation/testing: + en: 49449a6c8465c098 + zh: 1f476cc1226aa9cd +/agent-note-right-sidebar-tab-types-and-navigation/deferred: + en: fa27b7684e38329b + zh: d270e0cdcab73732 diff --git a/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.i18n.yaml index f44cffc1fa..561af11c1a 100644 --- a/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.i18n.yaml @@ -1,6 +1,52 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-workspace-files-service.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-05-workspace-files-service.md -2026-09-05-workspace-files-service.md: 65bebf18175d9a94452c92cd36ada3c5ef267ce5 -2026-09-05-workspace-files-service.zh.md: b4ca420042dc702f9bc1eaf5bb09f2667a19322d +/agent-note-workspace-file-service: + en: 4f48d3f949d8e3eb + zh: 4060f4e66c36439e +/agent-note-workspace-file-service/problem: + en: 55d969715a48c9b3 + zh: 755dab7523cd01c2 +/agent-note-workspace-file-service/decision: + en: 6ab2a1f635cfc87c + zh: 369e3ed9b6cdc159 +/agent-note-workspace-file-service/decision/package-topology: + en: 59c3648960630ff8 + zh: 1891f8659e660e45 +/agent-note-workspace-file-service/decision/the-workspacefiles-file-operations: + en: efdecd9cf80c03e7 + zh: 5ea40e48ab0559a2 +/agent-note-workspace-file-service/decision/paths-on-the-wire: + en: 7b5a96adc08177bc + zh: ae4692e5e62e7de0 +/agent-note-workspace-file-service/decision/file-checks-and-workspace-containment: + en: 1b588f346590a0fd + zh: 1cdac02b967b157f +/agent-note-workspace-file-service/decision/failures: + en: 0e419dd7bdcf38ba + zh: 6cb588a77593913c +/agent-note-workspace-file-service/decision/configuration: + en: 796ee295af0895bd + zh: 4dfa113ed19f5f9a +/agent-note-workspace-file-service/decision/the-readbyterange-seam-in-dsh-fs: + en: 24d84843c56a012a + zh: 058f959527589302 +/agent-note-workspace-file-service/decision/the-client-file-provider: + en: 0d42d4716dde706f + zh: 4e95b8af2df232b6 +/agent-note-workspace-file-service/decision/related-notes: + en: 6e8cfa03b5222af6 + zh: efdf8f17757fc378 +/agent-note-workspace-file-service/alternatives-considered: + en: 3d598eb6d03d05e5 + zh: 7dac0b7af471a651 +/agent-note-workspace-file-service/consequences: + en: 246bb7aed62f6c9b + zh: debf6d4129ee477b +/agent-note-workspace-file-service/testing: + en: 776c380b6150065e + zh: df3f0f1050966ff7 +/agent-note-workspace-file-service/deferred: + en: b033218338ca0122 + zh: aa48fa67f9eb36c3 diff --git a/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.md b/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.md index 65bebf1817..7deb0dac14 100644 --- a/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.md +++ b/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.md @@ -41,7 +41,7 @@ Every Host method takes `WorkspaceFileScope` first. The `workspaceFileScope` Gat - **`read`** returns one window of lines, `WorkspaceFileText = WorkspaceFileStat & { offset, text, lines, eof }`; `lines` counts the page's lines, so a page holding one empty line (`text: ''`, `lines: 1`) and a page past the end (`lines: 0`) read differently. `range.offset` is the 1-based first line and defaults to 1; `range.limit` is the largest number of lines and defaults to `maxLines`, which it may not exceed. Lines end at `\n` and a final `\n` terminates the last line rather than opening an empty one; `text` joins the page's lines with `\n` and carries no terminator; `eof` is true when the page includes the last line, and an offset past the end returns an empty page with `eof` true. The pager walks `streamText`, counts the lines before the window without keeping them, admits each in-window segment against `maxBytes` before buffering it, and returns at the first character past the window, so a file of any size costs one page of memory. The `version` and `bytes` on a page are the stat's, taken before the stream. - **`readBytes`** returns native bytes with file metadata, offset, and EOF. The required options object selects a complete read under `maxFileBytes` when `range` is absent, or a bounded window under `maxBytes` when present. `range: {}` uses offset zero and the configured window cap; windows can read files above the complete-file cap. The [binary transfer decision](2026-09-17-workspace-file-binary-transfer.md) owns the Remote response encoding. - **`baseFile`** selects target resolution independently of `range`: the target `path` must be relative and resolves from the base file's directory. The Host applies regular-file checks to both files and preserves backend read authority. [Document Preview](2026-09-08-document-preview-operations.md) owns content loading and address semantics. -- **`list`** returns `WorkspaceDirectoryListing { path, entries, truncated }`: the listed directory as a workspace path relative to the root (empty for the root), its direct children in the backend's stable name order as `{ name, type, size? }`, and whether `maxEntries` cut the list. `type` is `file`, `directory`, or `other`; a symlink child reports the type of what it points to and a dangling one is `other`, while opening such a child still fails the link gate below. Dotfiles are listed; nothing is filtered. +- **`list`** returns `WorkspaceDirectoryListing { path, entries, truncated }`: the listed directory as a workspace path relative to the root (empty for the root), its direct children in the backend's stable name order as `{ name, type, size? }`, and whether `maxEntries` cut the list. `type` is `file`, `directory`, or `other`; a symlink child reports the type of what it points to and a dangling one is `other`. A child the listing reports as a directory opens through its resolved target, including a Windows junction, and the listing then names that target; [directory link listing](../bug-fix/2026-09-18-windows-directory-junction-listing.md) owns the rule. Dotfiles are listed; nothing is filtered. - **`changes`** yields `WorkspaceFileWatchFrame`: `{ kind: 'ready' }` after the observation queue is registered and the workspace root resolves, followed by `{ kind: 'change', change }`. The `WorkspaceFileChange` payload is `{ absolutePath, version }` for a present file or `{ absolutePath, absent: true }` for one observed gone. Its source is `fs/observed` inside the workspace root, never an OS watcher. Observations after the first pull are queued, including during root resolution; cancellation or plugin disposal ends the generation. ### Paths on the wire @@ -54,12 +54,12 @@ Two path vocabularies leave the service, and each method uses exactly one. `read `read`, `readBytes`, and `stat` share regular-file checks and then rely on the filesystem backend's read authority. `list` shares path inspection but also checks workspace containment, while `changes` filters observations to the workspace root. The service applies the following checks: -1. **The path itself.** `lstat` inspects the path before anything follows it: a missing path is `not-found`, and a symlink — wherever it points, including back inside the workspace — is `not-regular-file` (kind `symlink`) for the file methods and `not-directory` for `list`. An empty path is a `gateway/bad-request`. +1. **The path itself.** `lstat` inspects the path before anything follows it: a missing path is `not-found`, and a symlink — wherever it points, including back inside the workspace — is `not-regular-file` (kind `symlink`) for the file methods. `list` instead follows a final link and judges the resolved target: the target must stat as a directory, and a link to a file or a link whose target is gone is `not-directory` (kind `symlink`). An empty path is a `gateway/bad-request`. 2. **Workspace containment for `list`.** The directory resolves to a target and `ctx.fs.contains(root, target)` decides, where `root` is the `WorkspaceFileScope.workspaceRoot` resolved from the selected Session header. A `..` traversal or an absolute directory outside the root is `outside-workspace`. `changes` applies the same backend containment predicate to observed targets. 3. **The caps.** A page or window above `maxBytes`, or a `read` asking for more than `maxLines`, is refused, never shortened, because a silently cut page reads as the whole page; a listing above `maxEntries` is cut and says so. Complete and related-file reads are refused above `maxFileBytes`. 4. **Text.** For `read` only: content that is not UTF-8 up to the end of the page, a NUL byte in the backend's 8 KiB opening sample, or a NUL byte anywhere in the page is `not-text`; bytes past the page are not inspected. -After path inspection the file methods `stat` the resolved target once more, because the file may have gone or changed kind before the read: a vanished file is `not-found` and a replaced one `not-regular-file` with the new kind. For `list`, an outside entry whose type already disqualifies it reports its kind before its position. +After path inspection the file methods `stat` the resolved target once more, because the file may have gone or changed kind before the read: a vanished file is `not-found` and a replaced one `not-regular-file` with the new kind. For `list`, an outside entry whose type already disqualifies it reports its kind before its position; a final link resolves and passes containment before its target kind is read. ### Failures @@ -140,7 +140,7 @@ The [resource model](2026-09-05-client-resource-model.md) owns `ctx.resources`, ## Testing -Host specs in `packages/api/workspace-files/tests` exercise header-only scope resolution for live and cold subagent Sessions, the deployment fallback, missing identities, and lookup disposal; the paged read (whole file, nested path, empty file, multi-byte UTF-8, the line window's edges, defaults and refused limits, carriage returns kept); the byte window (defaults, a middle window with more following, tail windows exact and short, past-end and empty files, NUL and invalid UTF-8 round-tripping through `Uint8Array`, version parity with `stat`, the cap as `too-large`, bad ranges, a window of a file far above the cap, and `eof` inferred without a size); `stat`; outside-workspace reads and backend refusals; `list` with containment, truncation, symlink children, and `not-directory`; and the `changes` stream driven by `fs/observed` and filtered by root. Client specs cover the provider's frames, the change feed, unsupported addresses, and registration and disposal. `fs/fs` and `fs-local` specs pin `readByteRange`; `dsh-util-workspace-path` specs pin the file-address grammar. The connection fixture serves `stat`, paged `read`, `list`, and an opt-in `changes` frame for the web e2e suite. +Host specs in `packages/api/workspace-files/tests` exercise header-only scope resolution for live and cold subagent Sessions, the deployment fallback, missing identities, and lookup disposal; the paged read (whole file, nested path, empty file, multi-byte UTF-8, the line window's edges, defaults and refused limits, carriage returns kept); the byte window (defaults, a middle window with more following, tail windows exact and short, past-end and empty files, NUL and invalid UTF-8 round-tripping through `Uint8Array`, version parity with `stat`, the cap as `too-large`, bad ranges, a window of a file far above the cap, and `eof` inferred without a size); `stat`; outside-workspace reads and backend refusals; `list` with containment, truncation, directory links, links whose target is gone, and `not-directory`; and the `changes` stream driven by `fs/observed` and filtered by root. Client specs cover the provider's frames, the change feed, unsupported addresses, and registration and disposal. `fs/fs` and `fs-local` specs pin `readByteRange`; `dsh-util-workspace-path` specs pin the file-address grammar. The connection fixture serves `stat`, paged `read`, `list`, and an opt-in `changes` frame for the web e2e suite. ## Deferred diff --git a/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.zh.md b/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.zh.md index b4ca420042..fe1dd00000 100644 --- a/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-05-workspace-files-service.zh.md @@ -41,7 +41,7 @@ Web 客户端需要从一个未必在 Host 机器上的浏览器查看会话工 - **`read`** 返回一个行窗口 `WorkspaceFileText = WorkspaceFileStat & { offset, text, lines, eof }`;`lines` 计页内行数,使只含一个空行的页(`text: ''`、`lines: 1`)与越过文件末尾的页(`lines: 0`)可区分。`range.offset` 是 1 起算的首行,缺省 1;`range.limit` 是最多行数,缺省 `maxLines` 且不得超过。行以 `\n` 结束,末尾的 `\n` 终止最后一行而不是开启一空行;`text` 以 `\n` 连接本页各行且不带终止符;页含最后一行时 `eof` 为 true,越过末尾的 offset 返回 `eof` 为 true 的空页。切页器沿 `streamText` 前进,数过窗口前的行而不保留,把每个窗内片段先按 `maxBytes` 核准再缓冲,并在越过窗口的第一个字符处返回,因此任意大小的文件只花一页内存。页上的 `version` 与 `bytes` 来自流之前的那次 stat。 - **`readBytes`** 返回原生字节、文件元数据、偏移量和 EOF。必填选项对象未传 `range` 时,在 `maxFileBytes` 上限内完整读取;传入时,在 `maxBytes` 上限内读取有界窗口。`range: {}` 使用零偏移和配置的窗口上限;窗口可读取超过完整文件上限的文件。[二进制传输决议](2026-09-17-workspace-file-binary-transfer.zh.md)负责 Remote 响应编码。 - **`baseFile`** 独立于 `range` 选择目标解析方式:目标 `path` 必须为相对路径,从基准文件所在目录解析。Host 对两个文件执行普通文件检查,并保留后端读取权限。[Document Preview](2026-09-08-document-preview-operations.zh.md)负责内容加载与地址语义。 -- **`list`** 返回 `WorkspaceDirectoryListing { path, entries, truncated }`:被列目录相对根的工作区路径(根为空串)、其直接子项按后端的稳定名序以 `{ name, type, size? }` 给出,以及 `maxEntries` 是否截断了列表。`type` 为 `file`、`directory` 或 `other`;符号链接子项报告其指向目标的类型,悬空者为 `other`,而打开这样的子项仍会在下文的链接关被拒。dotfile 照常列出,不做任何过滤。 +- **`list`** 返回 `WorkspaceDirectoryListing { path, entries, truncated }`:被列目录相对根的工作区路径(根为空串)、其直接子项按后端的稳定名序以 `{ name, type, size? }` 给出,以及 `maxEntries` 是否截断了列表。`type` 为 `file`、`directory` 或 `other`;符号链接子项报告其指向目标的类型,悬空者为 `other`。列表报告为目录的子项经其解析目标打开,Windows 目录联接亦然,此时列表以该目标命名;[目录链接列举](../bug-fix/2026-09-18-windows-directory-junction-listing.zh.md)拥有该规则。dotfile 照常列出,不做任何过滤。 - **`changes`** 产出 `WorkspaceFileWatchFrame`:在观察队列注册且工作区根解析完成后先发 `{ kind: 'ready' }`,随后为 `{ kind: 'change', change }`。载荷 `WorkspaceFileChange` 对存在的文件为 `{ absolutePath, version }`,对消失的文件为 `{ absolutePath, absent: true }`。来源是工作区根内的 `fs/observed`,不监视操作系统。首次拉取后的观察都会排队,包括根解析期间的观察;取消或插件释放会结束该代流。 ### 线路上的路径 @@ -54,12 +54,12 @@ Web 客户端需要从一个未必在 Host 机器上的浏览器查看会话工 `read`、`readBytes` 与 `stat` 共享普通文件检查,之后依赖文件系统后端的读取权限。`list` 共享路径检查,但还会检查工作区包含关系;`changes` 则把观察过滤到工作区根内。服务执行以下检查: -1. **路径本身。** `lstat` 在跟随任何东西之前检查路径:缺失路径为 `not-found`;符号链接——不论指向哪里,包括指回工作区内——对文件方法为 `not-regular-file`(kind 为 `symlink`),对 `list` 为 `not-directory`。空路径是 `gateway/bad-request`。 +1. **路径本身。** `lstat` 在跟随任何东西之前检查路径:缺失路径为 `not-found`;符号链接——不论指向哪里,包括指回工作区内——对文件方法为 `not-regular-file`(kind 为 `symlink`)。`list` 改为跟随末端链接并判定解析后的目标:目标经 stat 必须为目录,指向文件的链接或目标已消失的链接为 `not-directory`(kind 为 `symlink`)。空路径是 `gateway/bad-request`。 2. **`list` 的工作区包含。** 目录解析为目标,由 `ctx.fs.contains(root, target)` 判定,其中 `root` 是从所选 Session header 解析出的 `WorkspaceFileScope.workspaceRoot`。`..` 爬出或根外绝对目录为 `outside-workspace`。`changes` 对观察到的目标使用相同的后端包含判定。 3. **上限。** 超过 `maxBytes` 的页或窗口,或 `read` 索要超过 `maxLines` 的行数,一律拒绝、绝不截短,因为悄悄截短的页读起来就像整页;超过 `maxEntries` 的列表被截断并如实报告。全文及关联文件读取超过 `maxFileBytes` 时被拒绝。 4. **文本。** 仅限 `read`:到页末为止不是 UTF-8 的内容、后端 8 KiB 开头样本里的 NUL 字节,或页内任何位置的 NUL 字节,都是 `not-text`;页之后的字节不检查。 -路径检查之后,文件方法再对解析出的目标 `stat` 一次,因为文件可能在读取前已消失或换了种类:消失者为 `not-found`,被替换者为带新种类的 `not-regular-file`。对 `list` 而言,根外条目若类型本身已不合格,会先报告其种类而不是位置。 +路径检查之后,文件方法再对解析出的目标 `stat` 一次,因为文件可能在读取前已消失或换了种类:消失者为 `not-found`,被替换者为带新种类的 `not-regular-file`。对 `list` 而言,根外条目若类型本身已不合格,会先报告其种类而不是位置;末端链接先解析并通过包含检查,再读取其目标种类。 ### 失败 @@ -140,7 +140,7 @@ Client 导出向 `ctx.resources` 注册一个 `ResourceProvider<'file'>`,存 ## Testing -`packages/api/workspace-files/tests` 中的 Host spec 覆盖 live 与 cold subagent Session 的 header-only scope 解析、部署 fallback、缺失身份与 lookup 释放;分页读取(整文件、嵌套路径、空文件、多字节 UTF-8、行窗口边界、缺省与拒绝的 limit、保留回车);字节窗口(缺省、中段与尾窗、越界与空文件、`Uint8Array` 往返、版本、上限、坏范围以及无大小时的 `eof`);`stat`;工作区外读取及后端拒绝;`list` 的包含、截断、符号链接与 `not-directory`;以及由 `fs/observed` 驱动并按根过滤的 `changes`。Client spec 覆盖提供者帧、变更流、不支持地址及注册与释放。`fs/fs` 与 `fs-local` spec 钉住 `readByteRange`;`dsh-util-workspace-path` spec 钉住文件地址语法。connection fixture 为 web e2e 套件提供 `stat`、分页 `read`、`list` 与一帧可选启用的 `changes`。 +`packages/api/workspace-files/tests` 中的 Host spec 覆盖 live 与 cold subagent Session 的 header-only scope 解析、部署 fallback、缺失身份与 lookup 释放;分页读取(整文件、嵌套路径、空文件、多字节 UTF-8、行窗口边界、缺省与拒绝的 limit、保留回车);字节窗口(缺省、中段与尾窗、越界与空文件、`Uint8Array` 往返、版本、上限、坏范围以及无大小时的 `eof`);`stat`;工作区外读取及后端拒绝;`list` 的包含、截断、目录链接、目标已消失的链接与 `not-directory`;以及由 `fs/observed` 驱动并按根过滤的 `changes`。Client spec 覆盖提供者帧、变更流、不支持地址及注册与释放。`fs/fs` 与 `fs-local` spec 钉住 `readByteRange`;`dsh-util-workspace-path` spec 钉住文件地址语法。connection fixture 为 web e2e 套件提供 `stat`、分页 `read`、`list` 与一帧可选启用的 `changes`。 ## Deferred diff --git a/.agents/notes/implemented/architecture/2026-09-06-embedded-stream-record-readers.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-06-embedded-stream-record-readers.i18n.yaml index f19cf66c4d..f95de9ad8f 100644 --- a/.agents/notes/implemented/architecture/2026-09-06-embedded-stream-record-readers.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-06-embedded-stream-record-readers.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-embedded-stream-record-readers.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-06-embedded-stream-record-readers.md -2026-09-06-embedded-stream-record-readers.md: efad86a4f940bf3b56d4b141a8fe1e3659c8dd9c -2026-09-06-embedded-stream-record-readers.zh.md: f7131a27171163954bca8b7013dc6d90f907c552 +/agent-note-embedded-assistant-stream-consumers-read-compact-records: + en: ddc3fed8aa76c1b8 + zh: 409dcb67ef28080e +/agent-note-embedded-assistant-stream-consumers-read-compact-records/problem: + en: 34ceceb99e246ae6 + zh: 0a18314b78557205 +/agent-note-embedded-assistant-stream-consumers-read-compact-records/decision: + en: ad50509c41a7dacf + zh: c8170641203a3184 +/agent-note-embedded-assistant-stream-consumers-read-compact-records/decision/measurements: + en: 2eedf644fa07e35a + zh: cb691c75fbeda518 +/agent-note-embedded-assistant-stream-consumers-read-compact-records/alternatives-considered: + en: 66b6007d582f7521 + zh: a33aa19f7c912fa2 +/agent-note-embedded-assistant-stream-consumers-read-compact-records/consequences: + en: 05cf037a97b4254d + zh: 1a45fae2447678c2 diff --git a/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.i18n.yaml index e834c8bf6f..85d812f262 100644 --- a/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-v3-canonical-session-envelopes.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-06-v3-canonical-session-envelopes.md -2026-09-06-v3-canonical-session-envelopes.md: 68d4386b9e06025fd44d6d9054a95fb51ec8bc3e -2026-09-06-v3-canonical-session-envelopes.zh.md: d3bfc17fa263f8edb0b6f73ce59c626d772dbc1e +/agent-note-canonical-v3-session-event-envelopes: + en: 17b0c507058d0bba + zh: cc281197005d02c8 +/agent-note-canonical-v3-session-event-envelopes/problem: + en: 60cc4d9e1122118f + zh: c1e8d767dc1999e8 +/agent-note-canonical-v3-session-event-envelopes/decision: + en: f75747b415bfd13b + zh: 18e5e35853e4b506 +/agent-note-canonical-v3-session-event-envelopes/decision/validation-ownership: + en: 6fb18468df0b93e1 + zh: 8dd4dd58a883884f +/agent-note-canonical-v3-session-event-envelopes/decision/released-v2-to-v3-conversion: + en: 1f76511cc4c2fcfd + zh: 77633f9860f14d9d +/agent-note-canonical-v3-session-event-envelopes/alternatives-considered: + en: 08c196bc596a0b2a + zh: 55bbbec345e9a078 +/agent-note-canonical-v3-session-event-envelopes/consequences: + en: 9e88dd3830fb0522 + zh: 8be0d8bde8d0d9d2 +/agent-note-canonical-v3-session-event-envelopes/verification: + en: 31ec0b1095035042 + zh: 05d9f08138da1136 diff --git a/.agents/notes/implemented/architecture/2026-09-07-prebuilt-system-primitives.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-07-prebuilt-system-primitives.i18n.yaml index c11c54f6a9..8a100c6c1a 100644 --- a/.agents/notes/implemented/architecture/2026-09-07-prebuilt-system-primitives.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-07-prebuilt-system-primitives.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-prebuilt-system-primitives.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-07-prebuilt-system-primitives.md -2026-09-07-prebuilt-system-primitives.md: 183cd3ea984cd779417493f0de17a770f38fc001 -2026-09-07-prebuilt-system-primitives.zh.md: f051bba92910086601aa48a877f360e276df524d +/agent-note-prebuilt-system-primitives: + en: eb306b6649dcf8a0 + zh: eab9d3d896e40603 +/agent-note-prebuilt-system-primitives/problem: + en: 1d7458b11272d21a + zh: 534ac9709711f964 +/agent-note-prebuilt-system-primitives/decision: + en: 80093fd5aae0005f + zh: 56f9aa9549c03e7c +/agent-note-prebuilt-system-primitives/alternatives-considered: + en: 8dc5c0319fe6c7eb + zh: 26722ae58a788d0b +/agent-note-prebuilt-system-primitives/consequences: + en: cd0a9aa852ac178b + zh: 6f5376d64625da88 diff --git a/.agents/notes/implemented/architecture/2026-09-07-sidebar-responsive-tab-info.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-07-sidebar-responsive-tab-info.i18n.yaml index 3a61bfea9c..dd4a23fe04 100644 --- a/.agents/notes/implemented/architecture/2026-09-07-sidebar-responsive-tab-info.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-07-sidebar-responsive-tab-info.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-sidebar-responsive-tab-info.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-07-sidebar-responsive-tab-info.md -2026-09-07-sidebar-responsive-tab-info.md: 96f7f047d00a33d6cd48b026ce7762929720d9d6 -2026-09-07-sidebar-responsive-tab-info.zh.md: f020068e71777272fd15a967de547ce153884402 +/agent-note-responsive-sidebar-and-injected-tab-information: + en: 63ced560202cf1a3 + zh: 1ec49cd5ae68f909 +/agent-note-responsive-sidebar-and-injected-tab-information/problem: + en: f9824b1d6f93d329 + zh: 36bc474f646a1a25 +/agent-note-responsive-sidebar-and-injected-tab-information/decision: + en: 1a055f79cb0afcde + zh: 78467751791d42d1 +/agent-note-responsive-sidebar-and-injected-tab-information/alternatives-considered: + en: c05a3ca9a201f01a + zh: b1b30e134a92c8ed +/agent-note-responsive-sidebar-and-injected-tab-information/consequences: + en: 852e827be572c626 + zh: 125ac90be15a5187 diff --git a/.agents/notes/implemented/architecture/2026-09-07-workspace-files-dual-face-package.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-07-workspace-files-dual-face-package.i18n.yaml index 2b1ef7d81a..2d222100c4 100644 --- a/.agents/notes/implemented/architecture/2026-09-07-workspace-files-dual-face-package.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-07-workspace-files-dual-face-package.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-workspace-files-dual-face-package.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-07-workspace-files-dual-face-package.md -2026-09-07-workspace-files-dual-face-package.md: adc900865cb8d5f19518828a9cb230a835d025f5 -2026-09-07-workspace-files-dual-face-package.zh.md: ccfa60417284129a280efd7ddad2ea275c242f1e +/agent-note-workspace-files-as-one-dual-face-api-package: + en: fee20bed1c4f69d2 + zh: 8897bf7430250d46 +/agent-note-workspace-files-as-one-dual-face-api-package/problem: + en: 057ac188f6269740 + zh: 4ed1c2f6c3015efb +/agent-note-workspace-files-as-one-dual-face-api-package/decision: + en: 36fdbb0b44b1bb5e + zh: 87a7a9b45231cf28 +/agent-note-workspace-files-as-one-dual-face-api-package/alternatives-considered: + en: 45a93fced31f5980 + zh: 9283fbda48828416 +/agent-note-workspace-files-as-one-dual-face-api-package/consequences: + en: d4558eea4ac3a00b + zh: e625747fd469f146 +/agent-note-workspace-files-as-one-dual-face-api-package/verification: + en: 4c49a2ec778623e8 + zh: 94eacb1ee8e4d36d diff --git a/.agents/notes/implemented/architecture/2026-09-08-desktop-bundled-runtime-and-external-plugins.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-08-desktop-bundled-runtime-and-external-plugins.i18n.yaml index 552cf1b424..6e302c76a3 100644 --- a/.agents/notes/implemented/architecture/2026-09-08-desktop-bundled-runtime-and-external-plugins.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-08-desktop-bundled-runtime-and-external-plugins.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-desktop-bundled-runtime-and-external-plugins.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-08-desktop-bundled-runtime-and-external-plugins.md -2026-09-08-desktop-bundled-runtime-and-external-plugins.md: 61fa9eafb72133d4cbba1b65193275cc8474f7e5 -2026-09-08-desktop-bundled-runtime-and-external-plugins.zh.md: 8d94d5823526ab4e615dab13f8453c8b6da5d8b6 +/agent-note-bundle-the-desktop-runtime-and-retain-external-plugins: + en: f4c2a14c7f0dbd02 + zh: 5c9b9b68885f3ee0 +/agent-note-bundle-the-desktop-runtime-and-retain-external-plugins/problem: + en: fe97fe6ba33cb23a + zh: c83a1f023c4e352d +/agent-note-bundle-the-desktop-runtime-and-retain-external-plugins/decision: + en: e01df5ba880c2972 + zh: e62074a6a9ba5685 +/agent-note-bundle-the-desktop-runtime-and-retain-external-plugins/package-ownership: + en: 37cae6b28fd359ef + zh: 63118e361fa8f84c +/agent-note-bundle-the-desktop-runtime-and-retain-external-plugins/transactions-and-upgrades: + en: 5bdc450be55832fb + zh: 3312fc9e5497e139 +/agent-note-bundle-the-desktop-runtime-and-retain-external-plugins/alternatives-considered: + en: 1558bba473382cbb + zh: b6a6467866ee254d +/agent-note-bundle-the-desktop-runtime-and-retain-external-plugins/consequences: + en: 6dfa581ec6879c5b + zh: f6c735ad6a00b2b3 diff --git a/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.i18n.yaml index 744cb14c8d..9de126a4e4 100644 --- a/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-desktop-welcome-window-material.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.md -2026-09-08-desktop-welcome-window-material.md: 4ee5f6d2934378b06754c4a8f134a4ca07a80840 -2026-09-08-desktop-welcome-window-material.zh.md: 1689af8481925c787c1d2412173fbd7d8c2f4b64 +/agent-note-desktop-welcome-window-material: + en: a362add86cddc144 + zh: c6f482e5f9a66bdf +/agent-note-desktop-welcome-window-material/problem: + en: 8578b584bda3abdc + zh: 85dcf44aab2cfd51 +/agent-note-desktop-welcome-window-material/decision: + en: df7f9dc0c48769ab + zh: 5e667c736dd58a1c +/agent-note-desktop-welcome-window-material/alternatives-considered: + en: cf42e200b1d0f00a + zh: de96b5647f5ffb23 +/agent-note-desktop-welcome-window-material/consequences: + en: fd2533d63d9a1e4e + zh: 5cb602962608f5de diff --git a/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.md b/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.md index 4ee5f6d293..e3961481f8 100644 --- a/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.md +++ b/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.md @@ -12,7 +12,7 @@ The desktop welcome design blurs the desktop behind its entire window. Chromium The [Electron welcome window](../../../../apps/desktop/src/welcome-window.ts) owns native material and window controls. Its independently bundled React renderer supplies the entry, account sign-in states and API-key form. It shares the `StateDot` loading component with the Web UI without booting the Web plugin graph. The Desktop build emits local JavaScript and CSS under `lib/welcome`, included in packaged applications; the document keeps its network-denying content security policy. A narrow preload supplies typed shell copy, a write-only key operation, and a skip operation; IPC rejects other windows and subframes. Each sandboxed preload is bundled independently because Electron’s restricted require cannot load sibling chunks. The Electron main process authenticates through the shared Web launch URL and resolves the official provider's reference through the existing settings and credential RPC methods. The [thin Web wrapper](2026-09-10-desktop-web-wrapper.md) owns the HTTP server; onboarding adds no Host endpoint or child IPC operation. Responses contain metadata or a safe outcome, never a key or private provider diagnostics. -Cold startup opens the entry when neither an account credential nor a model API key is stored. Saving enters the workspace after persistence succeeds; skipping enters without saving a draft or a completion flag. The next process launch checks the credential store again. The Desktop preload marker suppresses only the Web credential step; settings and the welcome notice remain mounted. Other native shells can set `credentialOnboarding` through the Models Host plugin, which publishes that boolean through the page-injection event before dialogs register. The module graph carries package identities rather than arbitrary Host config, so a Host row alone does not configure its Client half. Startup reads account presence and API-key configuration independently. Account sign-in enters the workspace; sign-out reopens the welcome window only when no model API key remains configured. +Cold startup opens the entry when neither an account credential nor a model API key is configured. Saving enters the workspace after persistence succeeds; skipping enters without saving a draft or a credential-entry completion flag. The next process launch checks credentials again. The Desktop preload marker suppresses the automatic Web credential step and welcome notice; settings and explicit API-key editing remain available. The [Desktop onboarding decision](../feature/2026-09-16-desktop-onboarding.md) owns the separate device-local introduction after account login. Other native shells can disable only the credential step through the Models Host plugin's `credentialOnboarding` page-injection value. The module graph carries package identities rather than arbitrary Host config, so a Host row alone does not configure its Client half. The [account provider](2026-09-14-deepseek-account-login.md) supplies login and sign-out state while preserving independently stored API keys. The generated project follows declared workspace dependencies because pnpm’s hoist index alone can omit configured plugins. @@ -24,7 +24,7 @@ The welcome flow shares the Desktop backend controller with startup recovery. Th **A CSS-only backdrop filter.** It cannot blur other application windows or the desktop, so it cannot provide the required native effect. -**Persisting a completed-onboarding flag.** A skip is valid only for the current process; retaining it would suppress the next cold-start choice while the user still has no credentials. +**Persisting a credential-entry completion flag.** A native credential skip is valid only for the current process; retaining it would suppress the next cold-start choice while the user still has no credentials. The account introduction's separate completion flag does not bypass this authentication decision. **Keeping both native and Web credential dialogs.** Their separate completion state would ask for a key twice after a native skip. The composition assigns credential onboarding to one owner. @@ -34,4 +34,4 @@ The welcome flow shares the Desktop backend controller with startup recovery. Th ## Consequences -Native blur strength and font fallback vary by system. macOS uses menu vibrancy with the onboarding window tint: 40% white in light mode and 50% rgb(24 25 28) in dark mode. Native materials own the blur strength. Windows compositing needs platform QA. Owner-local text expectations cover both pages and locales, and a built-Host acceptance test proves credential persistence across restarts. Account sign-out preserves independently configured API keys. Onboarding presentation produces no Session events. +Native blur strength and font fallback vary by system. The main window uses the shared sidebar vibrancy; full-window onboarding retains a transparent renderer without an additional tint. Windows compositing needs platform QA. Owner-local text expectations cover both pages and locales, and built-Host acceptance covers credential persistence across restarts. Account sign-out preserves independent API keys. Onboarding presentation produces no Session events. diff --git a/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.zh.md b/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.zh.md index 1689af8481..17504368e8 100644 --- a/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-08-desktop-welcome-window-material.zh.md @@ -12,7 +12,7 @@ Status: implemented [Electron 欢迎窗口](../../../../apps/desktop/src/welcome-window.ts)负责原生材质和窗口控件。独立打包的 React 渲染器提供入口、账号登录状态和 API Key 表单。它与 Web UI 共用 `StateDot` 加载组件,不启动 Web 插件图。Desktop 构建将本地 JavaScript 和 CSS 输出到 `lib/welcome`,并纳入应用安装包;文档继续使用禁止网络访问的内容安全策略。窄接口 preload 提供强类型桌面文案、仅写密钥操作和跳过操作;IPC 拒绝其他窗口和子 frame。每个沙箱 preload 都独立打包,因为 Electron 受限的 require 无法加载同目录中的拆分模块。Electron 主进程通过共享 Web 启动 URL 认证,并通过现有设置和凭证 RPC 方法解析官方提供方的引用。[Web 薄壳](2026-09-10-desktop-web-wrapper.zh.md)负责 HTTP 服务;引导不增加 Host 端点或子进程 IPC 操作。响应只包含元数据或安全结果,不包含密钥或提供方的私有诊断。 -冷启动在既无已存账号凭证、也无已配置的模型 API Key 时打开入口。保存会在持久化成功后进入工作区;跳过会直接进入,不保存草稿或完成标记。下次进程启动时会重新检查凭证存储。Desktop preload 标记只抑制 Web 凭证步骤;设置和欢迎须知仍然挂载。其他原生壳可以通过 Models Host 插件设置 `credentialOnboarding`,由页面注入事件在注册弹窗前发布该布尔值。模块图传递的是包标识,而不是任意 Host 配置,因此单独配置 Host 行不会配置其 Client 半部。启动分别读取账号凭证是否存在和 API Key 配置状态。账号登录后进入工作区;退登后仅在没有已配置的模型 API Key 时重新打开欢迎窗口。 +冷启动在账号凭证与模型 API Key 均未配置时打开入口。保存会在持久化成功后进入工作区;跳过会直接进入,不保存草稿或凭证入口完成标记。下次进程启动时会重新检查凭证。Desktop preload 标记抑制自动 Web 凭证步骤和欢迎须知;设置与显式 API Key 编辑仍然可用。[Desktop 引导决策](../feature/2026-09-16-desktop-onboarding.zh.md)负责账号登录后独立的设备本地介绍流程。其他原生壳可以通过 Models Host 插件注入页面的 `credentialOnboarding` 值仅禁用凭证步骤。模块图传递的是包标识,而不是任意 Host 配置,因此单独配置 Host 行不会配置其 Client 半部。[账号提供方](2026-09-14-deepseek-account-login.zh.md)提供登录与退出登录状态,同时保留独立存储的 API Key。 生成的开发项目沿已声明的 workspace 依赖建立链接,因为单独依赖 pnpm 的提升索引会漏掉配置插件。 @@ -24,7 +24,7 @@ Desktop 在打开欢迎窗口前读取共享的 `locale.preference`。Client 在 **仅使用 CSS 背景滤镜。** 它无法模糊其他应用窗口或桌面,因此不能提供所需的原生效果。 -**持久化已完成引导标记。** 跳过只对当前进程有效;保存该标记会在用户仍无凭证时抑制下次冷启动的选择。 +**持久化凭证入口完成标记。** 跳过原生凭证入口只对当前进程有效;保留标记会在用户仍无凭证时抑制下次冷启动选择。账号介绍流程的独立完成标记不会绕过此认证判断。 **同时保留原生与 Web 凭证弹窗。** 两者独立的完成状态会在跳过原生引导后再次要求输入密钥。组合将凭证引导交给单一归属方。 @@ -34,4 +34,4 @@ Desktop 在打开欢迎窗口前读取共享的 `locale.preference`。Client 在 ## 后果 -原生模糊强度和字体回退因系统而异。macOS 使用 menu vibrancy,叠加 onboarding 的窗口背景色:浅色模式为 40% 白色,深色模式为 50% rgb(24 25 28)。模糊强度由原生材质控制。Windows 合成效果需要平台验证。所属目录内的文本预期覆盖两页和两种语言,构建后 Host 的验收测试证明凭证可跨重启持久化。账号退登保留独立配置的 API Key。引导展示不会生成 Session 事件。 +原生模糊强度和字体回退因系统而异。主窗口沿用共享的 sidebar vibrancy;全窗引导保持渲染器透明,不额外叠加底色。Windows 合成效果需要平台验证。所属目录内的文本预期覆盖两页和两种语言,构建后 Host 的验收覆盖凭证跨重启持久化。账号退出登录保留独立的 API Key。引导展示不会生成 Session 事件。 diff --git a/.agents/notes/implemented/architecture/2026-09-08-document-preview-operations.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-08-document-preview-operations.i18n.yaml index 6ccdf5d446..ec7374517f 100644 --- a/.agents/notes/implemented/architecture/2026-09-08-document-preview-operations.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-08-document-preview-operations.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-document-preview-operations.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-08-document-preview-operations.md -2026-09-08-document-preview-operations.md: 220db6db0474f244f902cdeb89b297856243672b -2026-09-08-document-preview-operations.zh.md: 7b838711e5118b8fcc072e4efb753abfc9756b56 +/agent-note-document-preview-and-file-addresses: + en: fffa621b7586f221 + zh: d9c7e9bea55fc11f +/agent-note-document-preview-and-file-addresses/problem: + en: a35075e6babe3f7a + zh: 3a64ac57761e1009 +/agent-note-document-preview-and-file-addresses/decision: + en: d0a2923efefbcfe1 + zh: 34f71d092c0e706b +/agent-note-document-preview-and-file-addresses/alternatives-considered: + en: 8e9616e954df488c + zh: 10801341ec53bbe8 +/agent-note-document-preview-and-file-addresses/consequences: + en: cc810ba19e203ead + zh: 9421857a5eb2abe2 diff --git a/.agents/notes/implemented/architecture/2026-09-08-global-main-panels.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-08-global-main-panels.i18n.yaml index 35d6b7f310..d16bba3786 100644 --- a/.agents/notes/implemented/architecture/2026-09-08-global-main-panels.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-08-global-main-panels.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-global-main-panels.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-08-global-main-panels.md -2026-09-08-global-main-panels.md: 63530a6b498bd8099cf627d82c888846d3d96767 -2026-09-08-global-main-panels.zh.md: 776787c3de3b79ca7948dcf949ac0393f87e7808 +/agent-note-global-main-panels-without-default-ui-additions: + en: df950323f9032f3b + zh: d08172be0c9ca71c +/agent-note-global-main-panels-without-default-ui-additions/problem: + en: da6aa479acac3baf + zh: ed6316ea9953ff99 +/agent-note-global-main-panels-without-default-ui-additions/decision: + en: e732d64ac12c0ac5 + zh: e8ff462ae93bf259 +/agent-note-global-main-panels-without-default-ui-additions/alternatives-considered: + en: 18c8461d961490ee + zh: a26b37ff3aa15bbc +/agent-note-global-main-panels-without-default-ui-additions/consequences: + en: 31db82c87448a292 + zh: 1923a60d2f0845f9 diff --git a/.agents/notes/implemented/architecture/2026-09-09-awaited-agent-creation.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-09-awaited-agent-creation.i18n.yaml index 50f7a2eb8b..a8255aa82a 100644 --- a/.agents/notes/implemented/architecture/2026-09-09-awaited-agent-creation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-09-awaited-agent-creation.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-awaited-agent-creation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-09-awaited-agent-creation.md -2026-09-09-awaited-agent-creation.md: 27353225a8d99d038d5c61b1eea0fa67d9120a55 -2026-09-09-awaited-agent-creation.zh.md: f664e89da0794acd1d2a6c0c8a4820a7056dcac6 +/agent-note-awaited-per-agent-initialization: + en: 982ac05aa02da2f0 + zh: 225f89c994efb1c4 +/agent-note-awaited-per-agent-initialization/problem: + en: 03e6b75365b29406 + zh: cc880a33cf2303d0 +/agent-note-awaited-per-agent-initialization/decision: + en: f1db71d1fdb4388e + zh: 6c5a43a770f4cffd +/agent-note-awaited-per-agent-initialization/alternatives-considered: + en: 466a9ebbb13f68c6 + zh: ab88fb34786d2c2b +/agent-note-awaited-per-agent-initialization/consequences: + en: d8cfe8d88ccacfc8 + zh: 8d2aa21408e6e40e diff --git a/.agents/notes/implemented/architecture/2026-09-09-consumer-owned-startup-strictness.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-09-consumer-owned-startup-strictness.i18n.yaml index bf6ed1340c..51149ea2fb 100644 --- a/.agents/notes/implemented/architecture/2026-09-09-consumer-owned-startup-strictness.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-09-consumer-owned-startup-strictness.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-consumer-owned-startup-strictness.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-09-consumer-owned-startup-strictness.md -2026-09-09-consumer-owned-startup-strictness.md: bbe975e13b251e2e0d18c4e002efbf1d362548f3 -2026-09-09-consumer-owned-startup-strictness.zh.md: 4bd2bfe026a13ccbd46215d2c0165b5a8c5327f7 +/agent-note-consumer-owned-startup-strictness: + en: 52b6747530b4c023 + zh: dc2f8c1f0c300d0a +/agent-note-consumer-owned-startup-strictness/problem: + en: 4548e7fbdbee5b5a + zh: 0078762ea92fa180 +/agent-note-consumer-owned-startup-strictness/decision: + en: eb2b83f5f65c6b6a + zh: b85a9aa4645c9a20 +/agent-note-consumer-owned-startup-strictness/alternatives-considered: + en: 1b67e062213184cd + zh: 91cc8a015de2bfe4 +/agent-note-consumer-owned-startup-strictness/consequences: + en: 283dec1b336c540d + zh: 2ed358079072cfff +/agent-note-consumer-owned-startup-strictness/testing: + en: d8cafae30ea1347b + zh: de47e4e7ba863261 diff --git a/.agents/notes/implemented/architecture/2026-09-09-deprecate-synchronous-session-event-reads.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-09-deprecate-synchronous-session-event-reads.i18n.yaml index 0cae49b087..f52d6e969f 100644 --- a/.agents/notes/implemented/architecture/2026-09-09-deprecate-synchronous-session-event-reads.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-09-deprecate-synchronous-session-event-reads.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-deprecate-synchronous-session-event-reads.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-09-deprecate-synchronous-session-event-reads.md -2026-09-09-deprecate-synchronous-session-event-reads.md: a2a86b0d6500269531ca1088738aaa612076bfb4 -2026-09-09-deprecate-synchronous-session-event-reads.zh.md: 38468708a5323b6ebf94377f3cc8f2c86dc95dde +/agent-note-deprecate-synchronous-reads-of-arbitrary-session-events: + en: c8011fa4e61dea2f + zh: afb60a2e5d39f6dc +/agent-note-deprecate-synchronous-reads-of-arbitrary-session-events/problem: + en: 95224617f6a308be + zh: 1d4187bb1e50efb4 +/agent-note-deprecate-synchronous-reads-of-arbitrary-session-events/decision: + en: 29d7cb4415f01a29 + zh: a414d90693e7150e +/agent-note-deprecate-synchronous-reads-of-arbitrary-session-events/decision/state-needed-after-resume: + en: e393309432e87d21 + zh: e1de0efa07abfdba +/agent-note-deprecate-synchronous-reads-of-arbitrary-session-events/decision/operations-that-require-complete-history: + en: 38653e50be5bd235 + zh: a2e4dead2ad61124 +/agent-note-deprecate-synchronous-reads-of-arbitrary-session-events/alternatives-considered: + en: 82d983c9c1110797 + zh: 2f491c4bb559b4f2 +/agent-note-deprecate-synchronous-reads-of-arbitrary-session-events/consequences: + en: eadd46697f6ad6bf + zh: 38de0e9a72c027e9 +/agent-note-deprecate-synchronous-reads-of-arbitrary-session-events/related-decisions: + en: 037813a1627520ee + zh: b0f7a75ab4c26bff diff --git a/.agents/notes/implemented/architecture/2026-09-09-desktop-build-release-validation.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-09-desktop-build-release-validation.i18n.yaml index c41d31830d..2516370b2e 100644 --- a/.agents/notes/implemented/architecture/2026-09-09-desktop-build-release-validation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-09-desktop-build-release-validation.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-desktop-build-release-validation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-09-desktop-build-release-validation.md -2026-09-09-desktop-build-release-validation.md: 23aeeaa98d2647f8b9f54e94ea2aedaa82b19e55 -2026-09-09-desktop-build-release-validation.zh.md: 266bca5bbd593907c9a8fadd43050113ede94100 +/agent-note-verify-desktop-release-compatibility-during-packaging: + en: 4183cb362d89a8fb + zh: ede5e45ba6245b6b +/agent-note-verify-desktop-release-compatibility-during-packaging/problem: + en: ae3f1e31ba929c0e + zh: 1a42684e41531547 +/agent-note-verify-desktop-release-compatibility-during-packaging/decision: + en: 352372f213c43a76 + zh: 54dc9826254e56f2 +/agent-note-verify-desktop-release-compatibility-during-packaging/alternatives-considered: + en: 515cec0d22c8373c + zh: e3a5b3058b6316c2 +/agent-note-verify-desktop-release-compatibility-during-packaging/consequences: + en: 5193e3ce82faa984 + zh: 1bd7a31152e3b71c diff --git a/.agents/notes/implemented/architecture/2026-09-09-desktop-immediate-window-and-direct-start.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-09-desktop-immediate-window-and-direct-start.i18n.yaml index 628396c454..ecc422ab61 100644 --- a/.agents/notes/implemented/architecture/2026-09-09-desktop-immediate-window-and-direct-start.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-09-desktop-immediate-window-and-direct-start.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-desktop-immediate-window-and-direct-start.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-09-desktop-immediate-window-and-direct-start.md -2026-09-09-desktop-immediate-window-and-direct-start.md: e7ccf9b7456213d69795a40d9cd2a8509adfc44e -2026-09-09-desktop-immediate-window-and-direct-start.zh.md: c59cc91f0013293cbaf2c086822085000dd3afd2 +/agent-note-show-the-desktop-window-before-starting-the-host: + en: aed1efe0e21399a1 + zh: dd45a0ed4bfa731e +/agent-note-show-the-desktop-window-before-starting-the-host/problem: + en: bd8f14bc0beaac9e + zh: 20b0521f27ad231f +/agent-note-show-the-desktop-window-before-starting-the-host/decision: + en: 6ac14061a85b3da6 + zh: ec35f11c15b34be8 +/agent-note-show-the-desktop-window-before-starting-the-host/alternatives-considered: + en: 4d476b25f3647e1b + zh: 4a1b0252005c8c22 +/agent-note-show-the-desktop-window-before-starting-the-host/consequences: + en: 98119090f2133d33 + zh: 53ad4539d677ee4e diff --git a/.agents/notes/implemented/architecture/2026-09-09-plugin-management-in-the-web-sidebar.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-09-plugin-management-in-the-web-sidebar.i18n.yaml index 030a4eadb9..6c34e86274 100644 --- a/.agents/notes/implemented/architecture/2026-09-09-plugin-management-in-the-web-sidebar.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-09-plugin-management-in-the-web-sidebar.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-plugin-management-in-the-web-sidebar.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-09-plugin-management-in-the-web-sidebar.md -2026-09-09-plugin-management-in-the-web-sidebar.md: ba359aeefe3883445fd5f3e3dc164262e0613219 -2026-09-09-plugin-management-in-the-web-sidebar.zh.md: 91664deeb422c1dc6c34f826a85f398183128d1c +/agent-note-plugin-management-moves-to-the-web-sidebar: + en: efdb6c8f366dd2c2 + zh: 5c55e2882753d481 +/agent-note-plugin-management-moves-to-the-web-sidebar/problem: + en: b0d11556425397b0 + zh: 00968088bec13102 +/agent-note-plugin-management-moves-to-the-web-sidebar/decision: + en: eb93a33f64907b80 + zh: 4073f2da219ad798 +/agent-note-plugin-management-moves-to-the-web-sidebar/alternatives-considered: + en: e5cea1a5e97884be + zh: d5544ae935a48f0a +/agent-note-plugin-management-moves-to-the-web-sidebar/consequences: + en: 74c0051937f03444 + zh: 256b38ff34549a4d +/agent-note-plugin-management-moves-to-the-web-sidebar/testing: + en: 9d08eb02abc00595 + zh: 56c7d26016f9deec diff --git a/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.i18n.yaml index 1514b7c6d3..7a4ee1cacd 100644 --- a/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-producer-owned-message-sources.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-09-producer-owned-message-sources.md -2026-09-09-producer-owned-message-sources.md: 83f8cb9368b516b7b6fde8717f9e5f8e9d4f7d4e -2026-09-09-producer-owned-message-sources.zh.md: f5cdfc48286f7b92883938c8e316a7751580f52c +/agent-note-producer-owned-message-sources-at-the-v4-edge: + en: 57c1c2cecb09ee0f + zh: 30b6a2c42ce573ca +/agent-note-producer-owned-message-sources-at-the-v4-edge/problem: + en: 4633a3379711846d + zh: aca05b06105b2683 +/agent-note-producer-owned-message-sources-at-the-v4-edge/decision: + en: a6f3c4040206a623 + zh: f44c3343e36cac01 +/agent-note-producer-owned-message-sources-at-the-v4-edge/alternatives-considered: + en: 99e30ba3f8782544 + zh: 3b443115115389f8 +/agent-note-producer-owned-message-sources-at-the-v4-edge/consequences: + en: 18b1b6ccbf1f299b + zh: 1bc741beb049185e diff --git a/.agents/notes/implemented/architecture/2026-09-09-profile-resolution-generations.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-09-profile-resolution-generations.i18n.yaml index 1d1ecb3a28..c1cc88bcdd 100644 --- a/.agents/notes/implemented/architecture/2026-09-09-profile-resolution-generations.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-09-profile-resolution-generations.i18n.yaml @@ -1,6 +1,52 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-profile-resolution-generations.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-09-profile-resolution-generations.md -2026-09-09-profile-resolution-generations.md: 649c6c358fece5557031b4a21f3d3ebdd9dac8f7 -2026-09-09-profile-resolution-generations.zh.md: 4e84cc1f1b763c88b4ae96c4c44ae79de0d4c0d6 +/agent-note-add-immutable-profile-resolution-generations: + en: 6a4338564c01ad91 + zh: 241248cff9bd4cfc +/agent-note-add-immutable-profile-resolution-generations/problem: + en: 8e192c176fe48c4c + zh: adb965d650088eb0 +/agent-note-add-immutable-profile-resolution-generations/decision: + en: a3022a87337058c5 + zh: 1d53a08a25ed6eb3 +/agent-note-add-immutable-profile-resolution-generations/decision/one-selection-algorithm: + en: eae0faee66f97e5e + zh: 6d400543869aa7b3 +/agent-note-add-immutable-profile-resolution-generations/decision/ordinary-and-linked-package-examples: + en: f77ef79e2499a0dc + zh: 4bc28292763a1075 +/agent-note-add-immutable-profile-resolution-generations/decision/source-and-built-module-identity: + en: 53a9e92698ce9a5d + zh: 6124d446e8d4a532 +/agent-note-add-immutable-profile-resolution-generations/decision/immutable-generations: + en: cd4e64bd80f448a2 + zh: 585e1fbd8721ae99 +/agent-note-add-immutable-profile-resolution-generations/decision/shared-esm-and-commonjs-rule: + en: 0e0575a04a081b52 + zh: 94c74334939e6d13 +/agent-note-add-immutable-profile-resolution-generations/decision/active-plugin-list-and-package-metadata: + en: 031404dd5b36d408 + zh: de21e819edffbcf7 +/agent-note-add-immutable-profile-resolution-generations/decision/workers-and-generation-updates: + en: 99308bd758859e02 + zh: 35f1e7719fe80d2e +/agent-note-add-immutable-profile-resolution-generations/decision/additive-package-changes: + en: 718dfa7826783f2a + zh: 21c3d5fdfae9cb99 +/agent-note-add-immutable-profile-resolution-generations/decision/filesystem-and-runtime-carriers: + en: b0607713102a093d + zh: 2de9c33bfaa0e3e2 +/agent-note-add-immutable-profile-resolution-generations/decision/performance-and-verification: + en: bf7bd2f8371f54f3 + zh: 426c3b33af8874b8 +/agent-note-add-immutable-profile-resolution-generations/alternatives-considered: + en: 2426173c58a17a48 + zh: 0423b3700273accd +/agent-note-add-immutable-profile-resolution-generations/verification: + en: fbb17aa8fe62b1e8 + zh: 2ed091fdfd995fc8 +/agent-note-add-immutable-profile-resolution-generations/consequences: + en: 54cae20b2734a07e + zh: caa334f8f7a40452 diff --git a/.agents/notes/implemented/architecture/2026-09-09-workspace-file-read-authority.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-09-workspace-file-read-authority.i18n.yaml index eed28e3666..3d1c6c968a 100644 --- a/.agents/notes/implemented/architecture/2026-09-09-workspace-file-read-authority.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-09-workspace-file-read-authority.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-workspace-file-read-authority.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-09-workspace-file-read-authority.md -2026-09-09-workspace-file-read-authority.md: 140816e8c48a6628133cf9208d5b48545e2e5eaf -2026-09-09-workspace-file-read-authority.zh.md: 75ffee32c40930c459018ab0fde42d5324371ba8 +/agent-note-workspace-file-read-authority: + en: 7ca22246a308d511 + zh: c51c7343db9c8cfa +/agent-note-workspace-file-read-authority/problem: + en: ee5703dcce5d81c5 + zh: 6c1aec04723d211b +/agent-note-workspace-file-read-authority/decision: + en: 92dbdf6087e00f04 + zh: 2c8720a081d492f9 +/agent-note-workspace-file-read-authority/alternatives-considered: + en: 329e575be02d7392 + zh: a78f428b36d40f59 +/agent-note-workspace-file-read-authority/consequences: + en: 5596ccd54a474e24 + zh: d31721c8d39b7fdc diff --git a/.agents/notes/implemented/architecture/2026-09-10-command-identities-and-composer-file-action.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-10-command-identities-and-composer-file-action.i18n.yaml index 5ea95513d9..85ab4e3c03 100644 --- a/.agents/notes/implemented/architecture/2026-09-10-command-identities-and-composer-file-action.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-10-command-identities-and-composer-file-action.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-command-identities-and-composer-file-action.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-10-command-identities-and-composer-file-action.md -2026-09-10-command-identities-and-composer-file-action.md: 696c3486c5e007416da3fd5e7be1d4b41cb5f582 -2026-09-10-command-identities-and-composer-file-action.zh.md: 2ce803bad5d39a6d4f40b665fb4ef7456e987912 +/agent-note-command-identities-and-composer-owned-file-action: + en: 96db2d4653b47858 + zh: b914d79ab95b0e51 +/agent-note-command-identities-and-composer-owned-file-action/problem: + en: ad2c360593eb7a42 + zh: 503a9c31a5eb55e7 +/agent-note-command-identities-and-composer-owned-file-action/decision: + en: c78d13ee6a59c04d + zh: 53fc322d351e437b +/agent-note-command-identities-and-composer-owned-file-action/alternatives-considered: + en: 94ccabd1fe224408 + zh: bfa28806f0218ce8 +/agent-note-command-identities-and-composer-owned-file-action/consequences: + en: 08f25ff5e0d227cf + zh: a26663e5b7d9feeb diff --git a/.agents/notes/implemented/architecture/2026-09-10-compact-tool-details.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-10-compact-tool-details.i18n.yaml index 484c0c2a3b..50d4ce7a3d 100644 --- a/.agents/notes/implemented/architecture/2026-09-10-compact-tool-details.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-10-compact-tool-details.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-compact-tool-details.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-10-compact-tool-details.md -2026-09-10-compact-tool-details.md: 6c1f29c5554c74b01fc2a86c2dee3750a529a6b5 -2026-09-10-compact-tool-details.zh.md: d0822a48f100f9f21ef4706204087fcd1e627da4 +/agent-note-compact-tool-details-from-recorded-results: + en: 7495c26039484440 + zh: d1907caf1f139054 +/agent-note-compact-tool-details-from-recorded-results/problem: + en: e4ce66f2cdb08516 + zh: 3f45374f23fa8f3b +/agent-note-compact-tool-details-from-recorded-results/decision: + en: 668e06f5146a78de + zh: 4af1edf74eb8121c +/agent-note-compact-tool-details-from-recorded-results/alternatives-considered: + en: 1f0bf45e4ecc0bfa + zh: c46b173dc7ee180b +/agent-note-compact-tool-details-from-recorded-results/consequences: + en: e02acb07b752c285 + zh: b29f9a5ad44ff10f diff --git a/.agents/notes/implemented/architecture/2026-09-10-component-factories-and-local-slots.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-10-component-factories-and-local-slots.i18n.yaml index 993f4391a6..ede649c464 100644 --- a/.agents/notes/implemented/architecture/2026-09-10-component-factories-and-local-slots.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-10-component-factories-and-local-slots.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-component-factories-and-local-slots.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-10-component-factories-and-local-slots.md -2026-09-10-component-factories-and-local-slots.md: 801e77644d9d2c80c4a9f3cad263420d1deda163 -2026-09-10-component-factories-and-local-slots.zh.md: 3ccd5f01633a1aa4ae830e1ee41243f5d1b65cc5 +/agent-note-reusable-component-factories-with-local-slots: + en: c59d9a681b69c8e0 + zh: 987e95099a9bbe2a +/agent-note-reusable-component-factories-with-local-slots/problem: + en: ba5734b4b97a73b5 + zh: 29f3fc9b7b88f25a +/agent-note-reusable-component-factories-with-local-slots/decision: + en: 21aa3e44ee63ef30 + zh: dbbed5107b354ff1 +/agent-note-reusable-component-factories-with-local-slots/decision/opposite-registration-directions: + en: cbe40f4b1db77180 + zh: d471b9b15c1180a8 +/agent-note-reusable-component-factories-with-local-slots/decision/definition-and-occurrence-lifecycle: + en: 5b1dbbc3cdadb743 + zh: 8efdfb12b80d305d +/agent-note-reusable-component-factories-with-local-slots/decision/local-slots-and-ordinary-children: + en: 4efed23287a0332e + zh: fa4079f4e47dd3f3 +/agent-note-reusable-component-factories-with-local-slots/decision/first-shipped-use: + en: 39d1d419e793b2d9 + zh: e5aa14bace690f52 +/agent-note-reusable-component-factories-with-local-slots/decision/type-and-runtime-enforcement: + en: dfa80b7d19335a1f + zh: 19fddd013bac8cee +/agent-note-reusable-component-factories-with-local-slots/alternatives-considered: + en: b20072038b089ea9 + zh: 129aa0705c030356 +/agent-note-reusable-component-factories-with-local-slots/consequences: + en: 14271ca39d681ca6 + zh: 76bceb0182164a6d diff --git a/.agents/notes/implemented/architecture/2026-09-10-desktop-web-wrapper.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-10-desktop-web-wrapper.i18n.yaml index 62399c273d..2de0be6d61 100644 --- a/.agents/notes/implemented/architecture/2026-09-10-desktop-web-wrapper.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-10-desktop-web-wrapper.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-desktop-web-wrapper.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-10-desktop-web-wrapper.md -2026-09-10-desktop-web-wrapper.md: 4f43cc650777596c807cf79463edc7a9131db44b -2026-09-10-desktop-web-wrapper.zh.md: bc41b4f8eff1dca7fc3dd9b934dac257a9d10a6b +/agent-note-run-desktop-through-the-shared-web-application: + en: 1803d1966797a555 + zh: 6ab64a673a217d34 +/agent-note-run-desktop-through-the-shared-web-application/problem: + en: 085b445846af76c1 + zh: fdddf72401292bbd +/agent-note-run-desktop-through-the-shared-web-application/decision: + en: 7767ab2839440970 + zh: 9a998e72b728fd17 +/agent-note-run-desktop-through-the-shared-web-application/alternatives-considered: + en: 9c5dfbf9cc788040 + zh: 631f851909dd7234 +/agent-note-run-desktop-through-the-shared-web-application/consequences: + en: 43a80c01a8a95170 + zh: 0d7a2d1d1c676a61 diff --git a/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.i18n.yaml index 6953db3edf..6a7a9b2152 100644 --- a/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-10-image-offload-events.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-image-offload-events.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-10-image-offload-events.md -2026-09-10-image-offload-events.md: e80c4ae17b148d9eb46517b92111a8d768160def -2026-09-10-image-offload-events.zh.md: 2aa2b8b1fbffd117b5d716aba28755a02a155bb8 +/agent-note-durable-image-offload-events: + en: 13b817438040d321 + zh: 490038f3c93551c7 +/agent-note-durable-image-offload-events/problem: + en: 93c2241e0f40fca1 + zh: fe3528cff00e07b3 +/agent-note-durable-image-offload-events/decision: + en: e1cbaf46e6a6a7be + zh: c3640a44c9be69af +/agent-note-durable-image-offload-events/alternatives-considered: + en: f1ab95c3bf1a17f8 + zh: 2708521190143182 +/agent-note-durable-image-offload-events/consequences: + en: 3a9b13af9673349b + zh: 7da10694e24edadc +/agent-note-durable-image-offload-events/testing: + en: 6fa4e40e7666aa68 + zh: e31ffd143463ca15 diff --git a/.agents/notes/implemented/architecture/2026-09-10-public-package-manifest.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-10-public-package-manifest.i18n.yaml index de121c7c16..493f5002ab 100644 --- a/.agents/notes/implemented/architecture/2026-09-10-public-package-manifest.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-10-public-package-manifest.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-public-package-manifest.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-10-public-package-manifest.md -2026-09-10-public-package-manifest.md: 2d35a3ad17c5aa62df4a5eccde351f325936a84f -2026-09-10-public-package-manifest.zh.md: 7dc03e5160b3837ea07e19469b1d8a0a4f64ebe6 +/agent-note-public-package-manifest-fields: + en: 1ea0f036c6d0ba67 + zh: 3e885b6827315f74 +/agent-note-public-package-manifest-fields/problem: + en: e4bafc2b26cae6d2 + zh: f8226b200b627c55 +/agent-note-public-package-manifest-fields/decision: + en: 9351e430c86c51fe + zh: 486496885b77824a +/agent-note-public-package-manifest-fields/alternatives-considered: + en: 656ef2c1e7853d01 + zh: 21c525fda71c6def +/agent-note-public-package-manifest-fields/consequences: + en: 7221805e563eceb2 + zh: d171144ecef841e9 diff --git a/.agents/notes/implemented/architecture/2026-09-10-windows-native-installer-pages.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-10-windows-native-installer-pages.i18n.yaml index 304ebc1404..30d6654c2d 100644 --- a/.agents/notes/implemented/architecture/2026-09-10-windows-native-installer-pages.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-10-windows-native-installer-pages.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-windows-native-installer-pages.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-10-windows-native-installer-pages.md -2026-09-10-windows-native-installer-pages.md: 93aa4839620207447ad85b1027a68fcfdc5d3e2c -2026-09-10-windows-native-installer-pages.zh.md: da28e22f82c6e403696904362bcbe6c8b96881b8 +/agent-note-native-windows-installer-pages: + en: 2170ba78b248756f + zh: 6e5852f4685fbc81 +/agent-note-native-windows-installer-pages/problem: + en: 5d148a332b151928 + zh: a79cdfd0f1556c58 +/agent-note-native-windows-installer-pages/decision: + en: 3357e9aca4862152 + zh: c2fa86534f9c8737 +/agent-note-native-windows-installer-pages/alternatives-considered: + en: a5b1e11a1b30ab99 + zh: 8495f05dc87b831a +/agent-note-native-windows-installer-pages/consequences: + en: 16243ca0777d1ff8 + zh: e35cb7f33a756b47 diff --git a/.agents/notes/implemented/architecture/2026-09-11-desktop-electron-node-runtime.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-11-desktop-electron-node-runtime.i18n.yaml index d8b4bc7ee7..65fd19d68d 100644 --- a/.agents/notes/implemented/architecture/2026-09-11-desktop-electron-node-runtime.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-11-desktop-electron-node-runtime.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-desktop-electron-node-runtime.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-11-desktop-electron-node-runtime.md -2026-09-11-desktop-electron-node-runtime.md: 71516bb930f8eee22c1c6a988b6dab596a53a215 -2026-09-11-desktop-electron-node-runtime.zh.md: 162908392b98ee6a666ca414b602207ad8344937 +/agent-note-use-electron-as-the-desktop-node-runtime: + en: 06290013c52b169d + zh: 5e876829cf708f34 +/agent-note-use-electron-as-the-desktop-node-runtime/problem: + en: 67e580ac6d9298d9 + zh: bb2bd7486090bde4 +/agent-note-use-electron-as-the-desktop-node-runtime/decision: + en: 3cac5d877b18179d + zh: 0376bce7b099e0a6 +/agent-note-use-electron-as-the-desktop-node-runtime/consequences: + en: b407d0ce648beea5 + zh: 7ab329aa1d7a237c +/agent-note-use-electron-as-the-desktop-node-runtime/alternatives-considered: + en: 880e255d56b45345 + zh: 5952d9685c564284 diff --git a/.agents/notes/implemented/architecture/2026-09-11-node-office-kit.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-11-node-office-kit.i18n.yaml index eea688362d..5879ae942a 100644 --- a/.agents/notes/implemented/architecture/2026-09-11-node-office-kit.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-11-node-office-kit.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-node-office-kit.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-11-node-office-kit.md -2026-09-11-node-office-kit.md: 2c95b7e27e059f6aaee21970fb30fca9ba1bb11b -2026-09-11-node-office-kit.zh.md: bec5d6bb59f987f629ebfd81bb753eee121566f3 +/agent-note-node-office-conversion-with-independently-packaged-engines: + en: 04142abd8eef58bc + zh: 1a2fe733f74e88ef +/agent-note-node-office-conversion-with-independently-packaged-engines/problem: + en: ac8ace90fa115f0d + zh: 18b9977031cbadeb +/agent-note-node-office-conversion-with-independently-packaged-engines/decision: + en: 61d2e96b5b3782c5 + zh: 49780b672e681b0e +/agent-note-node-office-conversion-with-independently-packaged-engines/alternatives-considered: + en: 70315a46124cbde7 + zh: ee258ed0ef7effb0 +/agent-note-node-office-conversion-with-independently-packaged-engines/consequences: + en: bb32631217be9743 + zh: 1ea86613ade03732 diff --git a/.agents/notes/implemented/architecture/2026-09-11-plugin-owned-message-projections.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-11-plugin-owned-message-projections.i18n.yaml index 86af0d0570..552e27d0a6 100644 --- a/.agents/notes/implemented/architecture/2026-09-11-plugin-owned-message-projections.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-11-plugin-owned-message-projections.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-plugin-owned-message-projections.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-11-plugin-owned-message-projections.md -2026-09-11-plugin-owned-message-projections.md: 9e1eca92567fc035d48c1c42ad86d371f2542c5b -2026-09-11-plugin-owned-message-projections.zh.md: b26b5d4549294b37665ac933944b7f51ef7a5717 +/agent-note-plugin-owned-message-projections: + en: 534c84d25c21d930 + zh: 30964b3e14ffaeac +/agent-note-plugin-owned-message-projections/problem: + en: bd3ad5505204ec0b + zh: 770b6089c760d99f +/agent-note-plugin-owned-message-projections/decision: + en: 2b33d4a1cfba0f53 + zh: 55347f3ecf234862 +/agent-note-plugin-owned-message-projections/alternatives-considered: + en: c6e4c770739dca68 + zh: 7bfcb3dda06a22a1 +/agent-note-plugin-owned-message-projections/consequences: + en: c2f3ff0b9639bec5 + zh: 357f90d9a3423751 diff --git a/.agents/notes/implemented/architecture/2026-09-11-posix-ssh-runtime.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-11-posix-ssh-runtime.i18n.yaml index d7adb64692..423de99127 100644 --- a/.agents/notes/implemented/architecture/2026-09-11-posix-ssh-runtime.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-11-posix-ssh-runtime.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-posix-ssh-runtime.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-11-posix-ssh-runtime.md -2026-09-11-posix-ssh-runtime.md: d54600faa68524b569f219627537ce250158d9b1 -2026-09-11-posix-ssh-runtime.zh.md: a6b3a84c37b0d7b4438e8c766ef4e010443fe744 +/agent-note-posix-ssh-execution-providers: + en: 416e4093259a80aa + zh: a04797294e6af446 +/agent-note-posix-ssh-execution-providers/problem: + en: f67f6add03a36e85 + zh: 656be288f8b2e1d2 +/agent-note-posix-ssh-execution-providers/decision: + en: b2d1e370d008f0f3 + zh: 3e98919538d3fb78 +/agent-note-posix-ssh-execution-providers/alternatives-considered: + en: 4efffb3edba91689 + zh: 40100a70e5f55a42 +/agent-note-posix-ssh-execution-providers/consequences: + en: f29359ab89feb084 + zh: db7505b8d4a5351a +/agent-note-posix-ssh-execution-providers/verification: + en: 822c7c029a77f3c0 + zh: 4a2eaaf3372cba8b +/agent-note-posix-ssh-execution-providers/deferred-work: + en: f300f112c9a09f7e + zh: b4708a0b7f596420 diff --git a/.agents/notes/implemented/architecture/2026-09-11-sandboxed-node-ptc-runtime.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-11-sandboxed-node-ptc-runtime.i18n.yaml index 6bb50069a8..22c7dbe890 100644 --- a/.agents/notes/implemented/architecture/2026-09-11-sandboxed-node-ptc-runtime.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-11-sandboxed-node-ptc-runtime.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-sandboxed-node-ptc-runtime.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-11-sandboxed-node-ptc-runtime.md -2026-09-11-sandboxed-node-ptc-runtime.md: 7efe06e8a4a48b2c1d4dcb672abc09961f3a2b14 -2026-09-11-sandboxed-node-ptc-runtime.zh.md: 2382b02247ebe6e0c524cd89fa64c8e59cf49797 +/agent-note-sandboxed-node-execution-for-ptc: + en: 0fb682d787b23a30 + zh: a7bdbbe987f53dcb +/agent-note-sandboxed-node-execution-for-ptc/problem: + en: 66ac3d7ce7eb8e15 + zh: abb9d41b71900bbf +/agent-note-sandboxed-node-execution-for-ptc/decision: + en: cf072f53de09faca + zh: 9edd5c4a2bfaae5a +/agent-note-sandboxed-node-execution-for-ptc/decision/resolved-inputs-and-policy: + en: e93df995efab569a + zh: 850daf02d1207028 +/agent-note-sandboxed-node-execution-for-ptc/decision/control-and-lifetime: + en: 2c7a694b04951772 + zh: 133b95b0477b127f +/agent-note-sandboxed-node-execution-for-ptc/decision/resource-limits: + en: b8e87a87cbcc4fa6 + zh: 5613a8d69c84c9f3 +/agent-note-sandboxed-node-execution-for-ptc/alternatives-considered: + en: 8ffcc2b32a2243d7 + zh: 81d48d38947abc76 +/agent-note-sandboxed-node-execution-for-ptc/consequences: + en: c0aa3a23a03ba234 + zh: 257c7d35a17abbea +/agent-note-sandboxed-node-execution-for-ptc/deferred-timeout-design: + en: 455d66252cd23253 + zh: bf3839a13dbaaab5 diff --git a/.agents/notes/implemented/architecture/2026-09-11-subprocess-control-pipe.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-11-subprocess-control-pipe.i18n.yaml index 5e270a8b60..991ebb72c1 100644 --- a/.agents/notes/implemented/architecture/2026-09-11-subprocess-control-pipe.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-11-subprocess-control-pipe.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-subprocess-control-pipe.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-11-subprocess-control-pipe.md -2026-09-11-subprocess-control-pipe.md: 438f840958cb2f7f576b899335602ecff1e8a5ef -2026-09-11-subprocess-control-pipe.zh.md: f4305d279342bb6c91162db5748ed49743d352c6 +/agent-note-subprocess-control-pipe: + en: dca4818e974b5b20 + zh: c4d2bd1dbb65e62e +/agent-note-subprocess-control-pipe/problem: + en: 64028c0449b6699c + zh: 6ad143bac0ce23bf +/agent-note-subprocess-control-pipe/decision: + en: 69dfe0cce4199d64 + zh: 80e2b847f9119372 +/agent-note-subprocess-control-pipe/alternatives-considered: + en: 8c677c2cf3cb15bd + zh: 4fccc1d9da7f041a +/agent-note-subprocess-control-pipe/consequences: + en: b5dd21f7c58f50a5 + zh: 24abcc7136d35211 diff --git a/.agents/notes/implemented/architecture/2026-09-11-windows-directory-installation.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-11-windows-directory-installation.i18n.yaml index 91e716d129..35bfbf6d4b 100644 --- a/.agents/notes/implemented/architecture/2026-09-11-windows-directory-installation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-11-windows-directory-installation.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-windows-directory-installation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-11-windows-directory-installation.md -2026-09-11-windows-directory-installation.md: 8208c6cc4b28de8d1ab947cb8e6afba7bfa4f673 -2026-09-11-windows-directory-installation.zh.md: d337397e8ea654d14cccd0839460763b66a19457 +/agent-note-replace-windows-application-directories-after-staging: + en: 7cdd071dd6ad760f + zh: eb8510c6c09f0068 +/agent-note-replace-windows-application-directories-after-staging/problem: + en: fa0015dca8cd9e85 + zh: a826baa59c0a3bd1 +/agent-note-replace-windows-application-directories-after-staging/decision: + en: 5bec9a233d21bb35 + zh: 50e8ba778b14b48e +/agent-note-replace-windows-application-directories-after-staging/consequences: + en: 3562fbc117967fb3 + zh: 6600b28ea6202f68 +/agent-note-replace-windows-application-directories-after-staging/alternatives-considered: + en: 0971baacd045ddef + zh: c908624104e242f9 +/agent-note-replace-windows-application-directories-after-staging/verification: + en: 650fdccdf35ad9d3 + zh: 6069b9acb5f03878 diff --git a/.agents/notes/implemented/architecture/2026-09-12-browser-use-provider-registration.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-12-browser-use-provider-registration.i18n.yaml index d2e46abf6d..3c86f14974 100644 --- a/.agents/notes/implemented/architecture/2026-09-12-browser-use-provider-registration.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-12-browser-use-provider-registration.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-browser-use-provider-registration.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-12-browser-use-provider-registration.md -2026-09-12-browser-use-provider-registration.md: a0d3cfdbd798dadee6a9514dffdc619d95811c4d -2026-09-12-browser-use-provider-registration.zh.md: b0016b6655292ccb5259adcb5a07decedda2e21e +/agent-note-browser-use-provider-registration-and-session-ownership: + en: 68473a007451cf68 + zh: f7a8281c5a5a2e11 +/agent-note-browser-use-provider-registration-and-session-ownership/problem: + en: b3513236c712132d + zh: df7701029eae9b31 +/agent-note-browser-use-provider-registration-and-session-ownership/decision: + en: ffca30883c040835 + zh: 3bfc6ebae9a1fe55 +/agent-note-browser-use-provider-registration-and-session-ownership/alternatives-considered: + en: 44408473ef24d8f9 + zh: 448ca799d905e9a9 +/agent-note-browser-use-provider-registration-and-session-ownership/consequences: + en: 8eb33d4073f96236 + zh: 42c456f778e36485 diff --git a/.agents/notes/implemented/architecture/2026-09-12-computer-use-provider-registration.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-12-computer-use-provider-registration.i18n.yaml index b3c762547c..5867eb3e2a 100644 --- a/.agents/notes/implemented/architecture/2026-09-12-computer-use-provider-registration.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-12-computer-use-provider-registration.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-computer-use-provider-registration.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-12-computer-use-provider-registration.md -2026-09-12-computer-use-provider-registration.md: 52e51ac9c4f89b6ad730e647280ba3f0c04ea3c9 -2026-09-12-computer-use-provider-registration.zh.md: 2d8802e1d8cb3c5262cbc2ba6185262f949bca01 +/agent-note-computer-use-provider-registration: + en: 7179585d8663cf3c + zh: e0ac002425dfd40b +/agent-note-computer-use-provider-registration/problem: + en: 915ca3edbd83a8fd + zh: 98fe85c63c6b2135 +/agent-note-computer-use-provider-registration/decision: + en: 7166d067e8955c9b + zh: 719263b97c5874e8 +/agent-note-computer-use-provider-registration/alternatives-considered: + en: 12913da00ffb6aa6 + zh: cbb08d075d1b91c0 +/agent-note-computer-use-provider-registration/consequences: + en: eed0c10237bf13b1 + zh: e077a9b42e2d9e71 diff --git a/.agents/notes/implemented/architecture/2026-09-12-ptc-runtime-vocabulary.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-12-ptc-runtime-vocabulary.i18n.yaml index 64a55ac887..ac5f77829d 100644 --- a/.agents/notes/implemented/architecture/2026-09-12-ptc-runtime-vocabulary.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-12-ptc-runtime-vocabulary.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-ptc-runtime-vocabulary.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-12-ptc-runtime-vocabulary.md -2026-09-12-ptc-runtime-vocabulary.md: 86d2132b735166fb0ee7c4a4929d5ca64ba0880a -2026-09-12-ptc-runtime-vocabulary.zh.md: 5951c43b9554a6266d96cc60d99c11e84acc138f +/agent-note-ptc-runtime-vocabulary: + en: 4e585bb88c918c48 + zh: 1ee36889df928e84 +/agent-note-ptc-runtime-vocabulary/problem: + en: 1281bbda56bc41e0 + zh: 719dc99572bd7921 +/agent-note-ptc-runtime-vocabulary/decision: + en: b3ca07cb6a92f358 + zh: f3b763124b483563 +/agent-note-ptc-runtime-vocabulary/alternatives-considered: + en: 38af2c476cc408bc + zh: 9f1ebd14829250e3 +/agent-note-ptc-runtime-vocabulary/consequences: + en: bb68774fb0a4bcc3 + zh: b866e8763b3a4f74 diff --git a/.agents/notes/implemented/architecture/2026-09-13-workflow-ptc-sandbox-reuse.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-13-workflow-ptc-sandbox-reuse.i18n.yaml index dad55cc0ce..46f602667d 100644 --- a/.agents/notes/implemented/architecture/2026-09-13-workflow-ptc-sandbox-reuse.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-13-workflow-ptc-sandbox-reuse.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-13-workflow-ptc-sandbox-reuse.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-13-workflow-ptc-sandbox-reuse.md -2026-09-13-workflow-ptc-sandbox-reuse.md: 9454ffef28e1ab5ba7791a30f4bcd67093a34ba3 -2026-09-13-workflow-ptc-sandbox-reuse.zh.md: c51706065703866520bfcad11beffc02eb1f5551 +/agent-note-reuse-the-ptc-node-sandbox-for-workflows: + en: 6db90d1dcfccd294 + zh: 0b66b16319b023a0 +/agent-note-reuse-the-ptc-node-sandbox-for-workflows/problem: + en: 42235162e945e015 + zh: 4edc5633720cd6cc +/agent-note-reuse-the-ptc-node-sandbox-for-workflows/decision: + en: b55a2a59b8039cdd + zh: fd6bbe987a49266f +/agent-note-reuse-the-ptc-node-sandbox-for-workflows/alternatives-considered: + en: 56d9a25713227146 + zh: 2cd89bf6ccc3b3bd +/agent-note-reuse-the-ptc-node-sandbox-for-workflows/consequences: + en: e650b834a6f6a3f2 + zh: de677719cdd49047 diff --git a/.agents/notes/implemented/architecture/2026-09-14-current-profile-plugin-management.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-14-current-profile-plugin-management.i18n.yaml index 6ec18af290..e9aab02a20 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-current-profile-plugin-management.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-14-current-profile-plugin-management.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-current-profile-plugin-management.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-14-current-profile-plugin-management.md -2026-09-14-current-profile-plugin-management.md: 8d4d4c40f033e490f09ebf8d367e1fb621037a6d -2026-09-14-current-profile-plugin-management.zh.md: a8dce606d00321bd96e643a9ba842581c961d6c1 +/agent-note-current-profile-plugin-management-shares-cli-transactions: + en: 86224d16fc754163 + zh: 1c9948a6f80f2544 +/agent-note-current-profile-plugin-management-shares-cli-transactions/problem: + en: 6bb727a659ba1503 + zh: d2ebf5c8164a807e +/agent-note-current-profile-plugin-management-shares-cli-transactions/decision: + en: 863b4369c39f3933 + zh: 7dd44a91ccaaef8f +/agent-note-current-profile-plugin-management-shares-cli-transactions/alternatives-considered: + en: 30c609de89084351 + zh: 27f2747ad9d9b752 +/agent-note-current-profile-plugin-management-shares-cli-transactions/consequences: + en: a51baa71aa3fe3f4 + zh: 291db9e4ba5723d2 diff --git a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.i18n.yaml index 60eec8a71e..4bef95dc24 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-deepseek-account-login.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.md -2026-09-14-deepseek-account-login.md: 458e020c2000fd3db5ee9806e99d4b653710cb1e -2026-09-14-deepseek-account-login.zh.md: 2fb59009302309a67e2c3ec99050685ba39b4212 +/agent-note-deepseek-account-browser-login: + en: 8328647bcdf8a666 + zh: 445a07c7ec4bcca4 +/agent-note-deepseek-account-browser-login/problem: + en: 67c00444d9dcf06d + zh: ef294910952ba052 +/agent-note-deepseek-account-browser-login/decision: + en: 3b6c781b5374a8af + zh: 2a3fb7c63dfdaf83 +/agent-note-deepseek-account-browser-login/alternatives-considered: + en: 3c2dd2c948ffb51b + zh: d019197df0ee3dcf +/agent-note-deepseek-account-browser-login/consequences: + en: a6eff4a0350e9018 + zh: 2e3200ca089023ab +/agent-note-deepseek-account-browser-login/verification: + en: 881edcb454b941a6 + zh: 7dc5a9b7a066f623 +/agent-note-deepseek-account-browser-login/related: + en: 3efeda0686194f07 + zh: 9c3ddc3b8baf9381 diff --git a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.md b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.md index 458e020c20..70ed73f265 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.md +++ b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.md @@ -4,7 +4,7 @@ Status: implemented English | [中文](2026-09-14-deepseek-account-login.zh.md) -Sign-in captures the initiating UI language per attempt so browser authorization follows the Desktop or Settings locale without depending on the Platform default. +Sign-in captures the initiating UI's client metadata per attempt so browser authorization follows the Desktop or Settings language without depending on the Platform default. ## Problem @@ -20,21 +20,21 @@ Authorization registers a temporary /oauth/callback route on the Host webServer. Platform navigation and authorization share one validated platformOrigin from Cordis configuration. Private profile patches or environment expressions supply deployment-specific origins without committing development addresses. -The Desktop profile supplies the native platform for Host API headers. Account and update-policy clients share one mapping to avoid different client identities for the same installation. This identity does not depend on a login attempt, since stored grants also issue requests after restart. Embedded pages use the same platform identity and retain their other separately configured headers. +Platform client identity belongs to the calling UI rather than to the Host. Every account operation carries the caller's client version, active language, and current UTC offset, and the provider derives the five Platform client headers for that call from them plus the composed native platform. Client identity headers override same-named deployment headers, so one Host shared by several callers reports the UI that made each request instead of the last one it saw, and the update-policy client keeps the same header meanings for the installed shell. PlatformSession deliberately omits caller identity; the embedding client composes its own five headers and limits them to the configured origin. ## Alternatives considered -Putting the protocol in Electron duplicates the implementation for Web consumers and gives the shell credential ownership. Putting tokens in DEEPSEEK_API_KEY loses the distinction between account grants and user API keys. Treating a browser callback as success before persistence admits false success. Waiting for a remote cancel acknowledgment leaves local cancellation dependent on network availability. These alternatives are rejected. +Putting the protocol in Electron duplicates the implementation for Web consumers and gives the shell credential ownership. Putting tokens in DEEPSEEK_API_KEY loses the distinction between account grants and user API keys. Treating a browser callback as success before persistence admits false success. Waiting for a remote cancel acknowledgment leaves local cancellation dependent on network availability. Remembering one client identity in the Host would mislabel every other caller that shares it or reaches it through a forward. These alternatives are rejected. ## Consequences Sign out removes the local grant before starting Platform POST /auth-api/v0/users/logout with the captured token. Remote failure never restores login. The provider retries at most five times after the initial request, with configurable exponential backoff starting at one second by default. Retry jobs retain only their old token, cannot change later login state, and end at provider shutdown without durable storage. Local credential deletion must succeed before publishing signed-out state. Sign out belongs to the sidebar account menu; Account settings owns profile, balance and sign-in. Both read one plugin-owned Host stream through framework hooks. -API keys and account grants remain separately stored. Account tokens have no expiry or refresh flow; exhausted logout retries can leave the removed token valid remotely. Provider initialization discards grants from a different configured Platform issuer locally, without remote revocation, so switching environments starts signed out instead of aborting Desktop startup. API keys and device identity survive this cleanup. Profile and balance query failures preserve login state; authorization-attempt deadlines apply only before token issuance. The same grant authenticates Platform current and get_user_summary queries on its configured issuer origin. Host preserves Platform-masked contact details and drops response tokens; account changes invalidate pending results. UI shows normal_wallets recharge balances and positive bonus_wallets in separate rows, so promotional credit is never presented as recharge funds. +API keys and account grants remain separately stored. Account tokens have no proactive refresh flow; exhausted logout retries can leave the removed token valid remotely. Provider initialization discards grants from a different configured Platform issuer locally, without remote revocation, so switching environments starts signed out instead of aborting Desktop startup. API keys and device identity survive this cleanup. Profile and balance HTTP 401 responses clear the rejected credential; other query failures preserve login state; authorization-attempt deadlines apply only before token issuance. The same grant authenticates Platform current and get_user_summary queries on its configured issuer origin. Host preserves Platform-masked contact details and drops response tokens; account changes invalidate pending results. UI shows normal_wallets recharge balances and positive bonus_wallets in separate rows, so promotional credit is never presented as recharge funds. The account plugin supplies choice, waiting, failure and timeout dialogs through settings.models.sign-in. The model package owns credential readiness and the existing API-key editor; the settings shell coordinates explicit reopening so login and API-key onboarding do not mount competing dialogs. -Platform embedding transfers a grant from Host to Electron over private Node IPC and then once to the trusted Platform main frame through a sandboxed preload. Preload performs one synchronous IPC before page scripts execute; the main process only validates the sender and returns prepared memory. Platform reads the token synchronously thereafter without a readiness API. A failed initialization retains embedded mode and a throwing getter. Account UI projections remain credential-free. The Platform document can read this credential, so its script security is part of account protection; context isolation protects native capabilities, not a token intentionally returned to the document. Replacing or removing the grant destroys the document and its temporary session. +Platform embedding transfers a grant from Host to Electron over private Node IPC and then once to the trusted Platform main frame through a sandboxed preload. Preload performs one synchronous IPC before page scripts execute; the main process only validates the sender and returns prepared memory. Platform reads the token synchronously thereafter without a readiness API. A failed initialization retains embedded mode and a throwing getter. Account UI projections remain credential-free. The Platform document can read this credential, so its script security is part of account protection; context isolation protects native capabilities, not a token intentionally returned to the document. Replacing or removing the grant destroys the document and clears browser authentication; [account-scoped page storage](2026-09-22-platform-browser-storage.md) survives. Support questionnaires receive only available environment metadata through explicit prefill fields. Account UIDs, tokens and masked contact details stay out of questionnaire URLs. @@ -56,6 +56,8 @@ The embedded Platform document stays hidden during loading because native child Separate accountRequestHeaders route account data and embedded Platform traffic independently of authorization and logout. Cookie overrides merge by name, retaining deployment authentication. Host passes the resolved headers over private process IPC; Electron injects them only at the configured origin and omits them from bootstrap. +Bonus notices use Platform-provided text and order identities. Reads occur when an account becomes active — signed-in startup and successful sign-in — and once per Settings entry or return from the top-up view, with no periodic polling. The card is painted as soon as the server offers it, including underneath the open Settings panel, so display is never deferred. The client acknowledges an order after a presented frame or the user closes it; nothing is written to browser storage, so a later sign-in re-displays an order the server still offers. Failed acknowledgments retry with capped exponential backoff for the rest of the signed-in session. Platform acknowledgments suppress delivery on other devices, but concurrent displays before acknowledgment are possible because the API does not reserve delivery. Fetch success alone never records a display. + The Host binds private Platform sessions to the account provider lifetime. Removal or watch termination clears Electron’s session; replacement subscribes to the new provider, and disposed reads cannot publish old credentials. The client distinguishes plugin disposal from terminal account-stream failure. RemoteStream aborts its signal after either outcome, so the plugin owns a separate disposal flag to preserve failure feedback while suppressing reports after unload. diff --git a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.zh.md b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.zh.md index 2fb5900930..5b0df92064 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.zh.md @@ -4,7 +4,7 @@ Status: implemented [English](2026-09-14-deepseek-account-login.md) | 中文 -登录申请保存发起界面的语言,使浏览器授权跟随桌面或设置页的语言,不依赖平台默认值。 +登录申请保存发起界面的客户端元数据,使浏览器授权跟随桌面或设置页的语言,不依赖平台默认值。 ## 问题 @@ -20,21 +20,21 @@ Status: implemented 平台导航与授权共享 Cordis 配置中同一个经过校验的 platformOrigin。私有 profile patch 或环境表达式提供部署来源,开发地址不进入仓库。 -Desktop profile 为 Host API 请求头提供原生平台信息。账号与更新策略客户端共用一份映射,避免同一安装实例发送不同的客户端标识。此标识不依赖登录尝试,因为重启后保存的授权仍会发起请求。内嵌页面使用同一平台标识,并保留独立配置的其他请求头。 +Platform 客户端身份属于发起调用的界面,而不属于 Host。每个账号操作都携带调用方的客户端版本、当前语言和当前 UTC 偏移,provider 据此与组合出的原生平台推导该次调用的五个 Platform 客户端请求头。客户端身份请求头覆盖部署配置中的同名请求头,因此一个被多方共享的 Host 报告的是每次请求的发起界面,而不是它上一次见到的调用方;更新策略客户端对已安装的壳沿用同一组请求头语义。PlatformSession 有意不携带调用方身份;内嵌客户端自行组装同样的五个请求头,并仅在配置来源发送。 ## 替代方案 -把协议放在 Electron 会为 Web 使用方重复实现,并让外壳拥有凭证。把 token 放入 DEEPSEEK_API_KEY 会丢失账号授权与用户 API Key 的区别。在持久化前将浏览器回调视为成功会产生虚假成功。等待远程取消确认会使本地取消依赖网络。这些方案均被拒绝。 +把协议放在 Electron 会为 Web 使用方重复实现,并让外壳拥有凭证。把 token 放入 DEEPSEEK_API_KEY 会丢失账号授权与用户 API Key 的区别。在持久化前将浏览器回调视为成功会产生虚假成功。等待远程取消确认会使本地取消依赖网络。在 Host 中记住一份客户端身份,会让共享该 Host 或经转发接入的其他调用方被标错。这些方案均被拒绝。 ## 影响 退出登录先删除本地授权,再使用捕获的 token 调用 Platform POST /auth-api/v0/users/logout。远程失败不会恢复登录态。首次请求失败后,提供者最多重试五次,使用可配置的指数退避,默认从一秒开始。重试任务只保留旧 token,不改变后续登录态,并在提供者关闭时结束,不持久化。本地凭证删除成功后才发布已退出状态。退出登录位于侧边栏账号菜单;账号设置负责资料、余额和登录。两者通过框架 hook 读取插件持有的同一条 Host 状态流。 -API Key 与账号记录独立保存。账号 token 没有过期或刷新流程;退登重试耗尽后,已从本地删除的 token 在远端仍可能有效。提供者初始化时在本地丢弃与配置的 Platform 来源不同的授权,不调用远端撤销,使环境切换以未登录态启动,而不导致 Desktop 启动失败。API Key 和设备标识保留。资料与余额查询失败保留登录态;授权尝试的有效期仅适用于 token 签发前。同一授权 token 可认证已配置签发来源上的 Platform current 和 get_user_summary 查询。Host 原样保留 Platform 脱敏后的联系方式并丢弃响应 token;账号变化使未完成结果失效。UI 分行显示 normal_wallets 充值余额与正额 bonus_wallets 赠金余额,避免将赠金额度显示为充值资金。 +API Key 与账号记录独立保存。账号 token 没有主动刷新流程;退登重试耗尽后,已从本地删除的 token 在远端仍可能有效。提供者初始化时在本地丢弃与配置的 Platform 来源不同的授权,不调用远端撤销,使环境切换以未登录态启动,而不导致 Desktop 启动失败。API Key 和设备标识保留。资料与余额接口的 HTTP 401 响应清除被拒绝的凭据,其他查询错误保留登录态;授权尝试的有效期仅适用于 token 签发前。同一授权 token 可认证已配置签发来源上的 Platform current 和 get_user_summary 查询。Host 原样保留 Platform 脱敏后的联系方式并丢弃响应 token;账号变化使未完成结果失效。UI 分行显示 normal_wallets 充值余额与正额 bonus_wallets 赠金余额,避免将赠金额度显示为充值资金。 账号插件通过 settings.models.sign-in 提供选择、等待、失败和超时对话框。模型包保留凭证就绪检查和现有 API Key 编辑器;设置外壳协调显式重开,避免登录与 API Key 引导同时挂载冲突的对话框。 -Platform 内嵌通过私有 Node IPC 将授权从 Host 传给 Electron,再经沙箱 preload 一次性传给受信任的 Platform 主 frame。preload 在页面脚本执行前执行一次同步 IPC;主进程仅校验调用来源并返回已准备的内存数据。Platform 此后同步读取 token,无需就绪接口。初始化失败时保留内嵌模式,由 getter 抛错。账号 UI 投影仍不包含凭证。Platform 文档能够读取此凭证,因此其脚本安全也是账号保护的一部分;上下文隔离保护原生能力,不能隐藏有意返回给文档的 token。替换或移除授权会销毁文档及其临时会话。 +Platform 内嵌通过私有 Node IPC 将授权从 Host 传给 Electron,再经沙箱 preload 一次性传给受信任的 Platform 主 frame。preload 在页面脚本执行前执行一次同步 IPC;主进程仅校验调用来源并返回已准备的内存数据。Platform 此后同步读取 token,无需就绪接口。初始化失败时保留内嵌模式,由 getter 抛错。账号 UI 投影仍不包含凭证。Platform 文档能够读取此凭证,因此其脚本安全也是账号保护的一部分;上下文隔离保护原生能力,不能隐藏有意返回给文档的 token。替换或移除授权会销毁文档并清理浏览器认证;[账号范围内的页面存储](2026-09-22-platform-browser-storage.zh.md)会保留。 支持问卷仅通过显式预填字段接收已有的环境信息,URL 不包含账号 UID、token 或脱敏联系方式。 @@ -56,6 +56,8 @@ exchange 的 user 数据在凭证提交后供首次资料读取使用,展示 独立的 accountRequestHeaders 将账号资料及内嵌 Platform 流量与授权、退登分开路由。Cookie 覆盖按名称合并,保留部署认证。Host 通过私有进程 IPC 传递合并后的请求头;Electron 仅在配置来源注入,并从 bootstrap 排除。 +赠金通知使用 Platform 提供的文案和订单标识。账号进入登录态(已登录启动、登录成功)时读取一次,每次进入设置页或从充值视图返回时再读取一次,不进行定时轮询。服务端下发的通知立即绘制,包括在打开的设置面板之下,因此展示从不延后。客户端在通知卡完成一帧绘制后或用户关闭卡片时确认订单。不写入任何浏览器存储,因此之后再次登录会重新展示服务端仍在下发的订单。确认失败会在本次登录会话内按带上限的指数退避重试。Platform 的确认记录阻止其他设备继续获取通知,但接口不预留展示资格,因此确认前仍可能并发展示。仅获取成功不会记录为已展示。 + Host 将私有 Platform 会话绑定到账号提供者的生命周期。提供者移除或订阅结束时清空 Electron 会话;替换后订阅新的提供者,已释放的读取不得发布旧凭据。 客户端区分插件卸载和账户状态流的终止错误。RemoteStream 在两种情况下都会中止其信号,因此插件独立记录卸载状态,保留错误反馈并抑制卸载后的报告。 diff --git a/.agents/notes/implemented/architecture/2026-09-14-independent-libreoffice-kit.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-14-independent-libreoffice-kit.i18n.yaml index c3570fad78..a0da60252b 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-independent-libreoffice-kit.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-14-independent-libreoffice-kit.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-independent-libreoffice-kit.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-14-independent-libreoffice-kit.md -2026-09-14-independent-libreoffice-kit.md: 13efc41e56a4810273fbb6d9314eeda6053dbe92 -2026-09-14-independent-libreoffice-kit.zh.md: 720ca2ba3f57546825ae14b5b5f0b086fbb7f287 +/agent-note-independent-libreoffice-kit-ownership: + en: ee1625b5a309d9e6 + zh: c3e78e1b1aa92fd8 +/agent-note-independent-libreoffice-kit-ownership/problem: + en: 2fc4ac7bdd4a3474 + zh: 21ebdd3ac9264132 +/agent-note-independent-libreoffice-kit-ownership/decision: + en: 31200a9be3940dc0 + zh: 8e22be1d160ec3e4 +/agent-note-independent-libreoffice-kit-ownership/alternatives-considered: + en: 55175bb30630bf0c + zh: 788853ddd5f7a4e9 +/agent-note-independent-libreoffice-kit-ownership/consequences: + en: ace5eeafb4795ab6 + zh: 136489e75455c8e7 diff --git a/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.i18n.yaml index 420bcd267c..76754c3084 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-session-log-upload-default.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.md -2026-09-14-session-log-upload-default.md: c1e7c9e050d1b1809ff3abba03fe4e17a3779daa -2026-09-14-session-log-upload-default.zh.md: d7b6e64098eca3fe07c43272fcba18a3790182e2 +/agent-note-default-deepseek-session-log-upload: + en: fcb31f3679ced0e2 + zh: 0e07b8a08f7e004f +/agent-note-default-deepseek-session-log-upload/problem: + en: f9721b730c7e70c7 + zh: 367e7839912cb726 +/agent-note-default-deepseek-session-log-upload/decision: + en: ec3b05fb70ae490f + zh: 59b0691e327855b4 +/agent-note-default-deepseek-session-log-upload/alternatives-considered: + en: 4cc4b61d76f84ff3 + zh: bdd29ea66037f744 +/agent-note-default-deepseek-session-log-upload/consequences: + en: 31d0c8deb33dbe3f + zh: 8af3905630c629a0 diff --git a/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.md b/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.md index c1e7c9e050..232ab867b1 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.md +++ b/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.md @@ -23,6 +23,6 @@ This supersedes only the opt-in default in the [request-extension decision](2026 ## Consequences -Eligible requests send the complete unaccepted canonical log suffix, including message text, tool arguments and results, workspace paths, and feedback, to the resolved DeepSeek endpoint or configured gateway. No prompt tokens or model-visible content are added. Request bodies can grow substantially, and provider rejection still fails the request. OTel remains independent; disabling OTel does not disable this contribution. +Eligible requests send the unaccepted canonical log suffix, up to `maxBytes` per request under the [bounded-upload decision](2026-09-24-bounded-session-log-upload.md), including message text, tool arguments and results, workspace paths, and feedback, to the resolved DeepSeek endpoint or configured gateway. No prompt tokens or model-visible content are added. Request bodies grow by up to that limit, and provider rejection still fails the request. OTel remains independent; disabling OTel does not disable this contribution. Configuration tests cover default-on and explicit overrides with and without test environment markers. Both DeepSeek protocol Loader cases observe the default request field and recorded acceptance watermark, and explicit-off cases observe their absence. Existing headless, ACP, Web, and SDK recordings validate their declared upload policies without rewriting committed Session generations. diff --git a/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.zh.md b/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.zh.md index d7b6e64098..0fd8210e46 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.zh.md @@ -23,6 +23,6 @@ Status: implemented ## 后果 -符合条件的请求会向解析后的 DeepSeek 端点或已配置网关发送完整的未接受规范日志后缀,包括消息文本、工具参数与结果、工作区路径和反馈。不增加提示词 token 或模型可见内容。请求正文可能显著增大,提供方拒绝仍会使请求失败。OTel 保持独立,关闭 OTel 不会关闭此贡献。 +符合条件的请求会向解析后的 DeepSeek 端点或已配置网关发送未接受的规范日志后缀,按[有上限上传决策](2026-09-24-bounded-session-log-upload.zh.md)每次最多 `maxBytes`,包括消息文本、工具参数与结果、工作区路径和反馈。不增加提示词 token 或模型可见内容。请求正文最多增加该上限,提供方拒绝仍会使请求失败。OTel 保持独立,关闭 OTel 不会关闭此贡献。 配置测试覆盖有无测试环境标记时的默认开启与显式覆盖。两种 DeepSeek 协议的 Loader 用例观察默认请求字段和已记录的接受水位,显式关闭用例观察两者均不存在。现有 headless、ACP、Web 和 SDK 录制验证各自声明的上传策略,无需重写已提交的会话代际。 diff --git a/.agents/notes/implemented/architecture/2026-09-14-sidebar-layout-provider-recovery.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-14-sidebar-layout-provider-recovery.i18n.yaml index 515ead78da..621d099284 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-sidebar-layout-provider-recovery.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-14-sidebar-layout-provider-recovery.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-sidebar-layout-provider-recovery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-14-sidebar-layout-provider-recovery.md -2026-09-14-sidebar-layout-provider-recovery.md: f7ec0324f9205a556750e0af54eb856002a4ea74 -2026-09-14-sidebar-layout-provider-recovery.zh.md: 02440391e5601e3ba125c33c4c8971d4d46cbaa8 +/agent-note-sidebar-layout-persistence-and-provider-recovery: + en: 78dee80210908b7d + zh: 01a490734740a523 +/agent-note-sidebar-layout-persistence-and-provider-recovery/problem: + en: 8adb7105e89be803 + zh: 96c4e92e85b6980e +/agent-note-sidebar-layout-persistence-and-provider-recovery/decision: + en: aa09cb90f663dfe8 + zh: edaabb76aa6dc8de +/agent-note-sidebar-layout-persistence-and-provider-recovery/alternatives-considered: + en: 4a9b1234b0289ae7 + zh: 81854e0e9d32b6da +/agent-note-sidebar-layout-persistence-and-provider-recovery/consequences: + en: 4daf813b59205ca3 + zh: 917c2b975c9a67dd diff --git a/.agents/notes/implemented/architecture/2026-09-14-web-document-relative-app-routes.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-14-web-document-relative-app-routes.i18n.yaml index 8f06bf7290..7d6b05d9fa 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-web-document-relative-app-routes.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-14-web-document-relative-app-routes.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-web-document-relative-app-routes.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-14-web-document-relative-app-routes.md -2026-09-14-web-document-relative-app-routes.md: fbf30253bbfcc23eb09847f93c1b1f047459d31b -2026-09-14-web-document-relative-app-routes.zh.md: c302ec88a4205239148132513d1ff2a4385033e8 +/agent-note-web-app-owned-routes-are-document-relative: + en: c31a8b2eeced1d7a + zh: 718b29b0f1e3f995 +/agent-note-web-app-owned-routes-are-document-relative/problem: + en: ce92162dd5ef0b2a + zh: a487cfd441b9fe1a +/agent-note-web-app-owned-routes-are-document-relative/decision: + en: 5d61f3f037df8f7e + zh: fbea19a5868d45b9 +/agent-note-web-app-owned-routes-are-document-relative/alternatives-considered: + en: 14cd7d83f28ef818 + zh: 5a429ab09dae43e5 +/agent-note-web-app-owned-routes-are-document-relative/consequences: + en: e3601f867e8c1825 + zh: 5c7ba5acb63a98a3 +/agent-note-web-app-owned-routes-are-document-relative/testing: + en: 3845fc2e126b858c + zh: 5a63b358be90e565 diff --git a/.agents/notes/implemented/architecture/2026-09-15-bounded-office-conversion.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-15-bounded-office-conversion.i18n.yaml index 2f64b37f55..a6d52473fa 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-bounded-office-conversion.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-15-bounded-office-conversion.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-bounded-office-conversion.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-15-bounded-office-conversion.md -2026-09-15-bounded-office-conversion.md: b15aa5421c575451ddb4a7bf91169bcb2fa38d3c -2026-09-15-bounded-office-conversion.zh.md: f23c38096764cf32207125cc0c3ebbdf1c04d009 +/agent-note-bounded-shared-office-conversion: + en: 10c171aa2a5ab0c2 + zh: 13e8e134e3a68e98 +/agent-note-bounded-shared-office-conversion/problem: + en: b305613daff5a763 + zh: 1aba13289664f65c +/agent-note-bounded-shared-office-conversion/decision: + en: bcd0780f95f173bf + zh: 2a7f49db2575c59d +/agent-note-bounded-shared-office-conversion/alternatives-considered: + en: 9d5cfb7fa5f66bd6 + zh: 4f4133daa2f02f43 +/agent-note-bounded-shared-office-conversion/consequences: + en: c2800ff56c8f89d1 + zh: 3b3710072b59c443 +/agent-note-bounded-shared-office-conversion/related: + en: 2e7b1a0f01c1f617 + zh: ed2abc0181ea4abe diff --git a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.i18n.yaml index 0a33e19e2c..d2b3a75106 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.i18n.yaml @@ -1,6 +1,49 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-client-session-references.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-15-client-session-references.md -2026-09-15-client-session-references.md: 162ef08875e5b0591b3b4099c9bdcadb18e7d175 -2026-09-15-client-session-references.zh.md: 3af8932f7c002b3b63de21c689ae91e3017a164e +/agent-note-client-session-references-reference-sources-and-ui-status: + en: 720fca3e1f085f8f + zh: 3480eb43eb5f0e44 +/agent-note-client-session-references-reference-sources-and-ui-status/problem: + en: 0f4d2b6e8b0393dc + zh: fe20aca8b4fd0701 +/agent-note-client-session-references-reference-sources-and-ui-status/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-client-session-references-reference-sources-and-ui-status/decision/scope-and-ownership: + en: d9d52caab1468205 + zh: 1b7665610bb025c6 +/agent-note-client-session-references-reference-sources-and-ui-status/decision/addresses-bindings-and-references: + en: 3743abc8bca00348 + zh: d79e6a9311f0a2fe +/agent-note-client-session-references-reference-sources-and-ui-status/decision/acquisition-failure-and-release: + en: 84e9528d4f995460 + zh: f79f197d3dfbe8e9 +/agent-note-client-session-references-reference-sources-and-ui-status/decision/reference-sources-and-session-list-records: + en: e2de83d10542f93b + zh: 3855b38fc8c48ea3 +/agent-note-client-session-references-reference-sources-and-ui-status/decision/unified-ui-session-status: + en: 2d75aef5cf5f1fc8 + zh: 87a7051f24f9871a +/agent-note-client-session-references-reference-sources-and-ui-status/decision/explicit-providers-and-consumer-lifetimes: + en: 04802baa0147fec1 + zh: b86037bf2e4bc936 +/agent-note-client-session-references-reference-sources-and-ui-status/decision/main-area-navigation-and-presentation: + en: c46c9ca54ea9eaad + zh: 918dc8eebff5edf3 +/agent-note-client-session-references-reference-sources-and-ui-status/decision/presets-and-creation-flows: + en: 70ef26a3cd399b14 + zh: 5c81515ff896f91a +/agent-note-client-session-references-reference-sources-and-ui-status/decision/host-event-context-ownership-and-typert: + en: eb3be89cf9431c44 + zh: bfc26899286b37ad +/agent-note-client-session-references-reference-sources-and-ui-status/alternatives-considered: + en: 658731de6bc235f3 + zh: be16e5067f450b6e +/agent-note-client-session-references-reference-sources-and-ui-status/verification: + en: b7a7bb90877fedc3 + zh: 8b39d7a9624d6b43 +/agent-note-client-session-references-reference-sources-and-ui-status/consequences: + en: aa1b46303452c3e8 + zh: 01571143251dfc61 diff --git a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.md b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.md index 162ef08875..ca4055bd9e 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.md +++ b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.md @@ -166,7 +166,7 @@ Workspace connection preserves its navigation guards and panel-switch invalidati Preset directories and deployment defaults may be shared. A bound Session's preset is read or changed through its Provider binding; preset controllers are cached by `SessionBinding` rather than managed by one root current-Session follower. The hero preset seat uses the `session-maybe` Provider: it shows the creation-flow choice without a Session and operates on the exact bound blank Session after one arrives. Header labels read the same Provider-bound Session projection. -A preset chosen before Session creation remains in the main Conversation's `session-maybe` preset surface. After Workspace creation or reuse establishes the main Provider over a blank Session, that surface applies the choice to its Provider-bound Session. When Settings changes the default preset or picker setting, the preset service selects the blank Session whose established Provider binding carries `mainView` ownership and updates that Session. Non-blank main Sessions, independent Sidebar Providers, and other background references remain unchanged; preset subtrees do not read the main reference or use a global current follower to find their target. +A preset chosen before Session creation remains in the main Conversation's `session-maybe` preset surface. After Workspace creation or reuse establishes the main Provider over a blank Session, that surface applies the choice to its Provider-bound Session. When Settings changes the default preset, the preset service selects the blank Session whose established Provider binding carries `mainView` ownership and updates that Session. Non-blank main Sessions, independent Sidebar Providers, and other background references remain unchanged; preset subtrees do not read the main reference or use a global current follower to find their target. ### Host-event Context ownership and Typert diff --git a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.zh.md b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.zh.md index 3af8932f7c..b8c6c313f6 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-client-session-references.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-15-client-session-references.zh.md @@ -166,7 +166,7 @@ Workspace 连接保持既有导航检查与面板切换失效规则。侧边栏 预设目录与部署默认值可以共享。已绑定 Session 的预设通过 Provider 的 binding 读取或修改;预设控制器按 `SessionBinding` 缓存,不由根级 current-Session 跟随器管理。Hero 的 preset seat 使用 `session-maybe` Provider:没有 Session 时显示创建流程选择,绑定空白 Session 后操作该确切 Session。标题标签读取同一 Provider 绑定 Session 的投影。 -Session 创建前选择的 preset 保留在主 Conversation 的 `session-maybe` preset surface 中。Workspace 创建或复用空白 Session 并建立主 Provider 后,该 surface 将选择应用到 Provider 绑定的 Session。设置页修改默认 preset 或 picker 设置时,preset 服务从 Provider 已建立的 binding 缓存中选择带 `mainView` 所有权标记的空白 Session,并更新该 Session。非空白主 Session、Sidebar 的独立 Provider 与其他后台引用均不受该设置动作影响;preset 子树不读取主引用,也不通过全局 current follower 寻找目标。 +Session 创建前选择的 preset 保留在主 Conversation 的 `session-maybe` preset surface 中。Workspace 创建或复用空白 Session 并建立主 Provider 后,该 surface 将选择应用到 Provider 绑定的 Session。设置页修改默认 preset 时,preset 服务从 Provider 已建立的 binding 缓存中选择带 `mainView` 所有权标记的空白 Session,并更新该 Session。非空白主 Session、Sidebar 的独立 Provider 与其他后台引用均不受该设置动作影响;preset 子树不读取主引用,也不通过全局 current follower 寻找目标。 ### Host 事件 Context 所有权与 Typert diff --git a/.agents/notes/implemented/architecture/2026-09-15-desktop-native-fatal-recovery.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-15-desktop-native-fatal-recovery.i18n.yaml index a57f31af0a..b5ebc209af 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-desktop-native-fatal-recovery.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-15-desktop-native-fatal-recovery.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-desktop-native-fatal-recovery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-15-desktop-native-fatal-recovery.md -2026-09-15-desktop-native-fatal-recovery.md: fc1564b02e2f7b707d2b6f6d8e0947b1a78f142d -2026-09-15-desktop-native-fatal-recovery.zh.md: ceda54b4141c5fe58e6b385c86e6c1e4958dd261 +/agent-note-native-desktop-fatal-recovery: + en: 753dfd819203ac69 + zh: 5ea088778b13d940 +/agent-note-native-desktop-fatal-recovery/problem: + en: 9cf7ba7dfd36aee0 + zh: 356fdbb01870981e +/agent-note-native-desktop-fatal-recovery/decision: + en: a3b9aa3659117524 + zh: 6f25cb295c37cddd +/agent-note-native-desktop-fatal-recovery/alternatives-considered: + en: 624d62bc0b73c37a + zh: 81c3d7cd66782f73 +/agent-note-native-desktop-fatal-recovery/consequences: + en: 309a935614b0b6a1 + zh: 58db41cd59568a6d diff --git a/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.i18n.yaml index d44576c5b1..7ebb9aaaf1 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-first-class-tool-role-messages.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-15-first-class-tool-role-messages.md -2026-09-15-first-class-tool-role-messages.md: 3749ad698890073634b1753d3370f9c9dc9a2e18 -2026-09-15-first-class-tool-role-messages.zh.md: c97d84a7b3ceaee17ebb6fe828bd739dba5fb0ea +/agent-note-first-class-tool-role-messages: + en: 7241f8eb82eda881 + zh: fecbc696803c619b +/agent-note-first-class-tool-role-messages/problem: + en: d1bff2dd3b7c5070 + zh: 866aecc4211992fd +/agent-note-first-class-tool-role-messages/decision: + en: fd6733aee2f00a16 + zh: 9dd9c2e7525ba9be +/agent-note-first-class-tool-role-messages/alternatives-considered: + en: 5f727366e0885a7a + zh: b1ac16578076c286 +/agent-note-first-class-tool-role-messages/consequences: + en: 6fb4a2047b748ba7 + zh: 5382786860f2e624 diff --git a/.agents/notes/implemented/architecture/2026-09-15-guided-plugin-installation.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-15-guided-plugin-installation.i18n.yaml index e1a4357fcd..9283aaa9e4 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-guided-plugin-installation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-15-guided-plugin-installation.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-guided-plugin-installation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-15-guided-plugin-installation.md -2026-09-15-guided-plugin-installation.md: 68bd519b7cb4342c42761dfaef53940c83ceb2d8 -2026-09-15-guided-plugin-installation.zh.md: f3cbefedeb151d37078b55140635b69516fafed2 +/agent-note-guided-plugin-installation: + en: 6b8375e59efb720e + zh: d94f130f72639233 +/agent-note-guided-plugin-installation/problem: + en: edefff7cd986a509 + zh: a270839fa86976a2 +/agent-note-guided-plugin-installation/decision: + en: b661fb786e7182c5 + zh: 4cdeb584639fda23 +/agent-note-guided-plugin-installation/alternatives-considered: + en: be64b541f4d81e7c + zh: 8600531c08ab4288 +/agent-note-guided-plugin-installation/consequences: + en: e4536b20f3587497 + zh: a8eeb1d3c578b785 +/agent-note-guided-plugin-installation/testing: + en: 1e121dca5f7dc572 + zh: bcdb1b6482cc1af6 diff --git a/.agents/notes/implemented/architecture/2026-09-15-narrow-pi-ai-runtime-imports.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-15-narrow-pi-ai-runtime-imports.i18n.yaml index 3201431720..7e6309f2da 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-narrow-pi-ai-runtime-imports.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-15-narrow-pi-ai-runtime-imports.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-narrow-pi-ai-runtime-imports.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-15-narrow-pi-ai-runtime-imports.md -2026-09-15-narrow-pi-ai-runtime-imports.md: 307d880f3fce22b0e1b96efb9c3a220a511eff15 -2026-09-15-narrow-pi-ai-runtime-imports.zh.md: 139983446a2f0cd5315629c4e0a632f8c125a837 +/agent-note-narrow-pi-ai-runtime-imports: + en: d29340bbc4bf0e5b + zh: 12a39c4efe53b580 +/agent-note-narrow-pi-ai-runtime-imports/problem: + en: 4b2048b356064ada + zh: 9926d7c54da73852 +/agent-note-narrow-pi-ai-runtime-imports/decision: + en: d425c01ec05ee7f2 + zh: 8d58d6db913720c4 +/agent-note-narrow-pi-ai-runtime-imports/alternatives-considered: + en: c663ce67f3831d3f + zh: de280dc149d5a6a0 +/agent-note-narrow-pi-ai-runtime-imports/consequences: + en: 9707284a83c1294a + zh: c53be621aac00fc9 diff --git a/.agents/notes/implemented/architecture/2026-09-15-platform-office-engines.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-15-platform-office-engines.i18n.yaml index 7ba1bf8a3e..c20b10b6fe 100644 --- a/.agents/notes/implemented/architecture/2026-09-15-platform-office-engines.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-15-platform-office-engines.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-platform-office-engines.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-15-platform-office-engines.md -2026-09-15-platform-office-engines.md: 4272054672c6163f22b910ab64b6472a9dbdfb4c -2026-09-15-platform-office-engines.zh.md: d0a317333049734415ab9c0c05a5624b63b27447 +/agent-note-one-office-engine-per-platform: + en: 5ba8eea6deb11824 + zh: 7d1cb289fa278c74 +/agent-note-one-office-engine-per-platform/problem: + en: 803030fa18966fef + zh: bb1bbd185860f533 +/agent-note-one-office-engine-per-platform/decision: + en: 8cea2cb889666af7 + zh: 346adb1e99787c78 +/agent-note-one-office-engine-per-platform/alternatives-considered: + en: d406d0a9f4dd503a + zh: b2685e11d706799e +/agent-note-one-office-engine-per-platform/consequences: + en: 7e236c479975eee6 + zh: 94a8e0e8883bd324 diff --git a/.agents/notes/implemented/architecture/2026-09-16-creator-persistent-plugin-management.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-16-creator-persistent-plugin-management.i18n.yaml index 2e5d7be1ec..0c59a93381 100644 --- a/.agents/notes/implemented/architecture/2026-09-16-creator-persistent-plugin-management.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-16-creator-persistent-plugin-management.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-creator-persistent-plugin-management.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-16-creator-persistent-plugin-management.md -2026-09-16-creator-persistent-plugin-management.md: 04ccbb83fe6d2f5c460f53100a9087cce119ea4d -2026-09-16-creator-persistent-plugin-management.zh.md: 91afa00cd3f0adb8b21a52ee958bac61bc0912fc +/agent-note-creator-mode-installs-persistent-plugin-bundles: + en: c73c641d920a1431 + zh: c8ee5e861cc8bad3 +/agent-note-creator-mode-installs-persistent-plugin-bundles/problem: + en: 44615a7a0939054e + zh: b8efa721321ba0d7 +/agent-note-creator-mode-installs-persistent-plugin-bundles/decision: + en: 3530a89a72e35bdd + zh: 3601941563747b5d +/agent-note-creator-mode-installs-persistent-plugin-bundles/alternatives-considered: + en: af527d8aabdfd59c + zh: 34388da992d2ab56 +/agent-note-creator-mode-installs-persistent-plugin-bundles/consequences: + en: f27b9e492a6035e0 + zh: 3d7832ad169b7daa diff --git a/.agents/notes/implemented/architecture/2026-09-16-desktop-cos-upload-transport.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-16-desktop-cos-upload-transport.i18n.yaml index ecb789a14d..8a90598c63 100644 --- a/.agents/notes/implemented/architecture/2026-09-16-desktop-cos-upload-transport.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-16-desktop-cos-upload-transport.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-desktop-cos-upload-transport.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-16-desktop-cos-upload-transport.md -2026-09-16-desktop-cos-upload-transport.md: 84504b32fd02d1fbaf8276b4f1baf7d85f7dcbd5 -2026-09-16-desktop-cos-upload-transport.zh.md: 2a2080f95b39ab433b4ccb3bec60e5ba61f52dc9 +/agent-note-upload-desktop-releases-through-the-tencent-cos-sdk: + en: acead237faaa9390 + zh: ca5d23451f3b4577 +/agent-note-upload-desktop-releases-through-the-tencent-cos-sdk/problem: + en: 74f8515cdbb2a0aa + zh: a00d1b08db6d6158 +/agent-note-upload-desktop-releases-through-the-tencent-cos-sdk/decision: + en: 54cef8eacccce2e8 + zh: 8bad9ce5c932e0dd +/agent-note-upload-desktop-releases-through-the-tencent-cos-sdk/testing: + en: c15a405f365ca499 + zh: ee59d1b593473ee7 +/agent-note-upload-desktop-releases-through-the-tencent-cos-sdk/alternatives-considered: + en: faae1f132d6cd404 + zh: 1683143fbe6b07ce +/agent-note-upload-desktop-releases-through-the-tencent-cos-sdk/consequences: + en: 2453f558b12db1ec + zh: 15d77bfb842f9b31 diff --git a/.agents/notes/implemented/architecture/2026-09-16-experimental-voice-input.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-16-experimental-voice-input.i18n.yaml index 65566f68ce..9845fb1909 100644 --- a/.agents/notes/implemented/architecture/2026-09-16-experimental-voice-input.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-16-experimental-voice-input.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-experimental-voice-input.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-16-experimental-voice-input.md -2026-09-16-experimental-voice-input.md: 30c81ab233f27242dcf1fe2ef89bbb86542f9c04 -2026-09-16-experimental-voice-input.zh.md: 76aa8d6fc4bea32f194b20d05db4bf49af0be313 +/agent-note-experimental-voice-input-with-explicit-recognition-providers: + en: 8d4bb68acfedbb76 + zh: e2fd06ac5d0d1f21 +/agent-note-experimental-voice-input-with-explicit-recognition-providers/problem: + en: 098f766687e70ec0 + zh: 5f75407de5357c36 +/agent-note-experimental-voice-input-with-explicit-recognition-providers/decision: + en: ac3b8f0534c8bc4b + zh: 8480dbb4bdf9e695 +/agent-note-experimental-voice-input-with-explicit-recognition-providers/alternatives-considered: + en: 660a547861d966ad + zh: d597eac0b15d81b4 +/agent-note-experimental-voice-input-with-explicit-recognition-providers/consequences: + en: 75189a3d36b12ccd + zh: 2d88b1c723a2f02e diff --git a/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.i18n.yaml new file mode 100644 index 0000000000..159fee0bf9 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-16-host-schedule-storage.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.md +/agent-note-host-owned-scheduled-messages: + en: 11854b220af809ea + zh: 0f0575de37107ed8 +/agent-note-host-owned-scheduled-messages/problem: + en: 2c774d05ae75784f + zh: 619ba7f281b13233 +/agent-note-host-owned-scheduled-messages/decision: + en: 4a38d9bd933241b0 + zh: b246c74f68e92a25 +/agent-note-host-owned-scheduled-messages/alternatives-considered: + en: 21d7ec9a9ff3cbf2 + zh: 93d03b8b3012aa7e +/agent-note-host-owned-scheduled-messages/consequences: + en: 0358aab730e4bf56 + zh: 61e89e0374891f8a diff --git a/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.md b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.md new file mode 100644 index 0000000000..79a4f72071 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.md @@ -0,0 +1,65 @@ +# Agent Note: Host-owned scheduled messages + +Status: implemented + +English | [中文](2026-09-16-host-schedule-storage.zh.md) + +## Problem + +Scheduled messages must remain discoverable after restart without loading every Session. A timer attached to a live Agent cannot dispatch a task whose Session remains cold. Users also need to inspect pending and delivered tasks without activating their conversation; removing a task after delivery loses that management record. + +## Decision + +The existing Schedule package owns one Host storage domain containing each task's original Session id, reminder record, `active` or `inactive` status, latest delivery receipt, and saved delivery history. The domain is authoritative for retained tasks. The Host scheduler restores timers only for active tasks; a due task uses the Session controller's existing resolution operation and queues an ordinary follow-up in the original Session. Querying and deleting tasks do not resolve an Agent. Stored records lacking status normalize to `active` without scanning or recreating historical Sessions. + +The task domain declares the whole-unit layout. Tasks are authoritative, so the JSON backend rejects an unreadable file, malformed document, unsupported version, or invalid task as a complete load failure instead of interpreting it as deletion. Failed recovery leaves `schedule.json` unchanged, while an initially absent file opens as an empty domain; repairing the file preserves task identity. `Service.init` waits for both storage validation and runtime setup, management methods wait for the same initialization result, and an unloading owner releases late-acquired storage without starting dispatch. Dispatch admission is separate from initialization: an ancestor can close Agent admission after a task mutation commits but before runtime cleanup starts. That refusal is logged without automatic retry and does not turn the persisted mutation into a failed management result. Invalid storage and failed cleanup registration still reject startup. + +This supersedes the Session-log authority, live-only activation, and read-only catalog decisions in the [Session-local reminders note](../feature/2026-08-05-durable-web-schedule.md). Its explicit absolute-time validation, fixed-rate arithmetic, and distinction between queue admission and model completion remain applicable. Historical `schedule/change` creation, fold, and invariant types remain restricted to After, At, and Every through `LegacyScheduleRecord`; a separate Host decoder accepts the current `ScheduleRecord`, including Daily, Weekly, and Cron. The Host record decoder requires a stored `title` that is non-empty after trimming, already trimmed, and at most 120 characters, and the strict task schema rejects the whole domain open instead of dropping such a task. The historical change decoder tolerates an absent `title` so an already-written Session log stays readable, and it applies the same three checks when the member is present. The storage domain remains version 1. Historical events do not populate that domain, and existing `at` tasks are not converted into daily or weekly rules. Loading a Session with active legacy reminders warns that they must be recreated. + +A plugin-sourced `followup()` synchronously appends the message to the Session inbox. Successful Session flush acknowledges durable delivery. One task-record put stores `lastDelivery`, appends a delivery record with the occurrence target, acknowledgment time, actual message id, and instruction snapshot, and updates the one-shot's `inactive` status or the recurring task's next target and status. Task state and its saved history therefore share one commit. Inactive tasks remain stored and never schedule another delivery; explicit deletion stops future delivery and removes the row together with its saved records. These records acknowledge inbox delivery, not user receipt or model execution completion. + +New tasks initialize an empty `deliveryHistory`. A task without that optional field exposes its existing latest receipt, if any, and marks earlier records unavailable. Reading never rewrites the old task or invents the lost history or instruction snapshot. Its next acknowledged delivery preserves that available receipt and appends the new one. Strict decoding rejects duplicate message ids and disagreement between the latest receipt and the last history entry. History follows append order, not wall-clock sorting, so clock rollback does not reverse acknowledged deliveries. + +A recurring task contributes its latest due occurrence once, including after Host restart. Every remains creation-aligned until an interval edit establishes a new anchor; Daily retains a local time and explicit IANA zone, and Weekly adds a non-empty ISO weekday set stored as unique ascending numbers. Every, Daily, Weekly, and Cron use `renderRecurringReminderBatchFraming` and share one follow-up message and its real message id when due for the same Session. A recurring task with no representable next target remains inactive with its last receipt. A stopped Host does not send messages. + +Daily is a fourth mutually exclusive creation selector, Weekly a fifth, and Cron a sixth, none a conversion of `every_seconds` or `at`. Weekly selects every local date whose ISO weekday belongs to its stored set; the decoder rejects an unnormalized stored set, and the selector rejects an empty, repeated, out-of-range, or non-integer one. Their first targets are strictly future. Missing local times and dates are skipped; overlaps select the earlier instant once per date. The next target is after the delivery decision and on a local date later than the selected occurrence's date. Only UTC targets are restricted to years 0001–9999; local dates may cross into year 0 or 10000 at the edges. After Session restoration, the runtime rechecks due members against the current clock so a rollback does not admit future tasks. + +The maintained `@js-temporal/polyfill` 0.5.1 resolves local dates and overlap/gap behavior using the Host's IANA data; Schedule does not own offset-sampling logic or add another package layer. Each daily or weekly record stores normalized `HH:mm:ss.SSS` time, its zone, its weekday set where applicable, and a committed next UTC instant. Decoding and restart do not recompute that instant. Valid zone aliases remain readable across canonical-name changes, while subsequent targets use current Host time-zone data. + +Model `schedule_list`, Remote `list`, and the Session header's right-aligned reminder clock show only active tasks. The independent Automation tasks page opens from the sidebar and reads active and inactive Host tasks through the read-only Remote `catalog` method, without activating Sessions or reading their history. That clock is absent while the Session has no active reminder, opens a single task's detail directly when exactly one remains, and otherwise lists them so one can be chosen; both paths open one right-Sidebar task tab that renders the same detail component the Automation tasks page uses, so neither path selects the main panel. The tab names its task and original Session through its navigation parameters and carries that binding into every mutation, so opening or deleting from it never activates a Session. The page has one All, Enabled, and Inactive status filter row, retained inactive details, latest delivery metadata, and an original-Session control that sits in the detail tab strip beside the task actions. Its header's New action starts a new Session, where the reminder is created by asking the model; the page offers no creation form. Navigation waits for Session and archive metadata, explains unavailable targets, and never restores an archived Session implicitly. Task retention remains independent of original-Session availability. Every, Daily, Weekly, and Cron are recurring rules; the page groups tasks only by status. Daily and Weekly rule labels retain the saved local time, exact rule zone, and stored weekday set rather than substituting the browser zone used for next-target display. Explicit confirmed deletion reuses `delete` with the entry's original Session binding, requiring that the supplied binding match the stored task. This argument check is not independent caller authorization: model tools capture the current Agent's Session, while the global user interface selects the task's original binding. Cross-Session model modification policy remains a product decision, not a consequence of the storage layout. A payload-free change notification invalidates queries, and reconnect queries recover missed notifications. Deletion prevents subsequent dispatch but does not retract a queued message. + +The second detail level separates Rules from Delivery records. Opening records requests `history` with the task's original Session binding and an explicit page limit of 1–100. An exclusive message-id cursor reads older receipts without changing position when new deliveries append. Catalogs retain only latest-receipt metadata rather than duplicating full histories in every task-list response. Missing tasks and unknown cursors are distinct failures, not empty successful history. The records view loads lazily, rejects stale responses, and keeps original-Session navigation separate from inspection. + +Name, instruction, and timing updates share the dispatch and deletion FIFO. Comparing the complete observed record inside that queue prevents a stale draft from overwriting a saved rule or a target advanced by delivery. This avoids adding a persisted revision counter, at the cost of rejecting drafts after normal delivery changes the target. One task put replaces the rule, name, or instruction, preserving identity, original Session binding, status, latest receipt, and saved history. A request may omit the timing change, the name, or the instruction; an omitted field keeps its stored value, and a name or instruction change alone leaves the committed target untouched. Normalized no-ops leave the committed target and stored bytes unchanged. Changed one-shots retain their identity as At records; changed fixed intervals use a new accepted-save anchor; changed wall-clock rules re-resolve their first future target from the same accepted-save sample, and an equivalent normalized rule stays a no-op. A timing change may select a different recurrence kind, and the new rule computes its target exactly as creation would from that accepted-save sample. Deletion removes the row together with its saved records ([consequences of that reversal](2026-09-22-schedule-hard-delete-and-bounded-history.md)), so the runtime never schedules the task again and `history` no longer resolves for its original binding. Inactive tasks are not reopened. + +The page uses the existing Host task domain and scheduler, not a mock engine or a Session projection. The name, the instruction, and the run-time rows edit one local draft for the shown task, and one Save commits that draft as a single update carrying the complete expected record; Cancel restores the stored values, a failed save retains the draft, an unsaved draft survives an authoritative refresh, and a committed save and a failed catalog refresh remain separate outcomes. Pause and execution-history operations remain unsupported. Lifecycle status and latest delivery acknowledgment do not describe model results. + +The client presentation derives from existing persisted data instead of widening a persisted format. The `schedule_create` transcript card reads the created task out of the call's model-visible result JSON, which already serializes the canonical task value, rather than declaring `presentationMeta`: a persisted metadata channel would add a durable field for a card that Session-log replay reconstructs from the result alone, and previously recorded Sessions render the card without a format change. The Sidebar Session-row clock mark occupies the root-scoped `sidebar.session.row.leading` seat rather than requesting a per-Session provider, because a Session-scoped seat would bind every listed Session and thereby activate and retain it; the same root-scoped owner share feeds `sidebar.session.row.hover`, and both read the shared Host catalog snapshot `schedule/catalog()` without reading a Session log. + +Session inbox persistence and the task put occur in separate persistence systems. Inbox persistence precedes the task put to avoid marking delivery before its message exists. A crash or task-write failure after inbox persistence can repeat a message; storing status, target, and receipt together does not make the two stores atomic. Dispatch failures retain the task and produce a diagnostic; there is no independent retry timer. This feature does not create or replace a Goal. + +## Alternatives considered + +**Load every Session at startup.** Session activation is unnecessary for discovering tasks and would couple timer restoration to Agent initialization and conversation size. + +**Introduce separate rule, run, scheduler, and delivery packages.** Durable schedules and their saved inbox receipts support task inspection without independent execution records or model completion tracking. + +**Write history separately from the task.** The domain exposes independent per-record writes, not a multi-record transaction. Keeping history in the task row makes status, next target, latest receipt, and appended history commit together. A separate history store requires an explicit transactional or recovery design before adopting it. + +**Advance before enqueue or promise exactly-once delivery.** Advance-first can lose a message on enqueue failure. Exactly-once delivery needs a shared transaction or a durable idempotency protocol that the two stores do not provide. + +**Import every historical Session automatically.** A startup scan would reintroduce the cold-history dependency. Explicit recreation keeps the persisted authority unambiguous; historical decoding preserves access to existing logs. + +**Represent daily reminders as 86,400-second intervals.** Fixed elapsed time cannot preserve a local wall-clock rule when offsets change. A distinct Daily record retains the rule needed to resolve each later date. Weekly extends the same decision with an explicit weekday set rather than a 604,800-second interval, so a later offset change still resolves each selected local date. + +**Sample offsets manually or recalculate saved targets during decoding.** Temporal supplies maintained calendar and disambiguation behavior without a Schedule-owned offset search. A committed target remains due even when newer time-zone data would resolve the rule differently; only later targets use that data. + +## Consequences + +**Keep the mock's hourly choice out of the stored vocabulary.** The approved mock lists 每小时整点 beside the daily, weekly and one-shot choices. Hourly and fixed-rate intervals are the same elapsed-time rule, so the card maps that menu slot onto the existing interval kind instead of adding a persisted kind. A dedicated hourly kind would need a new durable variant, its decoder, its target resolution, and its tool schema, all to express what an interval already expresses. + +Task discovery and timers do not depend on loaded Sessions. The after, absolute-time, and fixed-rate selectors retain their semantics alongside Daily, Weekly, and Cron; reading existing saved tasks does not rewrite them. The Host must have its ordinary Session persistence and recovery services available, and the Web bundle mounts Schedule in its host row list. Explicit deletion stops future delivery and removes the task from `list` and `catalog` without deleting conversation messages; the removed row takes its saved receipts with it. History is pruned to the configured window and record cap when an acknowledgment is appended, loaded into Host memory, and rewritten with the task on each acknowledgment. Pagination limits the returned record count; the plugin configuration (`deliveryHistoryDays`, default 30, and `deliveryHistoryRecords`, default 200) limits storage growth. Earlier overwritten receipts and deliveries whose task write failed cannot be reconstructed. Pause and execution-history operations remain unsupported. + +Required coverage includes startup from stored tasks, missing-status normalization, cold Session restoration, latest-only catch-up, inactive-task retention without repeat dispatch, real message receipts, deletion across restart, removal of a deleted task's saved deliveries, queue/persistence failures, and disposal. Wall-clock obligations include gaps and skipped dates, earlier-only overlaps, fractional seconds, UTC-range edges, committed-target and alias preservation, and post-restoration clock rollback. Weekly adds weekday normalization and validation, next-target selection across a gap and an overlap, and stored set preservation. Historical decoders must reject Daily, Weekly, and Cron while Host storage accepts them. Client coverage includes every recurring kind, exact rule time, zone, and weekday set, All/Enabled/Inactive status filters, retained inactive details and original-Session navigation, authoritative refresh after confirmed deletion and notification, empty lists, reconnect, and late responses. Presentation coverage includes the page's New action starting a Session, the transcript card's narrowing of persisted result JSON including an incomplete or replayed result, the header clock's direct open for exactly one task and its count label, the idle-only row mark with the hover-card two-task limit and omission line. History coverage includes legacy byte preservation, append and restart, immutable sent instructions, strict latest-receipt consistency, stable cursor pagination, binding checks, failed persistence, and late page replies during refresh or task changes. Cross-store crash duplication remains an explicit limitation rather than a completion claim. + +Name, instruction, and timing coverage includes all supported rule kinds, complete-record conflicts, delivery/save ordering, cancellation, normalized no-ops, unchanged-history persistence, pending controls, draft retention, and collision-free task identity. The [built CLI process test](../../../../apps/cli/tests/profiles/web/tests/schedule-timing.expected.e2e.ts) drives public Remote requests and reloads actual task-file bytes in a fresh Host. Its task and receipt seeds establish retained-data inputs, not real creation, delivery, or recorded-model evidence; those require ordinary Session operations and captured model requests. diff --git a/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.zh.md b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.zh.md new file mode 100644 index 0000000000..393a773fa0 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.zh.md @@ -0,0 +1,65 @@ +# Agent Note: Host 拥有的定时消息 + +Status: implemented + +[English](2026-09-16-host-schedule-storage.md) | 中文 + +## Problem + +定时消息必须能在重启后被发现,无须加载每个 Session。挂在 live Agent 上的 timer 无法投递目标 Session 仍为 cold 的任务。用户还需要在不激活对话的情况下查看待投递和已投递任务;投递后删除任务会丢失这条管理记录。 + +## Decision + +现有 Schedule 包拥有一个 Host storage domain,保存每个任务的原始 Session id、提醒记录、`active` 或 `inactive` 状态,最近一次投递回执,以及已保存的投递历史。该 domain 是保留任务的权威来源。Host scheduler 仅为活动任务恢复 timer;到期任务使用 Session controller 现有的解析操作,在原 Session 中排入普通 follow-up。查询和删除任务不会解析 Agent。已存储但缺少状态的记录规范化为 `active`,不扫描或重建历史 Session。 + +任务 domain 声明整 unit 布局。任务是权威数据,因此 JSON 后端会把文件不可读、文档损坏、版本不受支持或任务非法作为整批加载失败,而不是解释为删除。恢复失败不会改写 `schedule.json`,初始不存在的文件则作为空 domain 打开;修复该文件后会保留任务身份。`Service.init` 等待存储校验和运行时初始化,管理方法等待同一初始化结果;拥有方卸载时释放迟到的存储资源,而不开始投递。投递调度准入与初始化分开:任务变更提交后、运行时清理开始前,祖先可能关闭 Agent 准入。此类拒绝会记录日志而不自动重试,不会将已持久化的变更变成失败的管理结果。存储非法和清理注册失败仍拒绝启动。 + +此决策替代[会话内提醒记录](../feature/2026-08-05-durable-web-schedule.zh.md)中的 Session 日志权威来源、仅 live 时激活和只读目录决策。其中显式绝对时间校验、固定速率计算,以及区分排队接纳与模型完成的决策仍然适用。历史 `schedule/change` 的创建、fold 和 invariant 类型通过 `LegacyScheduleRecord` 保持为 After、At 和 Every;独立的宿主解码器接受包含 Daily、Weekly 与 Cron 的当前 `ScheduleRecord`。宿主记录解码器要求已存储的 `title` 去除首尾空白后非空、本身已去除首尾空白且不超过 120 个字符,严格的 task schema 会拒绝整个 domain 的打开,而不是丢弃这样的任务。历史变更解码器容忍缺失的 `title`,以便已写入的 Session 日志仍可读取;该成员存在时,同样按这三项检查校验。storage domain 保持版本 1。历史事件不会填充该 domain,已有 `at` 任务也不会转换为每日或每周规则。加载含有活动旧提醒的 Session 时,会警告需要重新创建提醒。 + +插件来源的 `followup()` 同步将消息追加到 Session 收件箱。Session flush 成功后确认持久投递。一次任务记录 put 存储 `lastDelivery`,追加包含发生目标、确认时间、真实消息 id 和指令快照的发送记录,并更新一次性任务的 `inactive` 状态或重复任务的下一目标和状态。因此,任务状态与其保存的历史共用一次提交。未运行任务仍保留在存储中,且不会再次安排投递;显式删除会阻止后续投递,并把该行连同其已保存记录一并移除。这些记录确认收件箱投递,不表示用户收到消息或模型执行完成。 + +新任务初始化空的 `deliveryHistory`。缺少该可选字段的任务会展示已有的最近一次回执(如果存在),并标明更早记录不可用。读取不会重写旧任务,也不会虚构已丢失的历史或指令快照。下一次确认投递时,保留已有回执并追加新记录。严格解码拒绝重复消息 id,以及最近一次回执与历史末项不一致的情况。历史按追加顺序排列,不按墙钟排序,因此时钟回拨不会颠倒已确认投递的顺序。 + +重复任务只投递一次最新到期发生时点,Host 重启后也一样。Every 保持与创建时间对齐,直到修改间隔后建立新的起算时点;Daily 保留本地时间与显式 IANA 时区,Weekly 另存非空 ISO 星期集合(唯一且升序)。Every、Daily、Weekly 与 Cron 均使用 `renderRecurringReminderBatchFraming`,同一 Session 的到期任务共用一条 follow-up 消息及其真实消息 id。没有可表示的下一目标时,重复任务保留未运行状态及最近一次回执。停止的 Host 不会发送消息。 + +Daily 是互斥的第四个创建选择器,Weekly 是第五个,Cron 是第六个,三者都不是对 `every_seconds` 或 `at` 的转换。Weekly 选择本地日期 ISO 星期属于其所存集合的每个日期;解码器拒绝未规范化的已存集合,选择器拒绝空、重复、超出范围或非整数的集合。它们的首个目标严格晚于当前时间。缺失的本地时间或日期被跳过;重叠时间选择较早时点,每个日期一次。下一目标晚于投递判断时刻,且其本地日期晚于所选发生时点的日期。仅 UTC 目标限制在 0001–9999 年;边缘处的本地日期可以进入第 0 年或第 10000 年。Session 恢复后,运行时依据当前时钟重新核对到期成员,避免时钟回拨时接纳未来任务。 + +受维护的 `@js-temporal/polyfill` 0.5.1 使用宿主 IANA 数据解析本地日期及重叠或缺口;Schedule 不拥有偏移量采样逻辑,也不增加包层级。每日或每周记录保存规范化后的 `HH:mm:ss.SSS` 时间、时区、适用的星期集合及已提交的下一 UTC 时点。解码和重启不会重新计算该时点。规范名称变化后,有效时区别名仍可读取;后续目标使用宿主当前的时区数据。 + +模型 `schedule_list`、Remote `list` 和 Session 顶部右侧的提醒时钟仅显示活动任务。独立的自动化任务页面从侧边栏打开,通过只读 Remote `catalog` 方法读取活动和未运行 Host 任务,不激活 Session 或读取其历史。该时钟在该 Session 没有活动提醒时不显示;恰好有一个时直接打开该任务详情,否则列出提醒供选择。两条路径都打开同一个右侧边栏任务页签,该页签渲染自动化任务页面所用的同一详情组件,因此都不会切换主面板。页签通过导航参数指明任务及其原 Session,并把该绑定带入每个修改操作,因此从页签打开或删除都不会激活 Session。页面提供一行“全部/已开启/未运行”状态筛选,保留未运行任务详情、最近一次投递元数据和固定在位于详情页签条内、与任务操作并排的原 Session 入口。页头的“新建”操作会打开一个新会话,提醒由模型在该会话中创建;页面不提供创建表单。导航等待 Session 与归档元数据,解释不可用目标,且不会隐式恢复已归档 Session。任务保留与原 Session 可用性相互独立。Every、Daily、Weekly 和 Cron 均为重复规则;页面只按状态分组。Daily 与 Weekly 规则标签保留保存的本地时间、精确规则时区和所存星期集合,不替换为下一目标显示所用的浏览器时区。显式确认删除复用 `delete`,传入条目的原始 Session 绑定,要求传入绑定与已存任务一致。这项参数校验不是独立的调用者鉴权:模型工具捕获当前 Agent 的 Session,全局用户界面则选择任务的原始绑定。跨会话模型修改政策仍是产品决策,不由存储布局直接决定。无载荷的变更通知使查询失效,重新连接时重新查询以恢复漏掉的通知。删除阻止后续投递,但不撤回已排队消息。 + +第二层详情将“规则”与“发送记录”分开。打开发送记录时,`history` 请求携带任务的原始 Session 绑定,以及 1–100 的显式分页数量。排他的消息 id 游标用于读取更早回执,新投递追加后不会改变其定位。目录仅保留最近一次回执元数据,不在每次任务列表响应中复制完整历史。任务不存在和游标未知属于独立失败,不是查询成功的空历史。记录视图按需加载,拒绝晚到的过期响应,并将原 Session 导航与查看记录分开。 + +名称、指令和时间更新与投递、删除共用 FIFO。在该队列内比较完整的已观察记录,可防止旧草稿覆盖已保存规则或投递已推进的目标。这样无须增加持久版本计数器,代价是正常投递改变目标后也会拒绝旧草稿。一次任务 put 替换规则、名称或指令,保留身份、原始 Session 绑定、状态、最近一次回执和已保存历史。请求可以省略时间变更、名称或指令;省略的字段保留已存储值,仅修改名称或指令不会改变已提交目标。归一化后等价的修改保留已提交目标与存储字节。修改后的一次性任务以 At 记录保留身份;固定间隔改变后以接纳保存时刻重新起算;钟表规则改变后以同一接纳保存时刻重新解析首个未来目标,而归一化后等价的规则不产生变更。时间变更可以选择不同的重复类型,新规则按创建时相同的方式、以同一接纳保存时刻计算目标。删除会移除该行及其已保存记录([该反转的后果](2026-09-22-schedule-hard-delete-and-bounded-history.zh.md)),因此运行时不会再调度该任务,`history` 也不再按其原始绑定解析。未运行任务不会被重新启用。 + +页面使用现有 Host 任务 domain 和调度器,不使用 mock 引擎或 Session projection。名称、指令和运行时间行编辑当前任务的同一份本地草稿,一次保存把该草稿作为携带完整预期记录的单个更新提交;取消恢复已存储值,保存失败保留草稿,未保存的草稿会保留到权威刷新之后,保存已提交与目录刷新失败仍是不同结果。暂停和执行历史操作仍不受支持。生命周期状态与最近一次投递确认不描述模型结果。 + +客户端的呈现从已有持久化数据派生,而不扩展持久化格式。`schedule_create` transcript(文本记录)卡片从该调用对模型可见的结果 JSON 中读出创建的任务——该 JSON 已经序列化规范任务值——而不是声明 `presentationMeta`:持久化 metadata 通道会为一张仅凭结果即可在 Session 日志回放中重建的卡片增加持久字段,而早于该卡片录制的 Session 无需格式变更即可渲染它。侧栏 Session 行的时钟标记占用 root 作用域的 `sidebar.session.row.leading` slot,而不是请求逐 Session provider,因为 Session 作用域的 slot 会绑定列表中每个 Session,从而激活并保留它;同一个 root 作用域属主约定也供给 `sidebar.session.row.hover`,两者都读取共享的 Host 目录快照 `schedule/catalog()`,不读取 Session 日志。 + +Session 收件箱持久化和任务 put 发生在两个持久化系统中。收件箱持久化先于任务 put,以免消息尚不存在时就标记已投递。收件箱持久化后崩溃或任务写入失败可能重复发送消息;状态、目标和回执一起存储,并不使两个存储具有原子性。投递失败保留任务并输出诊断;没有独立的重试 timer。此功能不创建或替换 Goal。 + +## Alternatives considered + +**启动时加载每个 Session。** 发现任务不需要激活 Session,这会让 timer 恢复依赖 Agent 初始化和对话大小。 + +**引入独立的 rule、run、scheduler 和 delivery 包。** 持久 schedule 与已保存的收件箱回执足以支持任务查看,无须独立执行记录或模型完成跟踪。 + +**将历史与任务分开写入。** domain 提供独立的逐记录写入,不提供多记录事务。将历史保存在任务行内,可使状态、下一目标、最近一次回执和追加历史一起提交。采用独立历史存储之前,需要明确的事务或恢复设计。 + +**入队前推进,或承诺恰好投递一次。** 先推进可能在入队失败时丢失消息。恰好投递一次需要共享事务或持久幂等协议,这两个存储并不提供。 + +**自动导入全部历史 Session。** 启动扫描会重新引入对 cold 历史的依赖。显式重建使持久化权威来源保持明确;历史解码保留了现有日志的访问能力。 + +**以 86,400 秒间隔表示每日提醒。** 固定经过时长无法在偏移量变化时保留本地钟表规则。独立的 Daily 记录保留了解析每个后续日期所需的规则。Weekly 以显式星期集合而非 604,800 秒间隔延续同一决策,因此偏移量变化后仍能解析每个所选本地日期。 + +**手动采样偏移量或在解码时重新计算已保存目标。** Temporal 提供受维护的日历与消歧行为,无须由 Schedule 实现偏移量搜索。即使较新的时区数据对规则给出不同解析,已提交目标仍然到期;仅后续目标使用该数据。 + +## Consequences + +**不把 mock 的「每小时整点」引入持久词表。** 设计稿把它与每天、每周、仅一次并列。每小时整点与固定间隔在语义上是同一种按经过时间计量的规则,因此详情里的该项直接映射到既有的间隔类型,而不是新增一个持久种类。若真要新增,需要新的持久变体、解码器、目标解析与工具 schema,而它表达的能力现有间隔已经覆盖。 + +任务发现和 timer 不依赖已加载的 Session。延迟、绝对时间和固定速率选择器在与 Daily、Weekly、Cron 并存时保留自身语义;读取已有任务不会重写它们。Host 必须提供普通 Session 持久化和恢复服务,Web bundle 在其宿主行列表中挂载 Schedule。显式删除会阻止后续投递,并将任务从 `list` 和 `catalog` 中移除,不删除对话消息;被移除的行会带走其已保存回执。历史在追加确认时按配置的窗口与条数上限裁剪,随后加载到 Host 内存,并在每次确认时随任务一起重写。分页限制返回记录数量,不限制存储增长或指令字节数。此前被覆盖的回执,以及任务写入失败的投递记录,无法重建。暂停和执行历史操作仍不受支持。 + +必要覆盖范围包括从已存储任务启动、缺失状态规范化、冷 Session 恢复、仅补发最新发生时点、保留未运行任务且不重复投递、真实消息回执、重启后的删除结果、删除会移除已保存发送记录、排队或持久化失败,以及销毁。钟表规则的验证要求包括缺口和跳过的日期、仅选择较早时点的重叠、小数秒、UTC 范围边缘、已提交目标和别名保留,以及恢复后的时钟回拨。Weekly 另需覆盖星期集合的规范化与校验、跨缺口与重叠的下一目标选择,以及已存集合的保留。历史解码器必须拒绝 Daily、Weekly 与 Cron,而宿主存储接受它们。客户端覆盖范围包括每种重复规则、精确规则时间、时区和星期集合、全部/已开启/未运行状态筛选、保留未运行任务详情和原 Session 导航、确认删除和通知后的权威刷新、空列表、重新连接和晚到响应。呈现覆盖范围包括页面“新建”操作打开新会话、transcript 卡片从不完整或回放的结果 JSON 中收窄任务、页头时钟在恰好一个任务时直接打开并给出数量标签、仅空闲行标记及其悬浮卡片两个任务上限与遗漏行。历史覆盖范围包括旧文件字节保留、追加与重启、不可变的发送指令、最近回执一致性严格校验、稳定游标分页、绑定校验、持久化失败,以及刷新或切换任务期间晚到的分页响应。跨存储崩溃导致的重复投递仍是明确限制,不能被表述为完成保证。 + +名称、指令和时间编辑覆盖范围包括所有支持的规则类型、完整记录冲突、投递与保存的顺序、取消、规范化后的无变更、历史持久化不变、等待期间的控件、草稿保留,以及无碰撞的任务标识。[已构建 CLI 进程测试](../../../../apps/cli/tests/profiles/web/tests/schedule-timing.expected.e2e.ts) 驱动公开 Remote 请求,并在新 Host 中重新加载实际任务文件字节。任务和回执种子只是已保留数据的输入,不是真实创建、投递或模型录制证据;这些证据需要普通 Session 操作与捕获的模型请求。 diff --git a/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.i18n.yaml index 8a8f6629f8..209838a431 100644 --- a/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-plugin-configuration-on-the-plugins-page.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.md -2026-09-16-plugin-configuration-on-the-plugins-page.md: 700ada15385d0ff95e2f7f1cc58545a28677a507 -2026-09-16-plugin-configuration-on-the-plugins-page.zh.md: 23935312d2b09a524a1571f81c18ad8b5ffafc3f +/agent-note-plugin-configuration-on-the-plugins-page: + en: e3cb8f2cfd31ee99 + zh: 75c7c498bb5b29e4 +/agent-note-plugin-configuration-on-the-plugins-page/problem: + en: 9ca845902f1df3a2 + zh: 41e3157a843a511e +/agent-note-plugin-configuration-on-the-plugins-page/decision: + en: ccee8068ea810fcb + zh: c87c4e6c44b33a67 +/agent-note-plugin-configuration-on-the-plugins-page/consequences: + en: d3d131d6c46bc32e + zh: eb7c06f119dfbe8d +/agent-note-plugin-configuration-on-the-plugins-page/alternatives-considered: + en: 14c6db09f23c2005 + zh: 979730121cd837c3 +/agent-note-plugin-configuration-on-the-plugins-page/testing: + en: b58fdf0d5922f52b + zh: 0b999255d2b9b832 diff --git a/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.md b/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.md index 700ada1538..35aaefd028 100644 --- a/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.md +++ b/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.md @@ -20,7 +20,7 @@ The page passes `view: 'page'` for each form. Official plugin cards and details **The four host-plane pages register while the Host serves their namespaces.** Each page's package registers it through `ctx.slots.inject` when the shared settings mirror shows the namespace and disposes it when the namespace goes, so a deployment that does not compose the owning plugin shows no trace of it; since [settings pages as companion packages](2026-09-17-settings-pages-as-companion-packages.md) that is one companion package per page, and `ui-settings-plugins` keeps the Settings section as the **Built-in plugins** shell around the inventory tab. The `settings.plugin.item` slot is retired. -**The Official group.** The optional bundles the installation ships open the group, tagged **Beta** where the feature is one (Agent Teams), with no official tag; the configuration pages follow. Auto review is a published experimental package used as the install guide's example, not an `OPTIONAL_BUNDLES` entry or a CLI dependency. +**The Official group.** The optional bundles the installation ships open the group, tagged **Beta** where the package is experimental, with no official tag; the configuration pages follow. The [optional-bundle decision for experimental capabilities](2026-09-21-experimental-capabilities-as-optional-bundles.md) names the entries. ## Consequences diff --git a/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.zh.md b/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.zh.md index 23935312d2..ccdaf5629a 100644 --- a/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-16-plugin-configuration-on-the-plugins-page.zh.md @@ -20,7 +20,7 @@ Status: implemented **四个宿主平面页面在 Host 服务其命名空间期间注册。** 每个页面所在的包在共享的 settings 镜像显示某个命名空间时通过 `ctx.slots.inject` 注册对应页面,命名空间消失时销毁,因此没有组装该插件的部署不会留下它的痕迹;自[设置页作为伴生包](2026-09-17-settings-pages-as-companion-packages.zh.md)起,每个页面各是一个伴生包,`ui-settings-plugins` 把设置分区保留为清单标签页外面的**内置插件**外壳。`settings.plugin.item` slot 退役。 -**官方分组。** 安装随附的可选组合包开启这个分组,属于 beta 功能的(Agent Teams)带 **Beta** 标签,没有官方标签;配置页排在其后。Auto review 是安装引导用作示例的已发布实验包,不属于 `OPTIONAL_BUNDLES` 或 CLI 依赖。 +**官方分组。** 安装随附的可选组合包开启这个分组,属于实验包的带 **Beta** 标签,没有官方标签;配置页排在其后。[实验能力的可选 bundle 决策](2026-09-21-experimental-capabilities-as-optional-bundles.zh.md)列出这些条目。 ## 后果 diff --git a/.agents/notes/implemented/architecture/2026-09-16-size-neutral-product-icon-weights.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-16-size-neutral-product-icon-weights.i18n.yaml index 758bca04da..de00746f9a 100644 --- a/.agents/notes/implemented/architecture/2026-09-16-size-neutral-product-icon-weights.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-16-size-neutral-product-icon-weights.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-size-neutral-product-icon-weights.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-16-size-neutral-product-icon-weights.md -2026-09-16-size-neutral-product-icon-weights.md: 3850fcbddfef6d096f648d5b3efa73790f40f8c1 -2026-09-16-size-neutral-product-icon-weights.zh.md: 84031677e9b13b8dbf3b8e5d959359824e0c94fc +/agent-note-size-neutral-product-icon-weights: + en: f0d742af33e3297e + zh: 5db6cdc26635d843 +/agent-note-size-neutral-product-icon-weights/problem: + en: aae2bf56f8695ee8 + zh: 491fa683d7cc580f +/agent-note-size-neutral-product-icon-weights/decision: + en: c0680b384d4198c8 + zh: a34f4481b7784b4f +/agent-note-size-neutral-product-icon-weights/alternatives-considered: + en: bda83cdc7a7c59a9 + zh: d3592cdf068556ea +/agent-note-size-neutral-product-icon-weights/consequences: + en: bceee31f65a32e69 + zh: d8fad0a01f1a7e7a diff --git a/.agents/notes/implemented/architecture/2026-09-16-user-terminal-permissions.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-16-user-terminal-permissions.i18n.yaml index e8df386371..f065cf26a3 100644 --- a/.agents/notes/implemented/architecture/2026-09-16-user-terminal-permissions.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-16-user-terminal-permissions.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-user-terminal-permissions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-16-user-terminal-permissions.md -2026-09-16-user-terminal-permissions.md: f45b96419c34f8ebddc30431b42c9859c46de6b9 -2026-09-16-user-terminal-permissions.zh.md: 62bb152a1b899d026c8d7bddb350317ba12f14cf +/agent-note-user-terminal-permissions: + en: 806fc2a4c3bc2294 + zh: dfdae2dc3c49b0b3 +/agent-note-user-terminal-permissions/problem: + en: 2948b4f40ebe9d3b + zh: a59676148531470f +/agent-note-user-terminal-permissions/decision: + en: 23aad535d7f8d41e + zh: 543ecefce61bee7f +/agent-note-user-terminal-permissions/alternatives-considered: + en: a4f8d5ac653db322 + zh: 9671639c5a2c746b +/agent-note-user-terminal-permissions/consequences: + en: b1c2a8059cd44cc2 + zh: 83aba1c4de722bdc diff --git a/.agents/notes/implemented/architecture/2026-09-17-account-provider-signout.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-account-provider-signout.i18n.yaml new file mode 100644 index 0000000000..883bb12bc0 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-account-provider-signout.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-17-account-provider-signout.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-account-provider-signout.md +/agent-note-account-provider-and-active-request-cancellation: + en: 3b8b363041dd596b + zh: 7c9b2eb195435b1f +/agent-note-account-provider-and-active-request-cancellation/problem: + en: 8d4d00e33af763b2 + zh: 61977c82d66ae9bf +/agent-note-account-provider-and-active-request-cancellation/decision: + en: d5eb12a1644c6226 + zh: 513d4f22ab74e039 +/agent-note-account-provider-and-active-request-cancellation/alternatives-considered: + en: a072026c1495a1ca + zh: bf053cc04fb33914 +/agent-note-account-provider-and-active-request-cancellation/consequences: + en: 8fd00b6d69b380c0 + zh: 3830dc3a93d5de3c diff --git a/.agents/notes/implemented/architecture/2026-09-17-account-provider-signout.md b/.agents/notes/implemented/architecture/2026-09-17-account-provider-signout.md new file mode 100644 index 0000000000..6b8ef842c5 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-account-provider-signout.md @@ -0,0 +1,27 @@ +# Agent Note: Account provider and active request cancellation + +Status: implemented + +English | [中文](2026-09-17-account-provider-signout.zh.md) + +## Problem + +Selecting credentials from login state changes the billing identity of an existing provider route. Sign-out also needs to stop account-dependent work without classifying requests from settings that may have changed while a request or tool is still running. + +## Decision + +`deepseek-official` and `deepseek-account` are independent routes sharing the DeepSeek protocol implementation. Each adapter has exactly one credential resolver and authentication header mode. Neither route falls back to the other credential. The account service retains the origin and issuer validation defined by the [login decision](2026-09-14-deepseek-account-login.md). + +Account cancellation reads each running Agent’s latest `Session.requestContext()` instead of maintaining another provider field. This logged value remains through tools and retries and follows the next bound request. Idle Agents are excluded. During a new turn’s first preparation it can still name the previous turn’s account route, so sign-out can also interrupt an API-key turn that has not bound its new request yet. A missing account credential rejects a first request without a previous context before transport. + +Successful local sign-out publishes an account event. The platform account provider installs the account module’s listener, which enumerates the Agent registry and cancels matching account routes through `Agent.cancel`, preserving inboxes. The account controller shares its predicate for sign-out confirmation. Each registered child is classified independently; existing parent-owned cancellation still applies to children whose lifetime is attached to a cancelled parent. The existing HTTP signal carries cancellation to transport. + +## Alternatives considered + +A historical set of providers wrongly cancels a turn after it switches to an API-key route. Current settings misclassify an older in-flight request. A second provider field or module-global map duplicates information already recorded in request context. A login-level cancellation signal duplicates the existing Agent and HTTP cancellation chain. + +## Consequences + +Model selection exposes both routes, and choosing an account route requires login even when an API key exists. The `llm-deepseek-account` and `llm-deepseek-api-key` plugins independently own catalogs, connection settings, and credentials; both use the `llm-deepseek` protocol library. Cancellation preserves queued input without waking it automatically. The recorded hook reason produces a localized conversation notice without changing durable event types. + +Behavior tests cover credential separation, first preparation, tool-stage cancellation, and route replacement. The SDK account-provider-signout scenario boots the shipped profile and records interrupted output plus the cancellation cause. diff --git a/.agents/notes/implemented/architecture/2026-09-17-account-provider-signout.zh.md b/.agents/notes/implemented/architecture/2026-09-17-account-provider-signout.zh.md new file mode 100644 index 0000000000..588dd38bf9 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-17-account-provider-signout.zh.md @@ -0,0 +1,27 @@ +# Agent Note: 账号提供方与当前请求取消 + +Status: implemented + +[English](2026-09-17-account-provider-signout.md) | 中文 + +## Problem + +根据登录态选择凭证会改变现有提供方路由的计费身份。退登也需要停止依赖账号的任务,不能根据请求或工具运行期间可能已经改变的设置判断归属。 + +## Decision + +`deepseek-official` 和 `deepseek-account` 是独立路由,共享 DeepSeek 协议实现。每个适配器仅有一个凭证解析器和认证请求头模式。两条路由均不回退到另一凭证。账号服务保留[登录决策](2026-09-14-deepseek-account-login.zh.md)定义的来源及签发方校验。 + +账号取消读取运行中 Agent 最近的 `Session.requestContext()`,不维护额外提供方字段。该已记录值在工具和重试阶段保留,随下一次绑定请求更新;空闲 Agent 不计入。新轮次首次准备期间,它仍可能指向上一轮的账号路由,因此退登也可能打断尚未绑定新请求的 API key 轮次。没有历史上下文的首请求若缺少账号凭据,会在传输前失败。 + +本地退登成功后发布账号事件。Platform 账号提供方安装账号模块的监听器,遍历 Agent 注册表,通过 `Agent.cancel` 取消匹配的账号路由并保留收件箱。账号控制器的退登确认复用同一判断函数。每个已注册子代理独立分类;生命周期绑定到已取消父代理的子代理仍受现有父级取消规则约束。现有 HTTP 信号将取消传递到传输层。 + +## Alternatives considered + +历史提供方集合会在轮次切换到 API Key 路由后仍错误取消它。当前设置会误判更早的在途请求。额外的提供方字段或模块级全局映射重复保存请求上下文中已有的信息。登录级取消信号重复现有 Agent 与 HTTP 取消链路。 + +## Consequences + +模型选择展示两条路由,即使存在 API Key,选择账号路由仍要求登录。两个路由分别由 `llm-deepseek-account` 和 `llm-deepseek-api-key` 注册,拥有独立的模型目录与连接设置,共用 `llm-deepseek` 协议实现。取消保留排队输入,不自动唤醒。已记录的 hook 原因生成本地化对话提示,无须改变持久事件类型。 + +行为测试覆盖凭证分离、首请求准备、工具阶段取消及路由替换。SDK account-provider-signout 场景启动随附 profile,记录被中断的输出和取消原因。 diff --git a/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.i18n.yaml index db3f3c7cb5..a110a82729 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-developer-session-changes.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-developer-session-changes.md -2026-09-17-developer-session-changes.md: 0545dfa4344f8ed87fe6343e13901647a5ccdac4 -2026-09-17-developer-session-changes.zh.md: 81c53115aaf4447dac358febcbd1310bb2a36cb2 +/agent-note-developer-messages-for-incremental-session-changes: + en: 1460291daf64190e + zh: 0456570fdcfbff56 +/agent-note-developer-messages-for-incremental-session-changes/problem: + en: 4b02ed98a500205c + zh: e1a075f6a8251059 +/agent-note-developer-messages-for-incremental-session-changes/decision: + en: 986e4806b1d7da88 + zh: dedecc5248fdd5f3 +/agent-note-developer-messages-for-incremental-session-changes/alternatives-considered: + en: a9ec42fb650d6cd8 + zh: c748181c603e675f +/agent-note-developer-messages-for-incremental-session-changes/consequences: + en: e98265bb86e38a2d + zh: a9749feb7d90c22a diff --git a/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.md b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.md index 0545dfa434..35697e569d 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.md +++ b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.md @@ -20,7 +20,7 @@ Dynamic tool changes need durable, ordered records before providers can preserve The V4 codec confines developer roles to the `developer/message` slot, including rejection from inbox and title-request arrays. Native validation checks required developer fields, historical header bindings, and developer-only tool-change blocks while preserving additional JSON properties. Optional metadata additions therefore remain readable under the persistence checker's optional-property rule; additional fields cannot weaken required-field, role, or open-step checks. An ignorable marker does not establish reader support: physical decoding preserves developer payloads until vocabulary-aware admission, while writers and native readers reject malformed known data. Developer admission leaves malformed ordinary message slots to decoder recovery. Installed Session adoption validates surface relationships without converting developer records into released-V3 user records. The [released migration rules](2026-08-31-released-session-format-migrations.md) continue to protect committed predecessor generations. -The producer requirement has one scoped exception: finalized Session V4 reserves the persisted representation needed by issue #4146. Waiting for provider and UI implementations would couple the format release to those independent integrations. The reservation permits storage and validation only; no shipped profile emits developer records, and unsupported consumers throw. Production emission requires provider, UI, and compaction support together. +Session V4 reserves the persisted representation needed by issue #4146. Production emission, provider projection, UI presentation, and compaction integration are described in the [dynamic tool update decision](2026-09-20-dynamic-tool-updates.md). ## Alternatives considered @@ -32,4 +32,4 @@ The producer requirement has one scoped exception: finalized Session V4 reserves ## Consequences -Session V4 persists the tool-change representation for issue #4146. Automatic emission, provider serialization, deferred loading, and UI presentation are intentionally deferred so this type-and-persistence change does not block the V4 merge. Both DeepSeek protocols and pi-ai throw for developer history and deferred-loading requests; Chat and Trajectory throw for developer events. Shipped model-output and SDK snapshot scenarios contain no developer records. +Session V4 persists the tool-change representation for issue #4146. Emission, route projection, DeepSeek serialization, and Chat and Trajectory presentation are owned by the [dynamic tool update decision](2026-09-20-dynamic-tool-updates.md). diff --git a/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.zh.md b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.zh.md index 81c53115aa..73e27ad123 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-17-developer-session-changes.zh.md @@ -20,7 +20,7 @@ Status: implemented V4 编解码器将 developer 角色限定在 `developer/message` 字段内,并拒绝 inbox 与标题请求数组中的该角色。原生验证检查 developer 必需字段、历史请求头绑定及工具变更块仅限 developer 的约束,同时保留附加 JSON 属性。因此,可选元数据添加符合持久化检查器的可选属性规则,仍可读取;附加字段不能削弱必需字段、角色或打开 step 的检查。可忽略标记不代表读取方支持该事件:物理解码保留 developer 载荷,直到按词表执行接纳;写入方和原生读取方仍拒绝格式错误的已知数据。developer 接纳逻辑将格式错误的普通消息字段留给解码器恢复。已安装的 Session 接纳逻辑验证 surface 关系,不把 developer 记录转换为已发布 V3 的 user 记录。[已发布格式迁移规则](2026-08-31-released-session-format-migrations.zh.md)继续保护已提交的前代文件。 -产生方要求有一个限定例外:已定稿 Session V4 为 issue #4146 保留所需的持久化表示。等待提供方与 UI 实现会将格式发布与这些独立集成耦合。该预留仅允许存储和验证;已提供的 profile 不发出 developer 记录,不支持的消费者会抛出错误。生产环境发出这些记录要求提供方、UI 与压缩支持一起落地。 +Session V4 预留 issue #4146 所需的持久表示。生产发出、提供方投影、UI 展示和压缩集成见[动态工具更新决策](2026-09-20-dynamic-tool-updates.zh.md)。 ## Alternatives considered @@ -32,4 +32,4 @@ V4 编解码器将 developer 角色限定在 `developer/message` 字段内,并 ## Consequences -Session V4 为 issue #4146 持久化工具变更表示。自动发出事件、提供方序列化、延迟加载与 UI 展示有意留待后续实现,使此类型与持久化变更不阻塞 V4 合并。DeepSeek 两种协议与 pi-ai 对 developer 历史及延迟加载请求抛出错误;Chat 与 Trajectory 对 developer 事件抛出错误。已提供的模型输出与 SDK 快照场景不包含 developer 记录。 +Session V4 持久化 issue #4146 的工具变更表示。发出、路由投影、DeepSeek 序列化及 Chat 和 Trajectory 展示由[动态工具更新决策](2026-09-20-dynamic-tool-updates.zh.md)负责。 diff --git a/.agents/notes/implemented/architecture/2026-09-17-frame-shell-leading-window-chrome-seat.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-frame-shell-leading-window-chrome-seat.i18n.yaml index 08712a98da..16d3ced836 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-frame-shell-leading-window-chrome-seat.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-17-frame-shell-leading-window-chrome-seat.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-frame-shell-leading-window-chrome-seat.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-frame-shell-leading-window-chrome-seat.md -2026-09-17-frame-shell-leading-window-chrome-seat.md: cc3ef576900e38dc26c46438fd5d490ac4361be0 -2026-09-17-frame-shell-leading-window-chrome-seat.zh.md: c652f313d4f4863decc14e556a1674487d1d3fea +/agent-note-frame-owned-shell-leading-window-chrome-seat: + en: 3e2cfa57af6b53e7 + zh: 78fe101ad11a6330 +/agent-note-frame-owned-shell-leading-window-chrome-seat/problem: + en: 09b5defb78287f7e + zh: b7333ce5077914a2 +/agent-note-frame-owned-shell-leading-window-chrome-seat/decision: + en: 04853eeed03a00c5 + zh: 9542acfaa6258842 +/agent-note-frame-owned-shell-leading-window-chrome-seat/alternatives-considered: + en: 81e997e43d185834 + zh: 38eda1f9a4bac318 +/agent-note-frame-owned-shell-leading-window-chrome-seat/consequences: + en: 7d95c4c155f8e3c3 + zh: b3f88fe2fb7a77f0 +/agent-note-frame-owned-shell-leading-window-chrome-seat/testing: + en: 2fcc157c9c4f0b81 + zh: 3b0e6135b1c10db1 diff --git a/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.i18n.yaml index c3afeacd89..cfe428cf55 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-native-v4-read-validation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-native-v4-read-validation.md -2026-09-17-native-v4-read-validation.md: b111e9f1dd4aae6557b7893a9f334445ef0c85bc -2026-09-17-native-v4-read-validation.zh.md: 20f1dc53b6eda42834e169c18f7b269e2933d27c +/agent-note-mandatory-native-v4-relationship-validation: + en: 67bc5b987df97d21 + zh: 173eb273e11a24a9 +/agent-note-mandatory-native-v4-relationship-validation/problem: + en: cfb527c1c2ca661a + zh: b61a906330cdaf97 +/agent-note-mandatory-native-v4-relationship-validation/decision: + en: 14feaf74a58d5609 + zh: 8aea80c89110e638 +/agent-note-mandatory-native-v4-relationship-validation/alternatives-considered: + en: d6296e00a6b30d48 + zh: 9f7074c69fb42e5f +/agent-note-mandatory-native-v4-relationship-validation/consequences: + en: b76aaca1c35dcc6c + zh: b933c2518c64c60c diff --git a/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.i18n.yaml index e2b272908e..2cb18a5a75 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-persistence-attribution-policy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-persistence-attribution-policy.md -2026-09-17-persistence-attribution-policy.md: 19bebc8bc186f4b2b7e2e561fb6a53ceadcebabf -2026-09-17-persistence-attribution-policy.zh.md: 3561c1d1afca5402cb94b1578603c4f1a2fc89a4 +/agent-note-recorded-user-source-attribution-compatibility: + en: db7dca9aee8a5f49 + zh: 1c5aace5cb896738 +/agent-note-recorded-user-source-attribution-compatibility/problem: + en: 21904d2f57e4e159 + zh: 589fe41a93ec9e5d +/agent-note-recorded-user-source-attribution-compatibility/decision: + en: 10bd45b099218280 + zh: c21ab6c74dd1afbf +/agent-note-recorded-user-source-attribution-compatibility/alternatives-considered: + en: 2e1b3bcd9e00b5be + zh: e5a1725390346470 +/agent-note-recorded-user-source-attribution-compatibility/consequences: + en: cb2b35edfe2a006f + zh: e73c28367e78c44c diff --git a/.agents/notes/implemented/architecture/2026-09-17-plugin-detail-page-extension-slots.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-plugin-detail-page-extension-slots.i18n.yaml index 5bd9f6000c..5b7f7e9b6b 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-plugin-detail-page-extension-slots.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-17-plugin-detail-page-extension-slots.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-plugin-detail-page-extension-slots.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-plugin-detail-page-extension-slots.md -2026-09-17-plugin-detail-page-extension-slots.md: d4bbca0c4466fbb78a8c56cfc4e327100385368f -2026-09-17-plugin-detail-page-extension-slots.zh.md: f07efc3d3cadded04a7551867680cc058d532943 +/agent-note-plugin-detail-pages-as-an-extension-point: + en: 71b432dfc4475c08 + zh: a9f9a7e272c32093 +/agent-note-plugin-detail-pages-as-an-extension-point/problem: + en: 39f7e246e6ab3beb + zh: dba3ba5206d81d8d +/agent-note-plugin-detail-pages-as-an-extension-point/decision: + en: df2cba037b6bcb4d + zh: 82d0a5dc61a1716c +/agent-note-plugin-detail-pages-as-an-extension-point/alternatives-considered: + en: cdcc8710be8ab1be + zh: d82781a3c353984f +/agent-note-plugin-detail-pages-as-an-extension-point/consequences: + en: 0567cb3fbfbdb4f8 + zh: 256811c9a7271da1 +/agent-note-plugin-detail-pages-as-an-extension-point/testing: + en: 8957db157d2f743e + zh: fb24db99bb5a55aa diff --git a/.agents/notes/implemented/architecture/2026-09-17-process-local-blank-sessions.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-process-local-blank-sessions.i18n.yaml index e89e510aea..25c6bed4ad 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-process-local-blank-sessions.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-17-process-local-blank-sessions.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-process-local-blank-sessions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-process-local-blank-sessions.md -2026-09-17-process-local-blank-sessions.md: 58d222185ae67c1f70874c0d0a73910eaa1e0e5b -2026-09-17-process-local-blank-sessions.zh.md: 0f3fdf050931d11a80e92d98577ac8b42628bb60 +/agent-note-writer-acquisition-for-blank-session-reuse: + en: a78ef0f5b14debe5 + zh: 8b7ef954fe622783 +/agent-note-writer-acquisition-for-blank-session-reuse/problem: + en: 837ebb0071a5611b + zh: 23d0f0713889ead6 +/agent-note-writer-acquisition-for-blank-session-reuse/decision: + en: 932bc5c0be3721de + zh: 000425c5f053e74e +/agent-note-writer-acquisition-for-blank-session-reuse/alternatives-considered: + en: 2a67a53f7f396ba8 + zh: 6df6ccc071fb0de2 +/agent-note-writer-acquisition-for-blank-session-reuse/consequences: + en: 2e1f1894337689a2 + zh: d0cab07cc48083ee +/agent-note-writer-acquisition-for-blank-session-reuse/verification: + en: 4680e845e2ab294e + zh: ea5890c5ffb09831 diff --git a/.agents/notes/implemented/architecture/2026-09-17-session-row-menu-actions-slot.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-session-row-menu-actions-slot.i18n.yaml index 0a9151134f..40bc5939fe 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-session-row-menu-actions-slot.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-17-session-row-menu-actions-slot.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-session-row-menu-actions-slot.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-session-row-menu-actions-slot.md -2026-09-17-session-row-menu-actions-slot.md: 034144b2b7c9d260f41565d3835687e52353c381 -2026-09-17-session-row-menu-actions-slot.zh.md: 6ad15d263fd41a0ad97a386506c8f581290d032f +/agent-note-session-row-actions-as-slot-lists: + en: 6c14eadc272cbe5f + zh: d0fb9907cddcae5a +/agent-note-session-row-actions-as-slot-lists/problem: + en: 1afb986570a4bb49 + zh: 22862e82275038b7 +/agent-note-session-row-actions-as-slot-lists/decision: + en: 7a353dd9c0642f56 + zh: e503a953cccfdc47 +/agent-note-session-row-actions-as-slot-lists/alternatives-considered: + en: 19fc0c951e9e49b5 + zh: 9010c3fb55b71ce0 +/agent-note-session-row-actions-as-slot-lists/consequences: + en: cfc90eb041452a48 + zh: 882748ceb29f21ea diff --git a/.agents/notes/implemented/architecture/2026-09-17-settings-pages-as-companion-packages.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-settings-pages-as-companion-packages.i18n.yaml index 665be1daa4..34faaaba25 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-settings-pages-as-companion-packages.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-17-settings-pages-as-companion-packages.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-settings-pages-as-companion-packages.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-settings-pages-as-companion-packages.md -2026-09-17-settings-pages-as-companion-packages.md: de2f2897938fcc158c49bed772f399b4d9328d19 -2026-09-17-settings-pages-as-companion-packages.zh.md: 27d00faa156f0f48c6dc3995930be9ca629a732d +/agent-note-settings-pages-as-companion-packages: + en: ada5eadeb6e921e4 + zh: 1cc804b1720c2c98 +/agent-note-settings-pages-as-companion-packages/problem: + en: 8c23fffd3cef6ea8 + zh: 6072e1e4197afd7c +/agent-note-settings-pages-as-companion-packages/decision: + en: d0610e0445b8fdb7 + zh: 5e8af1fce960cae5 +/agent-note-settings-pages-as-companion-packages/alternatives-considered: + en: cc29e94d925d84b4 + zh: bdaec6d6ff2d511a +/agent-note-settings-pages-as-companion-packages/consequences: + en: ef4733505d43fb1e + zh: 320475e4b5a0f5e0 +/agent-note-settings-pages-as-companion-packages/testing: + en: 92bef8e1c609359b + zh: c4f2016243441b1e diff --git a/.agents/notes/implemented/architecture/2026-09-17-shared-office-runtime.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-shared-office-runtime.i18n.yaml index f3e123135e..4aa201536b 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-shared-office-runtime.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-17-shared-office-runtime.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-shared-office-runtime.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-shared-office-runtime.md -2026-09-17-shared-office-runtime.md: 25b6ddccbb5b17b93bec2c0b024dfcb63e94abc3 -2026-09-17-shared-office-runtime.zh.md: 99dffe8d0233e60480689ff983b6261cbb83bb7b +/agent-note-shared-office-runtime-for-desktop-and-sdk: + en: 28af688a50a2d5c6 + zh: ee73d6dd4fab9184 +/agent-note-shared-office-runtime-for-desktop-and-sdk/problem: + en: 4d08aed08c8aff27 + zh: d618b4ac68832867 +/agent-note-shared-office-runtime-for-desktop-and-sdk/decision: + en: f92ce88d82a076ed + zh: 341e486effad4b6d +/agent-note-shared-office-runtime-for-desktop-and-sdk/alternatives-considered: + en: d85334a384a32a7d + zh: 61c370390d9fdcf9 +/agent-note-shared-office-runtime-for-desktop-and-sdk/consequences: + en: f236fec61d99ba16 + zh: 859ee94e05a95aa4 diff --git a/.agents/notes/implemented/architecture/2026-09-17-web-feature-routes-and-route-gate.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-web-feature-routes-and-route-gate.i18n.yaml index 4531b00628..735a46bdc2 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-web-feature-routes-and-route-gate.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-17-web-feature-routes-and-route-gate.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-web-feature-routes-and-route-gate.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-web-feature-routes-and-route-gate.md -2026-09-17-web-feature-routes-and-route-gate.md: 3939bdcd0c53e766827e8fcf05f64fb4d284c59b -2026-09-17-web-feature-routes-and-route-gate.zh.md: fb329c8fc1f93b9f979612b7163e838cc521428b +/agent-note-feature-routes-follow-the-document-base-and-a-gate-keeps-them-there: + en: ca746e8d558cfc31 + zh: 3524931b0bf9991f +/agent-note-feature-routes-follow-the-document-base-and-a-gate-keeps-them-there/problem: + en: d4a1124ae3b6f6a8 + zh: 4814da5d08947bc7 +/agent-note-feature-routes-follow-the-document-base-and-a-gate-keeps-them-there/decision: + en: 5b89e02010c2da46 + zh: d11e67d86ef27908 +/agent-note-feature-routes-follow-the-document-base-and-a-gate-keeps-them-there/alternatives-considered: + en: d90dbd0c95914085 + zh: 6256f4fd76a7cb55 +/agent-note-feature-routes-follow-the-document-base-and-a-gate-keeps-them-there/consequences: + en: 94530852d7746ddb + zh: ad2383c465053822 +/agent-note-feature-routes-follow-the-document-base-and-a-gate-keeps-them-there/testing: + en: 95c952092857cb53 + zh: 232cd731afcd3288 diff --git a/.agents/notes/implemented/architecture/2026-09-17-workspace-file-binary-transfer.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-17-workspace-file-binary-transfer.i18n.yaml index 7eef4b0fa9..5fbbb120e6 100644 --- a/.agents/notes/implemented/architecture/2026-09-17-workspace-file-binary-transfer.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-17-workspace-file-binary-transfer.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-workspace-file-binary-transfer.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-17-workspace-file-binary-transfer.md -2026-09-17-workspace-file-binary-transfer.md: b419c8bd15f51246825ceddf2905ec055bbc70ae -2026-09-17-workspace-file-binary-transfer.zh.md: 9cf3d7074c3d536a5c8a39732231c6996d6f6ead +/agent-note-binary-workspace-file-transfer: + en: ea1888ee2f867b71 + zh: fd32b8b9f29347cb +/agent-note-binary-workspace-file-transfer/problem: + en: 7da36071204124c9 + zh: c90cdeaef381b252 +/agent-note-binary-workspace-file-transfer/decision: + en: e1e0224605793212 + zh: 4e55f4b57a4b8739 +/agent-note-binary-workspace-file-transfer/alternatives-considered: + en: c548577bd53db153 + zh: 2880f3751b7fcad3 +/agent-note-binary-workspace-file-transfer/consequences: + en: 44733fbb2102c581 + zh: a0290e25401a40de +/agent-note-binary-workspace-file-transfer/validation: + en: 6d62210510b842d8 + zh: 6c5a2436ed59c354 diff --git a/.agents/notes/implemented/architecture/2026-09-18-agent-teams-single-bundle.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-18-agent-teams-single-bundle.i18n.yaml index ecf9b0571e..83ed8c5841 100644 --- a/.agents/notes/implemented/architecture/2026-09-18-agent-teams-single-bundle.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-18-agent-teams-single-bundle.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-18-agent-teams-single-bundle.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-18-agent-teams-single-bundle.md -2026-09-18-agent-teams-single-bundle.md: b417061d24928877d8d31739e1e3bde6b8512d51 -2026-09-18-agent-teams-single-bundle.zh.md: ed20dac79f39f6648767d57556ed97b42d0e1c65 +/agent-note-enable-agent-teams-with-one-bundle: + en: c595b526791a8dfd + zh: 61f4bf6948e41bee +/agent-note-enable-agent-teams-with-one-bundle/problem: + en: 8dd802c775d24e42 + zh: 53cf2818dd93181e +/agent-note-enable-agent-teams-with-one-bundle/decision: + en: d513c3239b59b2ee + zh: 7692b7ae43befc9d +/agent-note-enable-agent-teams-with-one-bundle/alternatives-considered: + en: 32952c4e1b6f486d + zh: 6c9b91eaf0460d30 +/agent-note-enable-agent-teams-with-one-bundle/consequences: + en: be92cb1ce7c86cb6 + zh: 0da06f76df72f97e +/agent-note-enable-agent-teams-with-one-bundle/verification: + en: 8fc694c4c84401f1 + zh: 6540462f6896bef7 diff --git a/.agents/notes/implemented/architecture/2026-09-18-chat-navigation-performance.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-18-chat-navigation-performance.i18n.yaml index 257088effa..d8ea21a542 100644 --- a/.agents/notes/implemented/architecture/2026-09-18-chat-navigation-performance.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-18-chat-navigation-performance.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-18-chat-navigation-performance.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-18-chat-navigation-performance.md -2026-09-18-chat-navigation-performance.md: d82c68098fc422abb181ed4e5e1ca41189cd0951 -2026-09-18-chat-navigation-performance.zh.md: 9c2f81a51ce53660aabf2dd1e729d02e8028b7b6 +/agent-note-bound-turn-navigation-work-and-batch-historical-jumps: + en: c37ea37bfa045a00 + zh: 88a75b8739e99fb5 +/agent-note-bound-turn-navigation-work-and-batch-historical-jumps/problem: + en: c3ca28379b414fc5 + zh: 4a25378cef3f2259 +/agent-note-bound-turn-navigation-work-and-batch-historical-jumps/decision: + en: a15c7c13f167e5ac + zh: a15c7c13f167e5ac +/agent-note-bound-turn-navigation-work-and-batch-historical-jumps/decision/fixed-pitch-virtual-rail: + en: 79e61c0dbffe6f01 + zh: 47dd4758d115f8bb +/agent-note-bound-turn-navigation-work-and-batch-historical-jumps/decision/two-layer-transcript-navigation: + en: 022a8ad83ac099f1 + zh: b4393e39bfdd401d +/agent-note-bound-turn-navigation-work-and-batch-historical-jumps/decision/one-publication-per-historical-jump: + en: 510e80edc58ebdea + zh: cfbff46bff1e43bb +/agent-note-bound-turn-navigation-work-and-batch-historical-jumps/decision/theoretical-work-model: + en: 6786e39e812ad355 + zh: eca00072cf880a08 +/agent-note-bound-turn-navigation-work-and-batch-historical-jumps/alternatives-considered: + en: f590762936560d5c + zh: 0fc836bf1841733e +/agent-note-bound-turn-navigation-work-and-batch-historical-jumps/consequences: + en: 5f50c3d4a539f48c + zh: 5aee80a99d52233e diff --git a/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.i18n.yaml index 8c41c47eeb..1f07fe4f8b 100644 --- a/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-18-declarative-agent-presets.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.md -2026-09-18-declarative-agent-presets.md: 55ec173b33b7ddd62c88c68afc8b7546074aae0a -2026-09-18-declarative-agent-presets.zh.md: 60c81de4d981818f805b1014c2e3f05f16d1e8a9 +/agent-note-declarative-agent-presets-and-retained-revisions: + en: 0a9b9ab7a29ddce9 + zh: 10893a464cde0f97 +/agent-note-declarative-agent-presets-and-retained-revisions/problem: + en: 725f773bb350218e + zh: dd8fbc09ef48208d +/agent-note-declarative-agent-presets-and-retained-revisions/decision: + en: 2a2489303fc76fc0 + zh: 1a760e9a5edfccc8 +/agent-note-declarative-agent-presets-and-retained-revisions/alternatives-considered: + en: 09f40eab4659e9f6 + zh: 7a70da0d0ae6845b +/agent-note-declarative-agent-presets-and-retained-revisions/consequences: + en: 24179c31261b0942 + zh: 651c61bb5e53fd78 +/agent-note-declarative-agent-presets-and-retained-revisions/testing: + en: d1a38a45212d4ebd + zh: 6ca7a86078515284 diff --git a/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.md b/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.md index 55ec173b33..bf900bc4dc 100644 --- a/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.md +++ b/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.md @@ -16,7 +16,7 @@ The registry owns each revision's scope and Loader tree. Agents link their own s The Web editor and `agent_preset` tool accept only child plugin YAML. Saving writes the active profile's user patch, preserving display metadata and unrelated configuration. Revision checks and profile locking prevent overwriting concurrent saves; validation rejects a higher-priority override that would defeat the edit. Persistence and activation outcomes are reported separately. Tool writes require approval or full access because configuration executes in the Host. -Session data continues to record the preset identity. Restart resolves that identity against current configuration and rejects a missing definition. Old executable revisions are process-local, not serialized. The existing chooser policy and blank-session selection remain: hiding the chooser uses the deployment default without deleting the saved user preference. +Session data continues to record the preset identity. Restart resolves that identity against current configuration and rejects a missing definition. Old executable revisions are process-local, not serialized. The saved user default and blank-session selection remain; `selectedDefault` is what an unnamed new session resolves, and the Client's Developer tools preference decides only whether the choice is shown. ## Alternatives considered diff --git a/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.zh.md b/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.zh.md index 60c81de4d9..21611da37f 100644 --- a/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.zh.md @@ -16,7 +16,7 @@ Preset 目录重复承担 Cordis 配置的所有权。独立的发现、元数 Web 编辑器与 `agent_preset` 工具只接受子插件 YAML。保存写入当前 profile 的用户补丁,保留显示元数据和无关配置。版本检查和 profile 锁防止覆盖并发保存;验证拒绝会使编辑失效的更高优先级覆盖。持久化与激活结果分别报告。配置在 Host 中执行,因此工具写入需要批准或完全访问权限。 -会话数据继续记录 preset 标识。重启时根据当前配置解析该标识,定义缺失则拒绝恢复。旧的可执行代际仅保留在进程内,不会序列化。现有选择器策略和空白会话选择保持不变:隐藏选择器使用部署默认值,但不删除保存的用户偏好。 +会话数据继续记录 preset 标识。重启时根据当前配置解析该标识,定义缺失则拒绝恢复。旧的可执行代际仅保留在进程内,不会序列化。保存的用户默认值与空白会话选择保持不变:未指定 preset 的新会话解析 `selectedDefault`,客户端的开发者工具偏好只决定是否展示这项选择。 ## Alternatives considered diff --git a/.agents/notes/implemented/architecture/2026-09-18-localized-package-metadata.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-18-localized-package-metadata.i18n.yaml index 89a7fa2cc4..828454ccca 100644 --- a/.agents/notes/implemented/architecture/2026-09-18-localized-package-metadata.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-18-localized-package-metadata.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-18-localized-package-metadata.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-18-localized-package-metadata.md -2026-09-18-localized-package-metadata.md: a7e41cccbbce63547e8e5f175ec2350bcf515bc2 -2026-09-18-localized-package-metadata.zh.md: d70aed2a57db4c474245806d4bd3db0129f4beb4 +/agent-note-plugin-owned-localized-display-metadata: + en: b78ee8e580f068ea + zh: 17dd59c9b6273897 +/agent-note-plugin-owned-localized-display-metadata/problem: + en: 4022a58baf82e77d + zh: 8439268ed4df9b69 +/agent-note-plugin-owned-localized-display-metadata/decision: + en: f6c3e24681977f48 + zh: 84ae52ec62f4af96 +/agent-note-plugin-owned-localized-display-metadata/existing-decisions: + en: a84f44d6a3179d47 + zh: 8fb62f08bec5f75d +/agent-note-plugin-owned-localized-display-metadata/alternatives-considered: + en: abbdb1b8ab360380 + zh: edfe6c06b1d67fd7 +/agent-note-plugin-owned-localized-display-metadata/verification: + en: 8541a2431321ef61 + zh: 77599e0855d93da9 +/agent-note-plugin-owned-localized-display-metadata/consequences: + en: 2a4547c9657038df + zh: 1a4bebd06d2b9e38 diff --git a/.agents/notes/implemented/architecture/2026-09-18-plugin-install-registries.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-18-plugin-install-registries.i18n.yaml index 7ca268a8fc..ac4c62e4a0 100644 --- a/.agents/notes/implemented/architecture/2026-09-18-plugin-install-registries.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-18-plugin-install-registries.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-18-plugin-install-registries.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-18-plugin-install-registries.md -2026-09-18-plugin-install-registries.md: bee870a87b1f5427af8f05a32396bd52bd1524b7 -2026-09-18-plugin-install-registries.zh.md: 65fe35c78910d1cdf1ce45aea7d9fa7ae8617006 +/agent-note-plugin-install-registries: + en: 88c789616a978d0c + zh: 27c9b37d12be8a6a +/agent-note-plugin-install-registries/problem: + en: 0b7713b33c9b665b + zh: eab1dac3e14c8587 +/agent-note-plugin-install-registries/decision: + en: 23bb185c5795943d + zh: 7939b6a738290adf +/agent-note-plugin-install-registries/alternatives-considered: + en: 247f164eaf0196fa + zh: 7863dcfed12161c0 +/agent-note-plugin-install-registries/consequences: + en: 9a4c2233b869350a + zh: 86562a4c8573d1c1 +/agent-note-plugin-install-registries/testing: + en: 6c7a39b22be31df7 + zh: 6eee9b14ed9be704 diff --git a/.agents/notes/implemented/architecture/2026-09-18-profile-plugin-host-runtime-instances.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-18-profile-plugin-host-runtime-instances.i18n.yaml index d8c7d77519..4325837109 100644 --- a/.agents/notes/implemented/architecture/2026-09-18-profile-plugin-host-runtime-instances.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-18-profile-plugin-host-runtime-instances.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-18-profile-plugin-host-runtime-instances.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-18-profile-plugin-host-runtime-instances.md -2026-09-18-profile-plugin-host-runtime-instances.md: 76135318b3a935e4588c360df3210618a6c69216 -2026-09-18-profile-plugin-host-runtime-instances.zh.md: b2229574876b0ad326348ababd6b6fca6f3a1ac2 +/agent-note-profile-plugins-share-the-installation-s-host-runtime-instances: + en: 04d5248dde932469 + zh: 877d263ca4b0beef +/agent-note-profile-plugins-share-the-installation-s-host-runtime-instances/problem: + en: f9c4830ba4be20bc + zh: be46323e2eae9247 +/agent-note-profile-plugins-share-the-installation-s-host-runtime-instances/decision: + en: bcd92c487ebfab32 + zh: c50478b864562f0d +/agent-note-profile-plugins-share-the-installation-s-host-runtime-instances/alternatives-considered: + en: 1443d5fc869ffcf9 + zh: 76b21473d2892e7f +/agent-note-profile-plugins-share-the-installation-s-host-runtime-instances/consequences: + en: 075067e84219ae67 + zh: 035c60f3e11783d5 diff --git a/.agents/notes/implemented/architecture/2026-09-18-volatile-config-references.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-18-volatile-config-references.i18n.yaml index ef7c78129d..729ecfe793 100644 --- a/.agents/notes/implemented/architecture/2026-09-18-volatile-config-references.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-18-volatile-config-references.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-18-volatile-config-references.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-18-volatile-config-references.md -2026-09-18-volatile-config-references.md: afaa6affdc3d18da182ec069126033cb55393b72 -2026-09-18-volatile-config-references.zh.md: 3d8800cb92dec4da80b698cb8b3c073331ed266f +/agent-note-volatile-configuration-references: + en: 6a5845c609acc131 + zh: f63fc95d58f06272 +/agent-note-volatile-configuration-references/problem: + en: da97e9a3eabc9a36 + zh: bca53a3021689d06 +/agent-note-volatile-configuration-references/decision: + en: 5798a8dd943987b1 + zh: 090d2b49958c3158 +/agent-note-volatile-configuration-references/alternatives-considered: + en: cf68e95cde8ff288 + zh: 817667d5c8c93056 +/agent-note-volatile-configuration-references/consequences: + en: 7941168bdfa2dc96 + zh: 29385474a4902a8a diff --git a/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.i18n.yaml index a66f2afe77..93be98ebc5 100644 --- a/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-lossless-projection-checkpoint-json.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-19-lossless-projection-checkpoint-json.md -2026-09-19-lossless-projection-checkpoint-json.md: 9c7d15dbd2d570eaa544f168d2c2ef882558d5ca -2026-09-19-lossless-projection-checkpoint-json.zh.md: 8c2b720358351af33a6d07888002c65d0cc30363 +/agent-note-lossless-projection-checkpoint-json: + en: 2b7b5f9e5da030df + zh: 76d65ddc85776939 +/agent-note-lossless-projection-checkpoint-json/problem: + en: 26e613246f31ee5a + zh: e0aa1e2f63bce802 +/agent-note-lossless-projection-checkpoint-json/decision: + en: 01161e9c42142971 + zh: e05e52d2af7fc4c5 +/agent-note-lossless-projection-checkpoint-json/alternatives-considered: + en: 1d64345d3d72ed5f + zh: 4c9d3410cfd815b3 +/agent-note-lossless-projection-checkpoint-json/consequences: + en: 94b619dc13cfff0b + zh: c432227d3333175f diff --git a/.agents/notes/implemented/architecture/2026-09-19-profile-owned-live-configuration.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-19-profile-owned-live-configuration.i18n.yaml index 8c966f2cfd..599afcc6f0 100644 --- a/.agents/notes/implemented/architecture/2026-09-19-profile-owned-live-configuration.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-19-profile-owned-live-configuration.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-profile-owned-live-configuration.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-19-profile-owned-live-configuration.md -2026-09-19-profile-owned-live-configuration.md: 7acf10986987960a9748308c9fe19060a97cfcc0 -2026-09-19-profile-owned-live-configuration.zh.md: c9b88462a5e0a8601d9dcd83f7d82b49e7ce5b5c +/agent-note-keep-live-configuration-in-the-owning-profile: + en: 4331f70f04ab7bac + zh: 68dece695f6f43a8 +/agent-note-keep-live-configuration-in-the-owning-profile/problem: + en: 2abacff687661d28 + zh: 2d7ba3ae27dba888 +/agent-note-keep-live-configuration-in-the-owning-profile/decision: + en: 66c3884425cfb90a + zh: 0fe6a1f1a576470b +/agent-note-keep-live-configuration-in-the-owning-profile/alternatives-considered: + en: 4089464ad1fb60bd + zh: 3168e9e4a205145d +/agent-note-keep-live-configuration-in-the-owning-profile/consequences: + en: 6033aaa12b2a521b + zh: 43934413c97670de diff --git a/.agents/notes/implemented/architecture/2026-09-19-profile-resolution-lookup-order.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-19-profile-resolution-lookup-order.i18n.yaml index da2d68745b..8892007905 100644 --- a/.agents/notes/implemented/architecture/2026-09-19-profile-resolution-lookup-order.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-19-profile-resolution-lookup-order.i18n.yaml @@ -1,6 +1,64 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-profile-resolution-lookup-order.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-19-profile-resolution-lookup-order.md -2026-09-19-profile-resolution-lookup-order.md: 6dfb5511afe885875a778b8a4f1b7c5fc3c0d842 -2026-09-19-profile-resolution-lookup-order.zh.md: 2474a9b040cb4917e71b7002d36c1e61fe3bc106 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer: + en: 7754ffbd03cff339 + zh: cbf34c74b346654a +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/problem: + en: 51374538814c0796 + zh: ebd74420bec9687a +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision: + en: d69f81d4fc545e29 + zh: 9fc532af8015cb28 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-1-resolution-rules: + en: de6ea16534218e69 + zh: fd8e1d470a2cf056 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-1-resolution-rules/1-the-ancestor-chain-node-s-ancestor-node-modules-lookup: + en: 197a263bc0152b74 + zh: ab05b5033f0a74e0 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-1-resolution-rules/2-the-interception-layer-the-runtime-resolution-occupies-dsh-home-profiles-node-modules-package: + en: 7acd592cb967f08f + zh: 5b20fd69c832287b +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-1-resolution-rules/3-linked-directories-peer-interception-at-each-ancestor-position: + en: 8b0ded021ddb87b4 + zh: 2f4d5c33dadf50e7 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-1-resolution-rules/4-what-the-interception-layer-holds-the-runtime-resolution-s-scan-contents: + en: 5fffd66f08d4b977 + zh: 020ef8953b20cc8a +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-1-resolution-rules/5-hook-coverage: + en: 644f6f9a6ff8d6c8 + zh: 7a81f928551e9041 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-1-resolution-rules/6-package-directories-and-module-files: + en: c85f82cb1c60360e + zh: c535f1c0ec58345e +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-2-walkthroughs: + en: 906e0d58e3c2aff3 + zh: ccc3a709034865b9 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-2-walkthroughs/table-1-ancestor-chain-and-interception-for-esm-and-commonjs-across-request-forms: + en: c88d52e8715281f6 + zh: f69aaf44655bc935 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-2-walkthroughs/table-2-interception-position-for-the-web-and-desktop-profiles: + en: e9dce1779952a066 + zh: d51cf26a192f3f91 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-2-walkthroughs/table-3-ancestor-chain-when-a-plugin-is-linked-outside-the-tree: + en: 6fc9735fac937ec2 + zh: e9502a116339c7c3 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-3-developer-integration-guide: + en: 35f27b53d995d59f + zh: 58a47c7bfced79a0 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-3-developer-integration-guide/1-normal-installation: + en: d0bed60317e6e3a8 + zh: 5714160678adc049 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/decision/part-3-developer-integration-guide/2-development-mode-the-plugin-repository-is-outside-the-profile-tree: + en: d7ec5a747ebcb93e + zh: 7e1d0724973b32c1 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/alternatives-considered: + en: 5466618bb5e3d4d9 + zh: 7d0b6d727e33d0d1 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/verification: + en: 328fbaca95eac5ff + zh: b41fbe45097d3ea9 +/agent-note-resolve-profile-modules-along-the-ancestor-chain-with-an-interception-layer/consequences: + en: 4a748267ef8d0480 + zh: 0ecc79b3c82bf9bb diff --git a/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.i18n.yaml index ea121beb8c..938a007c31 100644 --- a/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.i18n.yaml @@ -1,6 +1,49 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-projection-cache-listing-identity-and-cached-rows.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.md -2026-09-19-projection-cache-listing-identity-and-cached-rows.md: 61b82e5003ba4b634230941f5d3df65e65491e25 -2026-09-19-projection-cache-listing-identity-and-cached-rows.zh.md: ef49d90bc68ca501f7496adbac1d1aa8a5d706a7 +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows: + en: 04813e762d48995c + zh: b0ed6656adc7c5f0 +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/problem: + en: 2e7f99c81fbc941f + zh: b0fac7cd5eb86ffe +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/problem/mechanism: + en: 36d24e92eedf8cea + zh: 5dafc5758ee0f380 +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/problem/the-cache-s-two-uses-and-where-validation-lives: + en: 055ead18162ca1cd + zh: 9046bf04229e45d1 +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/problem/the-client-store-cannot-guarantee-that-connected-data-replaces-hints: + en: 597b346459a9d8b0 + zh: f7282a40061d645c +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/decision: + en: a15c7c13f167e5ac + zh: a15c7c13f167e5ac +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/decision/two-read-faces-the-cut-is-compared-only-on-the-fold-face: + en: 30bb0f92e2ba046b + zh: 25ae7e78a5887643 +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/decision/why-the-read-only-face-may-skip-the-cut: + en: 1138b58239be186b + zh: cf5fc5f1d3f21bd3 +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/decision/consumers: + en: 743f2dceda3072aa + zh: f4d53ddc13a4127e +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/decision/the-client-store-separates-cached-and-sequenced-rows: + en: 8a4e9e9ac2ada06f + zh: b5884535cd934f72 +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/decision/what-stays-untouched: + en: 1cefba02bbfb2647 + zh: 5a96942565ab9d72 +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/decision/worst-case-walked-through: + en: 396d75331b3b0143 + zh: 2eb41ac09de87de0 +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/alternatives-considered: + en: d71031c0dc256d80 + zh: 753c948a90a0c9ad +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/consequences: + en: 525ea6842ad2e19a + zh: 595da1db20255617 +/agent-note-projection-cache-read-only-face-matches-the-lifecycle-identity-the-client-store-separates-cached-and-sequenced-rows/testing: + en: 8faa78adc442992c + zh: 29cb78232985fd47 diff --git a/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.md b/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.md index 61b82e5003..bfdd8bda22 100644 --- a/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.md +++ b/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.md @@ -14,13 +14,12 @@ This is neither cache corruption nor a version mismatch. The projcache record's A cache record (record format and predecessor recovery: [Projection-cache predecessor recovery and Session-format binding](2026-09-02-projcache-cross-version-read-compat.md)) is bound to a lifecycle identity: `formatVersion + createdAt + cwd + isSeeded + inheritedEventCount`, matched by `identityMatches` on full equality. Since #3346, `inheritedEventCount` (the length of the event prefix a fork inherits, the cut below) no longer appears in the logical header: the header keeps only the `isSeeded` bit and the exact cut follows the body. Since Session format v2 (#3398) the physical header line no longer stores `seedLength` either; the reader derives the cut from the seq of the `session/end-seed {inherited: true}` marker in the body. -A header-only read therefore cannot obtain the cut: the JSONL backend's `fromHeaderLine` hard-codes `inheritedEventCount: 0` for header-only reads, and `SessionPersistenceSnapshot` carries only the header, the revision, and an optional eventCount. All three header-only cache consumers grew the same guard: +A header-only read therefore cannot obtain the cut: the JSONL backend's `fromHeaderLine` hard-codes `inheritedEventCount: 0` for header-only reads, and `SessionPersistenceSnapshot` carries only the header, the revision, and an optional eventCount. The Session-list and reference consumers grew the same guard: | Consumer | Guard | Fallback | Consequence | |---|---|---|---| | `packages/api/session-controller/src/list.ts` `projectionsFor` | `header.isSeeded ? undefined : cachedSnapshot(header, 0) ?? cachedPredecessorTitle(header, 0)` | none | no title, no `sessionListMetadata`; blank falls back to `false`, ordering falls back to `createdAt` | | `packages/context/session-reference/src/index.ts` `projectedLabels` | same | none | `@` completion labels by id; the title cannot be searched | -| `packages/subagent/subagent/src/list-children.ts` `resolveColdIdentity` | same | `observeSession` reads the body | correct result, one body read per seeded child | When the guard landed (#3346, 2026-09-01), `list.ts` still had `probeSmallCold`: on a cache miss it read the body when the log file was at most `DEFAULT_COLD_BLANK_PROBE_MAX_BYTES = 1024` bytes. Its purpose was blank-session detection; it covered only logs under 1KB and never applied to an ordinary fork. #3400 (2026-09-03) removed it and the list returned to metadata plus cache only. #4320 (2026-09-19) made forking a first-class feature (`packages/core/session/src/fork.ts`, fork at any seq); every fork is `isSeeded: true` with an exact cut, seeded sessions went from a handful to dozens, all of them cold after a restart, and the gap became visible at once. @@ -33,7 +32,7 @@ The read and write faces of `SessionProjectionCache` and their callers: | `write(session)` | writes the checkpoint at three mandatory points plus a throttle | yes | the cache's own listeners | | `hydratePrepared(session, events)` | uses `rows` as the fold starting point and applies events from `row.seq + 1`; the result lands in live cells | the next checkpoint | `session-query/src/observation.ts` | | `coldSnapshot(meta, cut, events)` | fold starting point plus write-back | yes | no production caller | -| `cachedSnapshot(meta, cut, keys?)` | `viewCheckpoint`: each row passes `ver` and `stateSchema`, is `view`ed, and returned | no | `list.ts`, `session-reference`, `list-children` | +| `cachedSnapshot(meta, cut, keys?)` | `viewCheckpoint`: each row passes `ver` and `stateSchema`, is `view`ed, and returned | no | `list.ts`, `session-reference` | | `cachedPredecessorTitle(meta, cut)` | the same, `title` only, allowing an older `formatVersion` | no | `list.ts` | Identity validation lives entirely inside the cache (`recordFor` → `identityMatches`; `viewCheckpoint` checks `ver` and schema per row). `list.ts` validates nothing itself; it merely declines to call when it cannot supply a cut. @@ -70,7 +69,6 @@ In the block the read-only face returns, `asOfSeq` is the lowest watermark among |---|---| | `list.ts` `projectionsFor` | drop the `isSeeded` branch and `SessionLogOffset(0)`; every cold row reads `cachedSnapshot(header) ?? cachedPredecessorTitle(header)` | | `session-reference` `projectedLabels` | same symptom, same change | -| `list-children.ts` `resolveColdIdentity` | follows the signature only; the `!header.isSeeded` guard and the body fallback stay, because it needs the cut to classify a seq as inherited or owned, which is fold semantics | ### The client store separates cached and sequenced rows @@ -147,7 +145,7 @@ Bought: Paid: -- `cachedSnapshot` and `cachedPredecessorTitle` change signature; three callers change with them. +- `cachedSnapshot` and `cachedPredecessorTitle` change signature; the Session-list and reference callers use the header-only signatures. - `SessionProjectionHints` gains the required field `kind`; every producer of a list summary and every test fixture that builds one carries it. - A hand-crafted record with the same four fields and a different cut is displayed in the list until the session is opened. - Keys the baseline omits clear together with their hints: when a Host does not mount `schedule`, the schedule mark the list hinted disappears after the session opens. Under "connected data is the truth" this is the correct behavior. @@ -163,4 +161,3 @@ Paid: - `api/session-controller/tests/manager.client.spec.ts`: a `cached` `api-session/added` block is replaced by a control baseline at the same cursor; a `cached` list block does not displace an existing sequenced title. - `api/session-controller/tests/inbox-projection.client.spec.ts`: unchanged; a live session's `sequenced` list block still outranks a delayed control baseline at a lower cut. - `context/session-reference/tests/session-reference.spec.ts`: a seeded cold session is labeled and searchable by its cached title, a session without a cache record is still labeled by id, and neither reads a log. -- `subagent/subagent/tests/list-children.spec.ts`: unchanged; seeded children still go through body observation. diff --git a/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.zh.md b/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.zh.md index ef49d90bc6..470c96385c 100644 --- a/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-19-projection-cache-listing-identity-and-cached-rows.zh.md @@ -14,13 +14,12 @@ Host 进程重启后,所有 fork 出来的会话(`SessionHeader.isSeeded === 缓存记录(记录格式与前代恢复见 [投影缓存前代恢复与 Session 格式绑定](2026-09-02-projcache-cross-version-read-compat.zh.md))绑定一份 lifecycle identity:`formatVersion + createdAt + cwd + isSeeded + inheritedEventCount`,`identityMatches` 做全等匹配。其中 `inheritedEventCount`(fork 继承的事件前缀长度,下称 cut)从 #3346 起不再出现在逻辑 header 里:header 只保留 `isSeeded` 这一位,精确 cut 跟随正文。Session 格式 v2 起(#3398),物理 header 行也不再存 `seedLength`,reader 从正文里 `session/end-seed {inherited: true}` 标记的 seq 推出 cut。 -于是 header-only 的读取拿不到 cut:JSONL 后端 `fromHeaderLine` 对 header-only 读取硬编码 `inheritedEventCount: 0`,`SessionPersistenceSnapshot` 只有 header、revision 和可选的 eventCount。三个只读 header 的缓存消费者都因此加了同一个守卫: +于是 header-only 的读取拿不到 cut:JSONL 后端 `fromHeaderLine` 对 header-only 读取硬编码 `inheritedEventCount: 0`,`SessionPersistenceSnapshot` 只有 header、revision 和可选的 eventCount。Session 列表与引用消费者都因此加了同一个守卫: | 消费者 | 守卫 | 兜底 | 后果 | |---|---|---|---| | `packages/api/session-controller/src/list.ts` `projectionsFor` | `header.isSeeded ? undefined : cachedSnapshot(header, 0) ?? cachedPredecessorTitle(header, 0)` | 无 | 无 title,无 `sessionListMetadata`,blank 判定退到 `false`,排序退到 `createdAt` | | `packages/context/session-reference/src/index.ts` `projectedLabels` | 同 | 无 | `@` 补全按 id 显示,搜不到 title | -| `packages/subagent/subagent/src/list-children.ts` `resolveColdIdentity` | 同 | `observeSession` 读正文 | 结果正确,每个 seeded 子代一次正文读 | 守卫存在时(#3346,2026-09-01),`list.ts` 还有 `probeSmallCold`:缓存 miss 且日志文件不超过 `DEFAULT_COLD_BLANK_PROBE_MAX_BYTES = 1024` 字节时读正文补全。它的目的是识别 blank 会话,只覆盖不到 1KB 的日志,对正常 fork 从未生效。#3400(2026-09-03)删掉它,列表回到纯元数据加缓存。#4320(2026-09-19)把 fork 变成一等功能(`packages/core/session/src/fork.ts`,任意 seq fork),每个 fork 都是 `isSeeded: true` 加精确 cut,seeded 会话数量从个位数变成几十条,重启后全部冷,问题集中显形。 @@ -33,7 +32,7 @@ Host 进程重启后,所有 fork 出来的会话(`SessionHeader.isSeeded === | `write(session)` | 三个强制点加节流写 checkpoint | 有 | 缓存内部监听 | | `hydratePrepared(session, events)` | 把 `rows` 当 fold 起点,从 `row.seq + 1` 继续 apply,结果进 live cell | 后续 checkpoint 写回 | `session-query/src/observation.ts` | | `coldSnapshot(meta, cut, events)` | fold 起点加回写 | 有 | 无生产调用方 | -| `cachedSnapshot(meta, cut, keys?)` | `viewCheckpoint`:每行过 `ver` 和 `stateSchema`,`view` 后返回 | 无 | `list.ts`、`session-reference`、`list-children` | +| `cachedSnapshot(meta, cut, keys?)` | `viewCheckpoint`:每行过 `ver` 和 `stateSchema`,`view` 后返回 | 无 | `list.ts`、`session-reference` | | `cachedPredecessorTitle(meta, cut)` | 同上,只看 `title`,允许更旧的 `formatVersion` | 无 | `list.ts` | 身份校验全部在缓存内部(`recordFor` → `identityMatches`;`viewCheckpoint` 逐行校验 `ver` 与 schema)。`list.ts` 自己不校验,只是给不出 cut 时不调。 @@ -70,7 +69,6 @@ spec.ts 与 README 描述身份检查的目的时用的都是同一个动词: |---|---| | `list.ts` `projectionsFor` | 删 `isSeeded` 分支和 `SessionLogOffset(0)`,冷会话统一 `cachedSnapshot(header) ?? cachedPredecessorTitle(header)` | | `session-reference` `projectedLabels` | 同一症状,同一改法 | -| `list-children.ts` `resolveColdIdentity` | 只跟随签名,`!header.isSeeded` 守卫和正文兜底原样保留;它需要 cut 做 inherited/owned 分类,属于 fold 语义 | ### 客户端 store 区分 cached 与 sequenced 行 @@ -147,7 +145,7 @@ seq 比较只在同一条 Host 连接内发生:`handleConnected` 先整表 `cl 付出的: -- `cachedSnapshot` 与 `cachedPredecessorTitle` 签名变化,三个调用方同步修改。 +- `cachedSnapshot` 与 `cachedPredecessorTitle` 签名变化,Session 列表与引用调用方使用仅需 header 的签名。 - `SessionProjectionHints` 新增必填字段 `kind`,所有产出列表摘要的地方和构造摘要的测试夹具都要带上。 - 手工构造的同四字段、不同 cut 的记录会在列表上显示到会话被打开为止。 - 基线没带的键连提示一起清掉:某个 Host 未挂载 `schedule` 时,打开会话后列表提示过的 schedule 标记消失。按"建连数据是真值"这是正确行为。 @@ -163,4 +161,3 @@ seq 比较只在同一条 Host 连接内发生:`handleConnected` 先整表 `cl - `api/session-controller/tests/manager.client.spec.ts`:`api-session/added` 的 `cached` block 被同 cursor 的 control 基线替换;`cached` 列表 block 不覆盖已有的 sequenced title。 - `api/session-controller/tests/inbox-projection.client.spec.ts`:不变,活会话的 `sequenced` 列表 block 仍压过延迟到达、cut 更低的 control 基线。 - `context/session-reference/tests/session-reference.spec.ts`:seeded 冷会话按缓存 title 标注并可按 title 搜到,没有缓存记录的会话仍按 id 标注,两者都不读日志。 -- `subagent/subagent/tests/list-children.spec.ts`:不变,seeded 子代仍走正文观察。 diff --git a/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.i18n.yaml index d5903d0fc2..eba3d7545a 100644 --- a/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.i18n.yaml @@ -1,6 +1,142 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-remote-duplex-stream.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.md -2026-09-19-remote-duplex-stream.md: 0f1f6a575f6871d37822c5829fe4531261b8e95b -2026-09-19-remote-duplex-stream.zh.md: d3982aa433aa3ce84b945bb5831cef8064472853 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context: + en: c52d4b55f470a50f + zh: d2d446516b1011bc +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/problem: + en: 70a969dce3283824 + zh: 18c61bf840a6518a +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/problem/current-state: + en: 8fb06638898de59e + zh: 79ed0cfe79e40be1 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/problem/three-unrelated-uplink-mechanisms: + en: 386be7b691ab63e7 + zh: 935e0db22ae1cf5d +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/problem/concrete-costs: + en: f374976b43645d15 + zh: 26b2c7aaafa41fba +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/problem/relation-to-background-jobs: + en: 5e67475010d52ddb + zh: ce23aad2d4aa0d67 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/problem/goals: + en: 1f8e6d20dd4b2bf7 + zh: c6939e72e9bac277 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision: + en: a15c7c13f167e5ac + zh: ff261e3705c47ff0 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/in-one-sentence: + en: 943208904785f7eb + zh: bda1969132a16101 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/terms: + en: 401703adbd9cc1c2 + zh: 56d960c0b6fdff57 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/type-signatures: + en: 5f9cd00890b6f4c3 + zh: 600ecba7e60b63f6 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/host-face: + en: 37f59749e1703ca8 + zh: d220eded761d83c0 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/host-face/how-the-invocation-context-reaches-the-method: + en: a7180d3c194cf9d9 + zh: 0dd7833e0e5d0a71 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/peerscope: + en: 202aa6e8e8b04bd6 + zh: b1fc897c09074a7c +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/client-face: + en: 9f10347a73402b8b + zh: b939c7a254a8e579 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/wire-frames: + en: 490c19bf403bc76f + zh: 55ad5cff840d0421 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/logical-stream-state-machine: + en: 438963f156ea05b1 + zh: e738fca49b9bc1cc +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/logical-stream-state-machine/host-side: + en: 959d7f191895af71 + zh: 9b70e5e36233e301 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/logical-stream-state-machine/client-side: + en: 6a6f94f54a29c1ed + zh: 1306602bae8a219b +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/half-close-and-termination: + en: 52e2097ea66452e8 + zh: 0cc058365773a792 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/cancellation-wait-lifetime: + en: a21405b6607345a7 + zh: 70b3be4327ab59d5 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/ordering-guarantees: + en: d176a388014d0bf8 + zh: db4a4988dcb36690 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/backpressure: + en: 607a1afd89892d15 + zh: a0aa85124340458c +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/security-and-validation: + en: 46a0c0b3ce1e5671 + zh: 7743707de42b1d1d +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/in-process-and-worker-carriers: + en: ec339e57dc2c0603 + zh: 3570be8c094ea24c +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/decision/relation-to-events: + en: a011793e5a4400ed + zh: df8b20115f0348b8 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/type-and-wire-definitions: + en: b8a63bcefdea2704 + zh: d2aa576cf736b1b7 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/type-and-wire-definitions/typert-protocol-packages-typert-protocol-src: + en: e1b2ae30d8a8a62d + zh: 8790a068aa3a10e9 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/type-and-wire-definitions/typert-generator-packages-typert-generator-src: + en: 3b0b1398141b9a3d + zh: 6a96f6785c59dad3 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/type-and-wire-definitions/two-names-one-entry-point: + en: 59188926c8e586de + zh: 3298be0413d14274 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/type-and-wire-definitions/gateway-host-packages-api-gateway-src: + en: 9c8122ce6048a432 + zh: 58f28ebe6d484a9d +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/type-and-wire-definitions/gateway-host-mux-stream-server-ts: + en: eb4b18a979c0665d + zh: 148bf697825ddc49 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/type-and-wire-definitions/gateway-client-packages-api-gateway-src-client: + en: 26dcd8bebdc8d974 + zh: e74bcef7c549e70c +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/placement: + en: 41128746334320c7 + zh: 558a676340aae3a2 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/key-sequences: + en: 130e4f9ec7296a10 + zh: 2a5aa1302a8db61a +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/key-sequences/open-uplink-half-close-downlink-end: + en: 3e8f671254c2b462 + zh: d2dba924dfc0f09e +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/key-sequences/client-dispose: + en: a5b474d42af07bd9 + zh: df2bd41480beb07e +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/key-sequences/inbox-overflow: + en: 32b009b9d90dc36c + zh: 52590ffa9bf9f90b +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/boundary-matrix: + en: c6a08daa98e3c189 + zh: 0c9dbe16f4cdaa79 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/error-codes: + en: 7da8cacc0a6892f2 + zh: e22ca8d3d9161568 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/minimal-echo-method: + en: b42ab0932f8b31b4 + zh: 7fed8cb5b6e36788 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/alternatives-considered: + en: 04e72789417d6e3a + zh: b57c5cc68dff45a5 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/consequences: + en: 07524e0c2dc22ad5 + zh: 5bf4f27160d78b43 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/testing: + en: 5c8188930b9d4fdb + zh: 1d94e6563cedde13 +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/deferred: + en: 3b99a327464edc3e + zh: dcffdc75369925dc +/agent-note-remote-duplex-stream-one-kind-of-stream-an-uplink-channel-and-an-invocation-context/related: + en: f8995f478dc1d478 + zh: 96621e80a4d3cefc diff --git a/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.md b/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.md index 0f1f6a575f..ea8e8cebcc 100644 --- a/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.md +++ b/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.md @@ -276,6 +276,12 @@ Parsing rules: `item` has exactly the keys `type` and `streamId` plus an optiona | `item` received after `end` | Any | The stream fails with a `gateway/protocol` error frame and aborts; the socket stays open | | `item` / `end` with an unknown `streamId` | Any | Ignored, like `cancel`: after the Host ends a stream and deletes its id, uplink frames still in flight from the Client are normal and must not take down the other streams on the same socket | +### Cancellation wait lifetime + +`cancellableStream`, `UplinkDecoder.next()`, and the Client uplink pump each create a cancellation or stop promise per read. `Promise.race` does not remove the losing input's reaction when a read completes: reusing a stream-wide pending promise retains completed races and their item results until that promise settles or becomes unreachable. Read-local promises keep retained cancellation state independent of the number of delivered items. + +The Host downlink clears its current reject callback after each read and checks cancellation before reading again. The uplink decoder retains only pending reads: abort rejects them, while normal close resolves all of them with `done`, including overlapping reads. The Client pump drops its stop promise after each read and does not start another read after stopping. Source iterators retain their existing release ownership; closing the Host uplink still precedes returning the method iterator. + ### Ordering guarantees Frames on one socket arrive in total order: a logical stream's `open`, `item`…, `end` reach the Host in send order, and uplink items enter `uplink()` in the order of `send`. There is no cross-direction ordering guarantee between uplink and downlink; a protocol that needs request-response pairing carries its own sequence numbers. @@ -538,6 +544,10 @@ for await (const reply of stream) replies.push(reply) // ['> a', '> b'] ## Alternatives considered +**A shared cancellation controller for all three reading loops.** Each loop already has an owner with distinct close behavior. Read-local promises bound retained state without moving those responsibilities into a new abstraction. + +**Requiring source iterators to cancel their own `next()`.** Gateway accepts arbitrary iterables, whose pending reads need not respond to cancellation or `return()`. Gateway must still wake its own waiters independently of source cleanup. + **A separate `mode: 'duplex'` plus a reserved parameter `uplink: AsyncIterable` alongside `signal`.** Special logic everywhere: the analyzer must recognize a second reserved parameter and its position rules, the generated signature gains a parameter, load time must validate `duplex ⟺ uplink`, and because the mux does not know the method mode, the Gateway must reject uplink frames on behalf of `'stream'` methods. Duplex is an inherent property of the transport-layer stream, not a mode of the method: the carrier already has `streamId`, `open`, and `cancel`; the uplink adds just two more frames, which any stream can receive and which are simply not sent when unused. **Declaring the uplink type in a decorator option, `@Remote({ mode: 'stream', uplink: 'JobInputFrame' })`.** A string reference to a type name is not checked by the compiler and breaks on rename. The return-type alias puts both types in one compiler-visible place. @@ -572,6 +582,8 @@ for await (const reply of stream) replies.push(reply) // ['> a', '> b'] ## Testing +Retention cases in `gateway-stream.host.spec.ts` and `gateway.client.spec.ts` count live iterator results after a full GC while the streams remain open. Lifecycle cases cover normal close waking multiple pending uplink reads, cancellation between reads, synchronous abort followed by a source exception, and termination during a Client send. + - `packages/api/gateway/tests/echo-stream.host.spec.ts`: the same echo method passes through the WebSocket carrier and through the in-process carrier. - Gateway Host: exact-key validation in frame parsing; `UplinkInbox` buffering during opening, `item` after `end`, overflow, ignored unknown `streamId`, and cleanup on socket closure; `UplinkDecoder` delivery with and without a codec and abort on decode failure; `uplink()` taken only once; the `extend({ invocation })` view and the origin of `peer`; `cancellableStream` closing the uplink before `return()`. - Gateway Client: the handle's `send` (JSON validation, queued before open, throws after termination), idempotent `end`, `dispose` driving the `cancel` frame and ending later reads; the pump's three exits; the pump stopping as soon as a terminal frame arrives. diff --git a/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.zh.md b/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.zh.md index d3982aa433..2e119bf054 100644 --- a/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-19-remote-duplex-stream.zh.md @@ -276,6 +276,12 @@ export type RemoteStreamServerMessage = | `end` 之后又收到 `item` | 任意 | 该流以 `gateway/protocol` 错误帧失败并中止;socket 不关闭 | | 未知 `streamId` 的 `item` / `end` | 任意 | 忽略,与 `cancel` 相同:Host 结束流并删除 id 后,客户端在途的上行帧属正常现象,不能连累同一 socket 上的其他流 | +### 取消等待的生命周期 + +`cancellableStream`、`UplinkDecoder.next()` 和 Client 上行泵各自为单次读取创建取消或停止 Promise。读取完成后,`Promise.race` 不会移除另一输入上的 reaction:复用流级未完成 Promise 会保留已完成的竞争及其读取结果,直到该 Promise 完成或不可达。单次读取的 Promise 使取消状态的保留量不随已交付项数增长。 + +Host 下行在每次读取后清除当前拒绝回调,并在再次读取前检查取消状态。上行解码器只保留尚未完成的读取:取消时拒绝这些读取,正常关闭则以 `done` 唤醒全部读取,包括重叠的读取。Client 泵在每次读取后移除停止 Promise,停止后不再发起读取。源迭代器的释放仍由原有所有者负责;Host 仍先关闭上行,再返回方法迭代器。 + ### 顺序保证 同一条 socket 上的帧全序到达:一条逻辑流的 `open`、`item`…、`end` 按发送顺序到达 Host;上行项进入 `uplink()` 的顺序就是 `send` 的顺序。上行与下行之间没有跨方向顺序保证;需要请求应答配对的协议自带序号。 @@ -538,6 +544,10 @@ for await (const reply of stream) replies.push(reply) // ['> a', '> b'] ## 考虑过的替代方案 +**三处读取循环共用一个取消控制器。** 每处循环已有自己的所有者和不同的关闭行为。单次读取的 Promise 能限制保留状态,不需要把这些职责迁入新抽象。 + +**要求源迭代器自行取消 `next()`。** Gateway 接受任意 iterable,其待处理读取不一定响应取消或 `return()`。Gateway 仍需独立于源清理来唤醒自己的等待者。 + **独立的 `mode: 'duplex'` 加一个与 `signal` 同级的保留参数 `uplink: AsyncIterable`。** 每一处都是特殊逻辑:analyzer 要认第二个保留参数及其位置规则,生成签名多一个参数,加载期要校验 `duplex ⟺ uplink`,mux 不知道方法模式所以网关要替 `'stream'` 方法拒绝上行帧。双工是传输层流的固有性质,不是方法的一种模式:载体本来就有 `streamId`、`open`、`cancel`,上行只是再加两种帧,任何流都能收,不用就不发。 **用装饰器选项声明上行类型,`@Remote({ mode: 'stream', uplink: 'JobInputFrame' })`。** 字符串引用类型名不受编译器约束,重命名即断。返回类型别名把两个类型写在同一个编译器可见的位置。 @@ -572,6 +582,8 @@ for await (const reply of stream) replies.push(reply) // ['> a', '> b'] ## 测试 +`gateway-stream.host.spec.ts` 和 `gateway.client.spec.ts` 中的保留对象用例在流保持打开时进行全量 GC,再统计存活的迭代结果。生命周期用例覆盖正常关闭唤醒多个待处理上行读取、两次读取之间的取消、源同步取消后抛错,以及 Client 发送期间流结束。 + - `packages/api/gateway/tests/echo-stream.host.spec.ts`:同一个 echo 方法分别穿过 WebSocket 载体与进程内载体。 - 网关 Host:帧解析的精确键校验;`UplinkInbox` 的 opening 缓冲、`end` 后 `item`、超限、未知 `streamId` 忽略、socket 关闭时的收尾;`UplinkDecoder` 有无 codec 两种交付与解码失败中止;`uplink()` 只能取一次;`extend({ invocation })` 视图与 `peer` 的来源;`cancellableStream` 先关 uplink 再 `return()`。 - 网关 Client:句柄的 `send`(JSON 校验、open 前入队、终止后抛错)、`end` 幂等、`dispose` 驱动 `cancel` 帧并结束后续读取;泵的三种退出;终止帧到达即停泵。 diff --git a/.agents/notes/implemented/architecture/2026-09-19-window-drag-coverage-contract.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-19-window-drag-coverage-contract.i18n.yaml new file mode 100644 index 0000000000..d2ba163848 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-19-window-drag-coverage-contract.i18n.yaml @@ -0,0 +1,25 @@ +# Bilingual-pair consistency record for 2026-09-19-window-drag-coverage-contract.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-19-window-drag-coverage-contract.md +/agent-note-window-drag-coverage-as-a-contract: + en: 120846e859b20561 + zh: 9511a261d15f87b5 +/agent-note-window-drag-coverage-as-a-contract/problem: + en: e4a1c339c31fb1b5 + zh: 0e9db2a9ba74e6c7 +/agent-note-window-drag-coverage-as-a-contract/decision: + en: 1cef50cc0c973afb + zh: c97495c70292f32c +/agent-note-window-drag-coverage-as-a-contract/alternatives-considered: + en: d3c08cbcee308605 + zh: 93bc631a31c16855 +/agent-note-window-drag-coverage-as-a-contract/consequences: + en: d312ce6aad9dc358 + zh: 96905d1acb95ed7c +/agent-note-window-drag-coverage-as-a-contract/testing: + en: bac710df115cac90 + zh: 236874d8df1caa27 +/agent-note-window-drag-coverage-as-a-contract/manual-state-matrix: + en: 8b86cf80458055b1 + zh: 55cece531251548a diff --git a/.agents/notes/implemented/architecture/2026-09-19-window-drag-coverage-contract.md b/.agents/notes/implemented/architecture/2026-09-19-window-drag-coverage-contract.md new file mode 100644 index 0000000000..c73d9230a4 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-19-window-drag-coverage-contract.md @@ -0,0 +1,64 @@ +# Agent Note: Window drag coverage as a contract + +Status: implemented + +English | [中文](2026-09-19-window-drag-coverage-contract.zh.md) + +## Problem + +The macOS desktop window's draggable area is authored twice. The layout decides where chrome rows are — their heights and what they contain — while hand-written app-region declarations decide what drags: one row declaration per chrome row (the sidebar's top strip and logo row, ui-dockkit's strip row, the Conversation header, the plugin manager's page heads, the Platform overlay's return bar) plus per-box subtractions spread across ui-web, ui-settings-general and ui-sidebar-right. The two descriptions are kept in step by hand, so they drift: a row whose box does not match the band leaves chrome outside the drag surface (the reported "the header drags, but some blank runs and controls do not") or puts content inside it (a press that misses a control by a few pixels drags the window, and a double click there runs the system's title-bar action). + +## Decision + +Coverage becomes a contract with four executed parts: + +1. ui-web's `window-drag/regions.ts` publishes the composition rule as an executable model — a point is draggable when the last collected app-region box containing it declares `drag`, the geometry-in-DOM-order composition the native window applies — together with `INTERACTIVE_SELECTOR`, the single source for the interactive subtraction ui-web base.css declares. The base-styles spec asserts the sheet declares exactly that list, so the two cannot drift. +2. The shell declares the darwin drag surface exactly once: `html[data-platform='darwin'] [data-window-drag]` in ui-web base.css. Every chrome row marks its own element in markup, so the row's box is the window's draggable geometry and no fixed band has to match any row's height. The ui-theme app-region gate holds a manifest that pairs each row's markup mark with its sheet, its class selector and its authored height, and refuses a mark on any element the manifest does not name — so a row that stops marking itself, an unmarked row added to the composition, and a mark on a content container all fail the same gate. +3. The browser lane gains `window-drag-coverage`, which boots the shipped composition in Chromium with `data-platform='darwin'` and asserts, through the model, that no interactive box lies inside the drag surface, plus per-row probes for the chrome rows and a page whose head row marks itself while its scrollable body stays content. +4. The shell owns the one recollection watcher — ui-web's `window-drag/recall.ts`, installed by the boot kernel. It measures every marked row once per frame while the surface can be moving, sets `data-window-drag-recall` on the body for each frame whose geometry changed, and clears it once the geometry holds still through a short grace window, so a report that arrives before a CSS transition moves anything cannot end the loop on its first unchanged sample. It reports every reason the surface can move: a DOM change touching a marked row or the container holding one, a marked row's box resizing, and a transition or animation starting on an element that holds a marked row. No chrome row carries a pulse of its own. + +The native half — whether a press really drags or reaches the page — stays a checklist, because no keyless CI lane reaches the window server: the state matrix below is run for any change to this layer. + +## Alternatives considered + +**Publishing measured rectangles from JavaScript as synthetic drag boxes.** Geometry would have to be re-derived at pointer cadence, and one stale frame is exactly the swallow class this work removes; CSS-derived regions cannot be stale by construction. + +**A global background drag (the `movableByWindowBackground` reading).** Dragging anywhere that is not a control would break text selection and blank-area clicks. + +**One drag declaration per row in each row's own sheet.** That was this work's first shape, with a manifest pinning each row's height and the band over it. Every sheet then restates the window's geometry, and a row whose box moves in layout alone still has to be re-declared in CSS; one shell rule over a markup mark keeps the declaration count at one, and the manifest pairs the marks with the geometry that the gate can still check. + +**Pinning current coverage as one golden snapshot.** That would freeze the two failure classes next to the correct behaviour; the manifest separates the invariant (no swallowed control) from the gaps (a budget that only shrinks). + +## Consequences + +- A new control needs no drag declaration: the interactive selector subtracts it. A new chrome row marks its element `data-window-drag` and adds a manifest entry pinning its height, so no band arithmetic and no other sheet changes. +- A row's own box is the whole draggable geometry, and a content container is never one. The plugin manager's detail views mark the head row they share, not the detail container they are rendered in: marking the container would drag the window over its text and form labels, and the lane samples the body below that head to keep it so. +- No coverage gap remains: every chrome row owns its run, and the gate asserts the whole package tree declares the drag surface in exactly two places — the shell's mark rule and the Windows caption row. The plugin manager's page head and its detail views' shared head row include the 48px clearance inside the row, so the entry-page gap closed with them. +- The settings overlay portals beside `#root` (like the Modal primitive) and dropped its per-sheet `no-drag` rule: a covering surface inside the root precedes the columns' chrome, so a drag row declared later would override its subtraction, and ui-web base.css's `body > :not(#root)` rule subtracts a portalled one wherever it overlaps a drag row. The browser lane asserts that placement with the overlay open. Because a step's onboarding overlay marks only `#root` inert, the panel closes when an onboarding step mounts rather than staying focusable behind it. +- The Platform overlay's return bar is a darwin drag row only. Its former per-sheet `app-region: drag` carried no platform scope, so Windows dragged the window from that 48px bar; under the one scoped rule the bar declares drag on macOS alone, where it is the window's top strip. Windows keeps the native caption row as its drag surface, and the shell ships no Linux desktop target. The manual state matrix gains a cell for this bar. +- A row that slides across a hidden/visible edge cannot rely on the layout change alone: Electron recollects the window's drag rects only when a computed app-region value changes (electron#32341), and Blink skips hidden boxes when it collects them. The watcher closes that gap for every row at once — it re-arms on a DOM change that touches a marked row or on a marked row's box resizing, then pulses each frame in which a box moved — so the right panel carries no pulse of its own. + +## Testing + +- `packages/client/web/tests/window-drag-regions.client.spec.ts` — the composition rule, including order sensitivity and box edges. +- `packages/client/web/tests/base-styles.client.spec.ts` — base.css declares the model's interactive selector, the one darwin drag rule, and the recall mark's subtraction. +- `packages/client/ui-theme/tests/app-region-styles.client.spec.ts` — drag ownership, the row manifest, and each row's mark; a mark outside the manifest or a changed row height fails. +- `packages/client/ui-dockkit/tests/app-region-styles.client.spec.ts` — the strip row's own subtraction; its drag is the markup mark's, so the sheet declares none. +- `packages/client/web/tests/window-drag-recall.client.spec.ts` — the watcher through its two seams: what re-arms it, what it ignores, the settle loop, the shell defaults, and disposal. +- `apps/web/tests/window-drag-coverage.e2e.ts` — real Chromium: no swallowed control, per-row probes, a detail page whose head row drags while its body does not, and the recall pulse the shell fires while the right panel slides. +- Real-machine verification (2026-09-20, both platforms, HID-level pointer input plus window-frame readback): the macOS matrix above ran on a real `hiddenInset` window and the Windows cells ran on a Windows 11 ARM64 VM — chrome rows drag, content and the covering overlay do not, controls keep their clicks, and the right panel's strip row drags after its slide. + +## Manual state matrix + +Run on the packaged macOS app for any change to this layer. Each cell means both halves: drag the row's blank run (the window must move) and click the row's controls (they must act rather than drag). + +| State | Rows to walk | +| --- | --- | +| Sidebar expanded, Conversation selected, view tabs shown | sidebar top strip, sidebar logo row, conversation title row, conversation tab-strip row, every control in those rows | +| Sidebar expanded, Conversation selected, single view (no tabs) | same rows, plus the transcript's first rows below the header | +| Sidebar collapsed | Conversation header over the centre, `shell.leading` seat controls, reopen and New session | +| Right sidebar pushed | panel strip row and its controls, the pane body run below the strip, the pane divider's top run | +| Right sidebar fullscreen | panel strip row at the traffic lights, first pane's strip inset, its controls | +| Entry page (guide, plugin manager, settings) | page head with its 48px clearance, its first control row, and a detail page's head row over its body | +| Window fullscreen on/off | every row above with the traffic lights hidden, in both sidebar states | +| Double click in a chrome row's blank run | on Windows the caption row takes the system title-bar action (maximize/restore); on macOS the darwin rows are app-region areas rather than a title bar, so no system action is expected there — only the controls keep their own double click | diff --git a/.agents/notes/implemented/architecture/2026-09-19-window-drag-coverage-contract.zh.md b/.agents/notes/implemented/architecture/2026-09-19-window-drag-coverage-contract.zh.md new file mode 100644 index 0000000000..81fb9bbcc2 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-19-window-drag-coverage-contract.zh.md @@ -0,0 +1,64 @@ +# Agent Note: 把窗口拖拽覆盖变成契约 + +Status: implemented + +[English](2026-09-19-window-drag-coverage-contract.md) | 中文 + +## Problem + +macOS 桌面窗口的可拖区域被写了两遍。布局决定 chrome 行在哪——它们多高、装了什么;手写的 app-region 声明决定什么能拖:每个 chrome 行一条行声明(侧栏顶条与 logo 行、ui-dockkit 的 strip 行、会话 header、插件管理的页头、Platform 浮层的返回栏),加上散落在 ui-web、ui-settings-general、ui-sidebar-right 的逐盒减除。两份描述靠人肉保持一致,于是会漂:盒子与 band 不匹配的行,要么有 chrome 落在拖拽面之外(就是反馈里的"header 能拖,但有些空白与控制不能"),要么有内容落进拖拽面(点偏几个像素就变成拖窗口,双击那里还会触发系统标题栏行为)。 + +## Decision + +覆盖变成由四部分组成的、可执行的契约: + +1. ui-web 的 `window-drag/regions.ts` 把合成规则发布成可执行模型——当包含某点的最后一个 app-region 盒声明 `drag` 时该点可拖,这正是原生窗口施加的"按 DOM 顺序的几何合成"——并发布 `INTERACTIVE_SELECTOR`,作为 ui-web base.css 交互减除的唯一来源。base-styles spec 断言样式表声明的正是该列表,两者无法漂移。 +2. 外壳只声明一次 darwin 拖拽面:ui-web base.css 里的 `html[data-platform='darwin'] [data-window-drag]`。每个 chrome 行在 markup 里给自己的元素打标,于是该行自己的盒子就是窗口的可拖几何,不需要任何固定 band 去匹配行高。ui-theme 的 app-region 门禁持有一份清单,把每行的 markup 标记与其样式表、类选择器和写死的高度配成一条,并拒绝清单未点名的元素上的标记——行不再打标、新增未打标的行、把标记打在内容容器上,都会在同一条门禁上失败。 +3. 浏览器车道增加 `window-drag-coverage`:以 `data-platform='darwin'` 在 Chromium 里启动真实组合,用模型断言没有任何交互盒落在拖拽面内,并对各 chrome 行逐一探测,另加一个"页头行打标、其可滚动正文保持内容"的页面。 +4. 外壳持有唯一那个重收集 watcher——ui-web 的 `window-drag/recall.ts`,由引导内核安装。在表面可能移动期间,它每帧测量每个被打标的行,凡该帧几何发生变化就在 body 上打 `data-window-drag-recall`;几何在一段很短的宽限窗口内保持不动之后才清掉,这样在 CSS transition 真正移动任何东西之前到达的一次报告,不会在它第一帧未测到变化时就终止循环。它会报告表面可能移动的每一种原因:触及被打标行或承载它的容器的 DOM 变化、被打标行的盒子尺寸变化,以及持有被打标行的元素上开始的 transition 或 animation。任何 chrome 行都不再自带脉冲。 + +原生那一半——一次按下到底是拖窗口还是到达页面——仍是清单,因为没有无密钥 CI 车道能到达窗口服务器:对本层的任何改动都要走下面的状态矩阵。 + +## Alternatives considered + +**用 JavaScript 测量矩形并发布合成 drag 盒。** 几何得按指针节拍重新推导,而一帧陈旧正是这项工作要消除的吞点击类别;CSS 推导的区域在构造上不可能陈旧。 + +**全局背景拖拽(`movableByWindowBackground` 的读法)。** 只要不是控件就能拖,会破坏文本选择与空白处点击。 + +**每个行在自己的样式表里各声明一条 drag。** 这是本项工作最初的样子,并配一份清单钉住每行高度与覆盖它的 band。那样每个样式表都要复述窗口几何,而且只在布局里移动的盒子仍得在 CSS 里重新声明;改成"markup 打标 + 外壳一条规则"后声明只有一处,清单则继续把标记与门禁能查的几何配起来。 + +**把当前覆盖钉成一张金标准快照。** 那会把两类故障和正确行为一起冻住;清单把不变量(不得吞掉控件)与缺口(只许缩小的预算)分开。 + +## Consequences + +- 新控件不需要任何 drag 声明:交互选择器会减除它。新 chrome 行只需给元素打上 `data-window-drag` 并在清单里加一条钉住高度,无需 band 算术,也不牵动其它样式表。 +- 行自己的盒子就是完整的可拖几何,内容容器永远不是。插件管理的详情视图给它们共用的页头行打标,而不是给它所在的详情容器打标:标记容器会让窗口在它的正文与表单 label 上拖动;车道会采样该页头下方的正文来守住这一点。 +- 不再有任何缺口:每个 chrome 行自持其拖拽段,门禁断言整个包树只在两处声明拖拽面——外壳的标记规则与 Windows 标题栏行。插件管理页头与其详情视图共用的页头行都把 48px 避让量包含在行内,入口页那条缺口也随之关闭。 +- settings 浮层现在与 Modal primitive 一样 portal 到 `#root` 之外,并删掉了它自己那条 no-drag:挂在 root 内的覆盖层先于各列 chrome,后声明的 drag 行会盖掉它的减除;portal 之后由 ui-web base.css 的 `body > :not(#root)` 规则在它与 drag 行重叠处减除。车道在浮层打开时会断言这个归属。由于 onboarding 步骤的浮层只把 `#root` 置为 inert,onboarding 步骤挂载时面板会自行关闭,而不是留在它背后仍可聚焦。 +- Platform overlay 的返回栏只是 darwin 的 drag 行。它原先那条按表声明的 `app-region: drag` 没有任何平台限定,因此 Windows 上也能从这条 48px 栏拖动窗口;改到唯一那条带作用域的规则之后,该栏只在 macOS 上声明 drag,在那里它就是窗口顶条。Windows 保留原生标题栏行作为拖拽面,且外壳没有 Linux 桌面目标。人工状态矩阵会为这条栏增加一格。 +- 跨越隐藏/显示边界滑动的行不能只靠布局变化:只有当计算出的 app-region 值变化时,Electron 才会重新收集窗口的拖拽矩形(electron#32341),而 Blink 收集时会跳过隐藏的盒子。watcher 一次性把这个缺口对所有行补上——它在"触及被打标行的 DOM 变化"或"被打标行的盒子尺寸变化"时重新启动,随后在盒子仍在移动的每一帧发脉冲——因此右栏不再自带任何脉冲。 + +## Testing + +- `packages/client/web/tests/window-drag-regions.client.spec.ts` —— 合成规则,含顺序敏感与盒子边界。 +- `packages/client/web/tests/base-styles.client.spec.ts` —— base.css 声明的正是模型的交互选择器、唯一那条 darwin drag 规则,以及 recall 标记的减除。 +- `packages/client/ui-theme/tests/app-region-styles.client.spec.ts` —— 拖拽所有权、行清单与每行的标记;清单之外的标记或行高变化即失败。 +- `packages/client/ui-dockkit/tests/app-region-styles.client.spec.ts` —— strip 行自己的减除;它的 drag 属于 markup 标记,因此样式表一条都不声明。 +- `packages/client/web/tests/window-drag-recall.client.spec.ts` —— 通过两个 seam 驱动 watcher:什么会重新启动它、什么被它忽略、收敛循环、外壳默认值,以及销毁。 +- `apps/web/tests/window-drag-coverage.e2e.ts` —— 真 Chromium:无控件被吞、逐行探测、一个页头行可拖而正文不可拖的详情页,以及右栏滑动期间外壳发出的 recall 脉冲。 +- 真机验收(2026-09-20,双平台,HID 级指针输入 + 窗口矩形读数):上面的 macOS 矩阵在真实 `hiddenInset` 窗口上跑过,Windows 各格在 Windows 11 ARM64 虚拟机上跑过——chrome 行可拖、正文与覆盖浮层不可拖、控件保留点击、右栏 strip 行在滑入后可拖。 + +## Manual state matrix + +对本层的任何改动都要在打包 macOS 应用上跑。每个格子包含两半:拖该行的空白段(窗口必须移动),点该行的控件(必须生效而不是拖动)。 + +| 状态 | 要走的行 | +| --- | --- | +| 侧栏展开、选中会话、显示视图 tab | 侧栏顶条、侧栏 logo 行、会话标题行、会话 tab 条行,以及这些行里的每个控件 | +| 侧栏展开、选中会话、单视图(无 tab) | 同上,外加 header 之下的转录区首行 | +| 侧栏收起 | 覆盖中列的 会话 header、`shell.leading` 座的控件、重新打开与新会话 | +| 右栏 push | 面板 strip 行及其控件、strip 下方的 pane body 段、分栏分隔条的顶部一段 | +| 右栏 fullscreen | 红绿灯处的面板 strip 行、首格 strip 内边距、其控件 | +| 入口页(开始页、插件管理、设置) | 含 48px 避让量的页头、它的首个控件行,以及详情页页头行与其正文 | +| 窗口全屏开关 | 以上各行在红绿灯隐藏时、两种侧栏状态各一遍 | +| 在 chrome 行空白段双击 | Windows 上 caption 行走系统标题栏行为(最大化/还原);macOS 上 darwin 行只是 app-region 区域而非标题栏,因此那里没有系统动作——只有控件保留自己的双击 | diff --git a/.agents/notes/implemented/architecture/2026-09-20-device-local-shortcut-preferences.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-20-device-local-shortcut-preferences.i18n.yaml new file mode 100644 index 0000000000..9ed3a48e3b --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-20-device-local-shortcut-preferences.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-20-device-local-shortcut-preferences.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-20-device-local-shortcut-preferences.md +/agent-note-keep-shortcut-preferences-device-local-and-commit-before-activation: + en: 0f033ac1e9acec35 + zh: 06f3bf59003446ea +/agent-note-keep-shortcut-preferences-device-local-and-commit-before-activation/problem: + en: d1d3ef4f6e66e5a7 + zh: 5691f2b106617a86 +/agent-note-keep-shortcut-preferences-device-local-and-commit-before-activation/decision: + en: 21f8da8d396c3f55 + zh: 46de3df8141bcb0a +/agent-note-keep-shortcut-preferences-device-local-and-commit-before-activation/alternatives-considered: + en: 202dcaddc6c9c400 + zh: 3f8e3576c2324636 +/agent-note-keep-shortcut-preferences-device-local-and-commit-before-activation/consequences: + en: 9dcfdef13faa374f + zh: 1951198555fcc9ea diff --git a/.agents/notes/implemented/architecture/2026-09-20-device-local-shortcut-preferences.md b/.agents/notes/implemented/architecture/2026-09-20-device-local-shortcut-preferences.md new file mode 100644 index 0000000000..3da3d3a29c --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-20-device-local-shortcut-preferences.md @@ -0,0 +1,27 @@ +# Agent Note: Keep shortcut preferences device-local and commit before activation + +Status: implemented + +English | [中文](2026-09-20-device-local-shortcut-preferences.zh.md) + +## Problem + +Keyboard bindings depend on the receiving device's operating system and browser restrictions. A Host can serve several devices, while a local save can fail after a user records a new combination. Activating an unpersisted binding makes the interface disagree with the next application launch. Rewriting unreadable or future-version preferences can destroy choices an older client cannot interpret. + +## Decision + +[The shortcut service](../../../../packages/client/shortcuts/README.md) stores only versioned overrides per runtime/platform. Web owns origin-local browser storage; Electron main owns `userData/keybindings.json`, independently of Harness home. Both adapters share validation and transaction logic. Successful persistence publishes one accepted configuration from which command matching, keycaps, and native interception derive. + +Missing commands retain dormant overrides. Explicit overrides win over newly introduced defaults; conflicting explicit overrides are all disabled. Unreadable configuration blocks ordinary edits and preserves the last accepted values. Restore All clears only the accepted current profile and cannot overwrite unreadable or future-version data. + +## Alternatives considered + +**Host settings.** A server's operating system and settings scope do not identify the visitor's device or browser restrictions. Host storage would also couple remote visitors' preferences. + +**Optimistic activation.** Updating bindings before persistence makes a failed save appear successful and leaves restart behavior inconsistent with the visible controls. + +**Cross-tab atomic merging.** localStorage has no compare-and-swap transaction. Web rereads before each operation and rejects known stale drafts, but accepts last-writer-wins for simultaneous writes. Electron main serializes edits and rejects stale revisions. + +## Consequences + +Devices and Web/Desktop do not synchronize bindings automatically. Repairing unreadable preferences requires correcting the stored document; application edits preserve those bytes. Browser concurrency does not promise lossless merging. Atomic Desktop replacement uses the shared writer's Windows retry behavior without promising fsync durability. Deterministic transaction, browser-storage, and Desktop-file tests cover failure retention, conflicts, stale drafts, and refusal to replace unreadable data; platform keyboard acceptance remains separate from persistence correctness. diff --git a/.agents/notes/implemented/architecture/2026-09-20-device-local-shortcut-preferences.zh.md b/.agents/notes/implemented/architecture/2026-09-20-device-local-shortcut-preferences.zh.md new file mode 100644 index 0000000000..3c5420e870 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-20-device-local-shortcut-preferences.zh.md @@ -0,0 +1,27 @@ +# Agent Note: 快捷键偏好按设备保存,提交后才激活 + +Status: implemented + +[English](2026-09-20-device-local-shortcut-preferences.md) | 中文 + +## 问题 + +快捷键取决于接收输入设备的操作系统和浏览器限制。一个 Host 可服务多个设备,而用户录入新组合后,本地保存仍可能失败。激活未持久化的绑定会使界面与下一次启动不一致。重写不可读或未来版本的偏好可能破坏旧客户端无法解释的选择。 + +## 决策 + +[快捷键服务](../../../../packages/client/shortcuts/README.zh.md) 只保存按运行端/平台区分的版本化覆盖。Web 使用同 origin 的浏览器存储;Electron main 管理 `userData/keybindings.json`,与 Harness home 独立。两端适配器共享校验和事务逻辑。持久化成功后发布一个已接受配置,命令匹配、键帽和原生拦截都由此派生。 + +未加载命令保留休眠覆盖。显式覆盖优先于新增默认值,相互冲突的显式覆盖全部禁用。不可读配置阻止普通编辑,并保留上次接受的值。全部恢复只清除已接受的当前平台覆盖,不会覆盖不可读或未来版本的数据。 + +## 考虑过的替代方案 + +**Host 设置。** 服务端操作系统和设置范围不能标识访问者设备或浏览器限制,Host 存储还会耦合远程访问者的偏好。 + +**乐观激活。** 在持久化之前更新绑定会让保存失败看起来像成功,并使重启行为与可见控件不一致。 + +**跨标签页原子合并。** localStorage 没有比较并交换事务。Web 每次操作前重新读取并拒绝已知过期草稿,但同时写入采用最后成功写入生效。Electron main 串行处理编辑并拒绝旧 revision。 + +## 影响 + +不同设备以及 Web/Desktop 不自动同步绑定。修复不可读偏好需要更正存储文档;应用内编辑保留这些原始内容。浏览器并发不承诺无损合并。Desktop 原子替换使用共享写入器的 Windows 重试行为,不承诺 fsync 持久性。确定性的事务、浏览器存储和桌面文件测试覆盖失败保留、冲突、过期草稿以及拒绝替换不可读数据;平台键盘验收与持久化正确性分别验证。 diff --git a/.agents/notes/implemented/architecture/2026-09-20-dynamic-tool-updates.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-20-dynamic-tool-updates.i18n.yaml new file mode 100644 index 0000000000..2663220c51 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-20-dynamic-tool-updates.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-20-dynamic-tool-updates.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-20-dynamic-tool-updates.md +/agent-note-active-tool-headers-and-stateful-request-projection: + en: c40dd7568bba391f + zh: 295ce33341e0aab7 +/agent-note-active-tool-headers-and-stateful-request-projection/problem: + en: 97fe58a13135b4a1 + zh: 7490373a8d941da5 +/agent-note-active-tool-headers-and-stateful-request-projection/decision: + en: 0c40a9283650c643 + zh: 91a18d752d09a9ce +/agent-note-active-tool-headers-and-stateful-request-projection/alternatives-considered: + en: b78785f2a603eba8 + zh: b8c268228da7e2e7 +/agent-note-active-tool-headers-and-stateful-request-projection/consequences: + en: 93c32b795b71a1cc + zh: d42b5c563341c898 diff --git a/.agents/notes/implemented/architecture/2026-09-20-dynamic-tool-updates.md b/.agents/notes/implemented/architecture/2026-09-20-dynamic-tool-updates.md new file mode 100644 index 0000000000..1b505eec4b --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-20-dynamic-tool-updates.md @@ -0,0 +1,37 @@ +# Agent Note: Active tool headers and stateful request projection + +Status: implemented + +English | [中文](2026-09-20-dynamic-tool-updates.zh.md) + +## Problem + +Plugin and MCP tools change during conversations. Providers differ in whether they activate deferred definitions or remove tools through history. Storing retained provider declarations as active tools makes comparisons repeat removals and miss restorations. + +## Decision + +`request/header.tools` records assembled active tools independently of model capability. The loop compares names against the preceding header and emits one `developer/message` with additions and removals under the `tool-registry` source. Additions reference the new header through `headerSeq`. Definition changes remain header changes; unchanged names emit no update. Existing header equality and request-series rules remain in force. + +`Session.toolHistory()` caches a capability-independent fold of committed headers and developer messages. First access restores inherited events; later reads consume only unseen events. Immutable snapshots carry initial declarations and ordered update identities with additions resolved through their historical headers. Explicit series starts and changed retained definitions rebuild declarations. Restoring a retained name with an unchanged definition continues the series: the projection keeps the declaration unchanged and lets the recorded addition re-offer the tool after its earlier removal, so a removal never disables a declared tool and a loading mode never rewrites an earlier declaration. + +Loop and compaction requests carry this snapshot as `GenerateOptions.toolHistory`. At adapter dispatch, `projectToolUpdates` uses the prepared route's `toolUpdate`. Unsupported routes receive active definitions without `deferLoading` or developer messages. Supported routes defer historical additions; `in-history` retains removed definitions and removal blocks, while `addition-only` omits both. Only current-series update identities survive. Missing history or a request prefix omitting recorded updates uses current declarations without developer updates. Explicit deferred loading remains available on capable routes. + +DeepSeek translates projected updates into system-role `tool_addition` and `tool_removal` blocks and `defer_loading` declarations, sending the tool-changes beta header when update blocks occur. The default `deepseek-flash` entry declares `addition-only`; pi-ai declares no mode. Chat and Trajectory display developer messages as context nodes, using localized tool-change notices: single changes show the tool name; multiple changes show counts and expandable name lists. + +## Alternatives considered + +**Store provider declarations in headers.** Retained removed definitions are not active tools. Mixing those meanings makes durable updates capability-dependent and breaks change detection. + +**Reconstruct definitions in adapters from messages alone.** Addition messages contain names, not schemas or event-level header references. Session owns that historical relationship; adapters translate projected requests. + +**Scan the complete log on every request.** The cached fold consumes new events and supplies stable snapshots to ordinary and auxiliary calls without adding arbitrary synchronous history readers. + +**Reject same-name schema changes during tool registration.** This restriction is not enforced. Immediate failure for a plugin registering an incompatible tool requires comparing the new registration with historical definitions of tools called on each affected current surface, while excluding calls removed by compaction. That registration-time historical and scope-aware check is deferred because of its implementation complexity. Same-name schema changes remain allowed; they rebuild declarations and invalidate prefix reuse even on `in-history` routes. + +## Consequences + +Tool lists and logical update events are capability-independent; only outgoing declarations and messages vary. Calls to removed retained tools fail through the existing `UNKNOWN_TOOL` path. Changed definitions and incomplete auxiliary prefixes sacrifice prefix reuse for coherent declarations; unchanged restoration keeps the cached prefix on `in-history` routes only while the request series continues. Routes supporting tool updates and in-history system prompts preserve earlier messages when tools are added alongside a changed prompt or after an earlier prompt update. Routes without tool-update support still consolidate on tool changes; explicit series starts and surface replacements still consolidate on every route. No persisted fields or Session format revision are added. + +The authored [headless prompt/tool scenario](../../../../snapshots/session/dynamic-tool-prompt-updates/snapshot.yml) pins an appended prompt beside a deferred tool addition and verifies that the first request's messages stay unchanged. It shares the stable-prompt scenario's tool lifecycle and schema expectations. + +The [real DeepSeek SDK test](../../../../apps/cli/tests/profiles/sdk/dynamic-tool-cache.e2e.ts) measures the first request after a native tool addition with both unchanged and simultaneously updated instructions. Unique user history prevents a shared system-prompt cache hit from satisfying the preceding-input assertion. Removal checks tool availability without requiring cache retention; each case disables retries. diff --git a/.agents/notes/implemented/architecture/2026-09-20-dynamic-tool-updates.zh.md b/.agents/notes/implemented/architecture/2026-09-20-dynamic-tool-updates.zh.md new file mode 100644 index 0000000000..6a8fb256c5 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-20-dynamic-tool-updates.zh.md @@ -0,0 +1,37 @@ +# Agent Note: 有效工具请求头与有状态请求投影 + +Status: implemented + +[English](2026-09-20-dynamic-tool-updates.md) | 中文 + +## Problem + +插件和 MCP 工具会在对话期间变化。不同提供方对通过历史激活延迟定义或移除工具的支持不同。把为提供方保留的声明当作有效工具存储,会使比较重复记录移除并遗漏恢复。 + +## Decision + +`request/header.tools` 记录组装得到的有效工具,不依赖模型能力。循环将名称与前一请求头比较,以 `tool-registry` 来源发出一条包含添加和移除的 `developer/message`。添加通过 `headerSeq` 引用新请求头。定义变化仍体现为请求头变化;名称未变时不发出更新。现有请求头相等判断和请求序列规则保持有效。 + +`Session.toolHistory()` 缓存对已提交请求头和 developer 消息的归约,不依赖模型能力。首次访问恢复继承事件;后续读取仅处理新增事件。不可变快照携带初始声明和有序更新标识,添加定义通过历史请求头解析。显式新序列和保留定义变化会重建声明。以未变化的定义恢复保留名称时序列继续:投影保持声明不变,由记录的添加在先前移除之后重新提供该工具,因此移除不会禁用已声明的工具,加载模式也不会改写先前声明。 + +循环和压缩请求通过 `GenerateOptions.toolHistory` 携带此快照。适配器分发时,`projectToolUpdates` 使用已准备路由的 `toolUpdate`。不支持的路由接收有效定义,不携带 `deferLoading` 或 developer 消息。支持的路由延迟历史添加;`in-history` 保留已移除定义和移除块,`addition-only` 则省略两者。仅保留当前序列的更新标识。缺少历史或请求前缀遗漏已记录更新时,使用当前声明且不发送 developer 更新。显式延迟加载在支持的路由上仍然可用。 + +DeepSeek 把投影后的更新转换为 system 角色的 `tool_addition` 和 `tool_removal` 块以及 `defer_loading` 声明,在存在更新块时发送工具变更 beta 请求头。默认 `deepseek-flash` 条目声明 `addition-only`;pi-ai 不声明模式。Chat 和 Trajectory 将 developer 消息显示为上下文节点,工具变更使用本地化通知:单项变更显示工具名,多项变更显示数量及可展开的名称列表。 + +## Alternatives considered + +**在请求头存储提供方声明。** 为提供方保留的已移除定义不是有效工具。混合两种含义会使持久更新依赖能力,并破坏变更检测。 + +**仅凭消息在适配器重建定义。** 添加消息包含名称,不包含模式或事件级请求头引用。Session 拥有该历史关系;适配器转换投影后的请求。 + +**每次请求扫描完整日志。** 缓存归约处理新事件,为普通和辅助调用提供稳定快照,不增加任意同步历史读取接口。 + +**在工具注册时拒绝同名 schema 变化。** 当前不执行此限制。要让注册不兼容工具的插件立即收到异常,需要将新注册与各受影响当前 surface 中已调用工具的历史定义比较,同时排除已被压缩移除的调用。由于实现复杂,注册时结合历史和作用域的检查留待后续实现。同名 schema 变化仍被允许;它们会重建声明,即使在 `in-history` 路由上也会使前缀复用失效。 + +## Consequences + +工具列表和逻辑更新事件不依赖能力;只有发出的声明和消息不同。调用已移除但保留声明的工具时,通过现有 `UNKNOWN_TOOL` 路径失败。定义变化和不完整辅助前缀为保证声明一致而放弃前缀复用;仅当请求序列继续时,未变化的恢复才在 `in-history` 路由上保留缓存前缀。同时支持工具更新和历史内系统提示词的路由,在工具添加与提示词变化同时发生或晚于此前提示词更新时,保留此前消息。不支持工具更新的路由仍在工具变化时归并提示词;所有路由仍在显式新序列和 surface 替换时归并。不增加持久字段或 Session 格式版本。 + +手写的[无界面提示词/工具场景](../../../../snapshots/session/dynamic-tool-prompt-updates/snapshot.yml)钉住追加提示词与延迟工具添加同时发生的行为,并验证首次请求的消息保持不变。它复用稳定提示词场景的工具生命周期和 schema 期望值。 + +[真实 DeepSeek SDK 测试](../../../../apps/cli/tests/profiles/sdk/dynamic-tool-cache.e2e.ts) 分别在指令不变和指令同时更新时测量原生工具新增后的首次请求。独有的用户历史确保仅命中共享系统提示词缓存无法满足前序输入断言。移除场景检查工具可用性,不要求保留缓存;每个用例均禁用重试。 diff --git a/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.i18n.yaml index 061872368c..641b4a5806 100644 --- a/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-20-sidebar-retained-tab-layout.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.md -2026-09-20-sidebar-retained-tab-layout.md: 9579a0ba47c56f1d533f066fddd37e7ddf443346 -2026-09-20-sidebar-retained-tab-layout.zh.md: 365ad5682c8610cab5dc855984e58b4303bfae49 +/agent-note-stable-sidebar-tab-mounting-and-session-retention: + en: 79bf4b50c50b52d4 + zh: cfd15cdb020ef7c8 +/agent-note-stable-sidebar-tab-mounting-and-session-retention/problem: + en: fd5b83cd022f1696 + zh: fd14a1bc7f5d9119 +/agent-note-stable-sidebar-tab-mounting-and-session-retention/decision: + en: 3e604325fdf0e8b5 + zh: ddf00764a68532d4 +/agent-note-stable-sidebar-tab-mounting-and-session-retention/decision/layout-ownership: + en: 7095df7c949b8e3c + zh: e7410e44eaa97797 +/agent-note-stable-sidebar-tab-mounting-and-session-retention/decision/session-and-tab-lifetime: + en: 60a4450a1a4f398c + zh: cc0054505b973c91 +/agent-note-stable-sidebar-tab-mounting-and-session-retention/decision/provider-responsibilities: + en: a34c228751a1a329 + zh: 8e8b962b55e7c68e +/agent-note-stable-sidebar-tab-mounting-and-session-retention/decision/retention-versus-recovery: + en: aabfa99401aa0f73 + zh: 465ebf723c4393aa +/agent-note-stable-sidebar-tab-mounting-and-session-retention/alternatives-considered: + en: 84cfe7613657bfdb + zh: 4a0a499eb5d36d22 +/agent-note-stable-sidebar-tab-mounting-and-session-retention/consequences: + en: 9569f8398823e0da + zh: 9b95fb2f5d53b963 +/agent-note-stable-sidebar-tab-mounting-and-session-retention/verification: + en: 8d6fd48c494ba5f6 + zh: 1aa02f822f58d73b diff --git a/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.md b/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.md index 9579a0ba47..3c1e23ad93 100644 --- a/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.md +++ b/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.md @@ -17,7 +17,7 @@ Sidebar owns live-body retention, independently of Browser navigation and Worksp - `DockLayout` renders the Sidebar's one or two horizontal panes with stable tab siblings. The existing recursive `DockSurface` and separate `FloatLayer` remain available for general split-tree rendering; the layout engine and serialized format are unchanged. - Every tab has a stable Grid cell, frame, Header container and Body container. Explicit Grid columns determine docking placement; Flex assigns Header and Body height. Floating changes that same frame to `position: fixed` without changing its parent or replacing Body. - A floating frame's zero-sized Grid cell establishes a stacking context at the float layer. CSS `order` expresses float depth within that layer; DOM order stays sorted by tab identity. Raising many floats cannot increment their layer past menus. Selection and strip order never reorder the content-node list. -- Common ancestors have no transform, clipping or enclosing stacking context. Docked cells own collapse transforms and visibility; each frame clips its content. Fullscreen changes the same root's width and docked layer. Existing window-drag region pulses remain, but no RAF copies content positions. +- Common ancestors have no transform, clipping or enclosing stacking context. Docked cells own collapse transforms and visibility; each frame clips its content. Fullscreen changes the same root's width and docked layer. The right panel carries no window-drag pulse of its own: one shell-owned watcher measures the marked rows each frame while the surface can move and pulses the recall mark itself, so no layout code copies content positions. - Split and float gestures retain their existing measurements and operation state. These update user-selected split fractions and float rectangles, not a second Browser rectangle. Browser resize and content sizing use normal CSS layout. ### Session and tab lifetime diff --git a/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.zh.md b/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.zh.md index 365ad5682c..000174a0c3 100644 --- a/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-20-sidebar-retained-tab-layout.zh.md @@ -17,7 +17,7 @@ Sidebar 负责活 Body 的保留,不依赖 Browser 导航和 Workspace 存储 - `DockLayout` 用稳定的 Tab 兄弟节点渲染 Sidebar 的一个或两个水平 Pane。现有递归 `DockSurface` 和独立 `FloatLayer` 仍可用于通用分割树渲染;布局引擎和序列化格式不变。 - 每个 Tab 都有稳定的 Grid cell、frame、Header 容器和 Body 容器。显式 Grid 列决定停靠归属,Flex 分配 Header 与 Body 的高度。浮动只把同一个 frame 改为 `position: fixed`,不改父节点或替换 Body。 - 浮动 frame 的零尺寸 Grid cell 在浮窗层建立层叠上下文。CSS `order` 表达该层内的浮窗深度,DOM 顺序始终按 Tab 身份排序。大量浮窗置顶不会把层级递增到菜单之上;选中项和 Tab 条排序均不重排内容节点列表。 -- 共同祖先不设置 transform、裁剪或包住全部内容的层叠上下文。停靠 cell 负责收起 transform 和显隐,各 frame 裁剪自身内容。Fullscreen 修改同一个根的宽度和停靠层级。窗口拖动区域的既有脉冲仍保留,但没有 RAF 复制内容位置。 +- 共同祖先不设置 transform、裁剪或包住全部内容的层叠上下文。停靠 cell 负责收起 transform 和显隐,各 frame 裁剪自身内容。Fullscreen 修改同一个根的宽度和停靠层级。右栏不再自带窗口拖拽脉冲:由外壳唯一那个 watcher 在表面可能移动时逐帧测量被打标行并自行脉冲 recall 标记,因此没有布局代码复制内容位置。 - 分栏与浮窗手势沿用原有测量和操作状态,更新用户选择的分栏比例与浮窗矩形,而非维护第二份 Browser 矩形。窗口缩放和内容尺寸变化由普通 CSS 布局处理。 ### 会话与 Tab 生命周期 diff --git a/.agents/notes/implemented/architecture/2026-09-21-conversation-build-groups.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-21-conversation-build-groups.i18n.yaml index 1bd7d91641..f715253877 100644 --- a/.agents/notes/implemented/architecture/2026-09-21-conversation-build-groups.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-21-conversation-build-groups.i18n.yaml @@ -1,6 +1,43 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-21-conversation-build-groups.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-21-conversation-build-groups.md -2026-09-21-conversation-build-groups.md: bccb48b0e40a076bbcb59aaca9e9ef6208e9469d -2026-09-21-conversation-build-groups.zh.md: 5d2ec9e684c75b3db3568c4f046129431295f736 +/agent-note-definition-owned-grouping-with-generic-node-group-assembly: + en: 011f264e0aea8d0c + zh: d0ad8b4334af619e +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/problem: + en: 83dd98f48ee30a1a + zh: 66dec35b4b54f291 +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/decision: + en: d4216ce4d80382e8 + zh: 9ee608af410e81e0 +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/decision/responsibilities: + en: d7cf1bd544f163ee + zh: 2433f3faa5f5abcb +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/decision/related-decisions: + en: d8307dcaf2a9ac72 + zh: 4852b1e2a4d09af0 +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/definition-input-state-and-registration: + en: 9fb89bddbfd75627 + zh: 950c319db123c637 +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/node-group-references-and-updates: + en: 13034cf7eb143055 + zh: 4ff0c0be55028258 +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/assembly-order-and-lifecycle: + en: 52a1bbfe6e9bcac7 + zh: dabbcd108f68bd14 +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/concrete-implementation-locations: + en: 85715eb77bf73713 + zh: 7e6c90830b65281b +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/react-reading-and-presentation: + en: 7636207f33e971a4 + zh: ace1f5bbaf5a01b5 +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/alternatives-considered: + en: 21a74f9031f86a92 + zh: c6abd0a5dfbf56a8 +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/verification: + en: b42409d029fc0fde + zh: 0f8ab7d206cab772 +/agent-note-definition-owned-grouping-with-generic-node-group-assembly/consequences: + en: 96f1d81b28534661 + zh: 8cb1c7a0f000c335 diff --git a/.agents/notes/implemented/architecture/2026-09-21-creator-skills-progressive-disclosure.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-21-creator-skills-progressive-disclosure.i18n.yaml index 61830cb7cd..4a59755b21 100644 --- a/.agents/notes/implemented/architecture/2026-09-21-creator-skills-progressive-disclosure.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-21-creator-skills-progressive-disclosure.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-21-creator-skills-progressive-disclosure.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-21-creator-skills-progressive-disclosure.md -2026-09-21-creator-skills-progressive-disclosure.md: bdd70beda7c92584a336cda856d196ac23d1f968 -2026-09-21-creator-skills-progressive-disclosure.zh.md: 265d9db21a5288b4d589078ff85a75eb74f3b237 +/agent-note-creator-skills-disclose-progressively-and-may-read-sources: + en: 374f4a41f3026e59 + zh: 4e7f90d18b03fd14 +/agent-note-creator-skills-disclose-progressively-and-may-read-sources/problem: + en: 1808717550a5e7ba + zh: e18dd5a813a2398d +/agent-note-creator-skills-disclose-progressively-and-may-read-sources/decision: + en: b83fb74f03ca75a7 + zh: e4f6b1c73ef96787 +/agent-note-creator-skills-disclose-progressively-and-may-read-sources/alternatives-considered: + en: d36d4f610925060a + zh: c0ed56b6c631789e +/agent-note-creator-skills-disclose-progressively-and-may-read-sources/consequences: + en: ed908afe74adf3bc + zh: 62a3cfba359dfbb6 diff --git a/.agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.i18n.yaml new file mode 100644 index 0000000000..55a0c25bdd --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-21-desktop-page-close-shortcuts.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.md +/agent-note-desktop-close-shortcuts-follow-page-focus: + en: e6ce0bc9592af8ba + zh: b43fa4c48c634e27 +/agent-note-desktop-close-shortcuts-follow-page-focus/problem: + en: feb9d491ad4a9016 + zh: 291f0e6c913b0b19 +/agent-note-desktop-close-shortcuts-follow-page-focus/decision: + en: c587d88575b6ce7e + zh: 2287cf4d6d2e7587 +/agent-note-desktop-close-shortcuts-follow-page-focus/alternatives-considered: + en: 10c7bb2fc87bdd16 + zh: 796ecde8bcf09d34 +/agent-note-desktop-close-shortcuts-follow-page-focus/consequences: + en: aea659e749840caa + zh: e75d757165055a55 diff --git a/.agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.md b/.agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.md new file mode 100644 index 0000000000..dc97680644 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.md @@ -0,0 +1,27 @@ +# Agent Note: Desktop close shortcuts follow page focus + +Status: implemented + +English | [中文](2026-09-21-desktop-page-close-shortcuts.zh.md) + +## Problem + +The [shortcut PRD](https://trtgsjkv6r.feishu.cn/wiki/APvtwgbztiBLzvk9DM4cQbccnhf) gives the close command two targets: the focused right-sidebar page, or the Desktop window when no page can close. Electron's native close role bypasses the page owner. On Windows, closing the last window also quits the Desktop instance and stops its Host tasks, so this fallback is a lifecycle choice rather than a menu-label change. + +## Decision + +The sidebar page owner resolves close against live focus and captures the target's Session, pane, tab occurrence, and navigation revision. It closes that page through its resource cleanup handler, or collapses the sole docked guide. Stale sidebar targets do not fall back to another page or the window. Without a closeable page, Desktop requests native window closure; Web has no window fallback. + +The macOS File menu routes Close Page or Window through the same owner and displays the accepted single-key binding. Native closure requires the current configuration revision, a focused and enabled product window, and inactive shortcut recording. The existing window lifecycle applies without a shortcut-specific confirmation: macOS keeps the application alive after its last window closes; Windows and Linux quit and stop the Host. + +This decision owns File-menu and close behavior in place of the close-role choice in [the standard macOS menu note](../bug-fix/2026-09-16-desktop-window-menus.md). That note retains the rationale for native Window and application hide commands. [Shortcut preference persistence](2026-09-20-device-local-shortcut-preferences.md) owns accepted bindings and revision publication. + +## Alternatives considered + +**Use Electron's native close role.** It closes the window without asking the focused page owner and cannot preserve page cleanup or the accepted custom binding's routing. + +**Disable the Windows window fallback.** This avoids a task-stopping close shortcut but omits the PRD's explicit Desktop fallback. The product keeps native window-close semantics; users who need the application to remain running can minimize it. + +## Consequences + +Close behaves consistently across the shortcut and macOS File menu. On Windows and Linux, pressing it outside a closeable sidebar page can stop active tasks by quitting the instance. The command does not add a background Host lifetime or a task-aware shutdown confirmation. Desktop keyboard tests cover revision and focus guards; sidebar focus tests cover captured page identity and stale targets; startup tests cover the platform menu declarations. diff --git a/.agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.zh.md b/.agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.zh.md new file mode 100644 index 0000000000..6ef60c084f --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.zh.md @@ -0,0 +1,27 @@ +# Agent Note: Desktop 关闭快捷键跟随页面焦点 + +Status: implemented + +[English](2026-09-21-desktop-page-close-shortcuts.md) | 中文 + +## 问题 + +[快捷键 PRD](https://trtgsjkv6r.feishu.cn/wiki/APvtwgbztiBLzvk9DM4cQbccnhf) 为关闭命令规定了两类目标:获得焦点的右侧栏页面,或没有可关闭页面时的 Desktop 窗口。Electron 原生 close role 绕过页面 owner。Windows 关闭最后一个窗口还会退出 Desktop 实例并停止其 Host 任务,因此该回退属于生命周期选择,不只是菜单标签变更。 + +## 决策 + +侧栏页面 owner 根据实时焦点解析关闭操作,并捕获目标的 Session、窗格、tab occurrence 和导航 revision。它通过资源清理处理器关闭该页面,或收起唯一的停靠引导页。过期侧栏目标不会回退到其他页面或窗口。没有可关闭页面时,Desktop 请求原生窗口关闭;Web 没有窗口回退。 + +macOS File 菜单通过同一个 owner 路由“关闭页面或窗口”,并显示已接受的单键绑定。原生关闭要求配置 revision 仍为当前值、产品窗口已聚焦且启用,并且没有在录制快捷键。现有窗口生命周期直接生效,不增加快捷键专用确认:macOS 最后一个窗口关闭后保留应用;Windows 和 Linux 退出并停止 Host。 + +本决策接管[标准 macOS 菜单记录](../bug-fix/2026-09-16-desktop-window-menus.zh.md)中 close role 选择所涉及的 File 菜单和关闭行为。该记录保留原生 Window 与应用隐藏命令的理由。[快捷键偏好持久化](2026-09-20-device-local-shortcut-preferences.zh.md)负责已接受绑定及 revision 发布。 + +## 考虑过的替代方案 + +**使用 Electron 原生 close role。** 它不询问获得焦点的页面 owner 就关闭窗口,无法保留页面清理和已接受自定义绑定的路由。 + +**禁用 Windows 窗口回退。** 这能避免关闭快捷键停止任务,但会遗漏 PRD 明确要求的 Desktop 回退。产品保留原生关窗语义;需要应用继续运行时,用户可以最小化窗口。 + +## 影响 + +快捷键与 macOS File 菜单的关闭行为一致。在 Windows 和 Linux 上,焦点不在可关闭侧栏页面时按下该快捷键,可能因退出实例而停止活动任务。该命令不增加后台 Host 生命周期或感知任务状态的退出确认。Desktop 键盘测试覆盖 revision 和焦点保护;侧栏焦点测试覆盖捕获的页面身份和过期目标;启动测试覆盖各平台菜单声明。 diff --git a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.i18n.yaml new file mode 100644 index 0000000000..e8573b2e72 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-21-experimental-capabilities-as-optional-bundles.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md +/agent-note-ship-experimental-capabilities-as-optional-bundles: + en: 9ec3d64c70d601b6 + zh: c85722cfc7bf70df +/agent-note-ship-experimental-capabilities-as-optional-bundles/problem: + en: 2ba6c43b20a3d347 + zh: 5647179ddaa38ad9 +/agent-note-ship-experimental-capabilities-as-optional-bundles/decision: + en: 1c5a43b3ce2d3056 + zh: b59f549a12cf67d1 +/agent-note-ship-experimental-capabilities-as-optional-bundles/alternatives-considered: + en: a65d84004e48b3ef + zh: 17221f08e7a8a89b +/agent-note-ship-experimental-capabilities-as-optional-bundles/consequences: + en: d52ed0a248131a37 + zh: 779b8d415281c5da diff --git a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md new file mode 100644 index 0000000000..a2a83645c9 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md @@ -0,0 +1,25 @@ +# Agent Note: Ship experimental capabilities as optional bundles + +Status: implemented + +English | [中文](2026-09-21-experimental-capabilities-as-optional-bundles.zh.md) + +## Problem + +The Web plugin page offered two optional bundles, Agent Teams and voice input. Auto review and the Inspector were published experimental packages that a person had to install by name or mount through a hand-written profile patch, although both already declared a bundle patch or shipped a mountable overlay. + +## Decision + +`OPTIONAL_BUNDLES` lists Agent Teams, voice input, and Auto review. Every optional bundle declares `icon` and exports `./locale/*.json` with `meta.title` and `meta.description`, so the Official group renders a localized title, description, and image; `verify-default-product-isolation` rejects an optional bundle without them. The Inspector's `cordis.patch.yml` names the package instead of a built-artifact path, so the same file is the bundle patch and the `--patch` overlay for a built Web launch. + +An optional bundle is a runtime dependency of the installation, so its dependency graph is downloaded by every `dsh` install. The list therefore admits only packages whose graph is already in the installation's closure; Auto review adds nothing. The Inspector stays available through explicit installation and does not appear in the default plugin list. The browser-use and computer-use providers stay explicit compositions: Playwright MCP, Chrome DevTools MCP, and the native Cua Driver runtime binaries add about 85 MB and 21 packages to every install whether or not the bundle is enabled, and a shipped Cua Driver MCP switch would offer a capability whose executable the installation does not carry. Those provider packages keep locale display metadata for their component rows. Two more packages stay out for other reasons: `ptc-runtime-python` replaces the PTC runtime, and `workflow-ptc` rejects a non-TypeScript runtime at load while the Web presets carry `workflow-ptc` rows a bundle patch cannot reach; `browser-use-stagehand-native` requires a native model name and API key at schema validation with no configuration form on the page. + +## Alternatives considered + +**Ship every provider as an optional bundle.** Composes and displays correctly, but grows every install by provider runtimes for a capability most installations never switch on; voice input's `sherpa-onnx-node` is the one accepted precedent. + +**Mount the registration-only `computer-use` and `browser-use` services in `dsh-base`.** The shared composition would carry rows that only an optional provider bundle needs; a provider bundle can insert the service row from its own patch and dependencies. + +## Consequences + +The Official group grows from two to three entries, each tagged experimental by its experimental name. The runtime dependency closure of the installation is unchanged. A browser-use or computer-use provider still needs its Service Definition and the provider in a profile patch or composition. diff --git a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md new file mode 100644 index 0000000000..62e248e5ae --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md @@ -0,0 +1,25 @@ +# Agent Note: 将实验能力作为可选 bundle 发布 + +Status: implemented + +[English](2026-09-21-experimental-capabilities-as-optional-bundles.md) | 中文 + +## 问题 + +Web 插件页只提供两个可选 bundle:Agent Teams 与语音输入。Auto review 与 Inspector 都是已发布的实验包,用户必须按名称安装或手写 profile patch 才能挂载,尽管两者已经声明了 bundle patch 或附带可挂载的 overlay。 + +## 决策 + +`OPTIONAL_BUNDLES` 列出 Agent Teams、语音输入与 Auto review。每个可选 bundle 都声明 `icon` 并导出带 `meta.title` 与 `meta.description` 的 `./locale/*.json`,官方分组因此能渲染本地化标题、描述和图片;`verify-default-product-isolation` 会拒绝缺少这些声明的可选 bundle。Inspector 的 `cordis.patch.yml` 直接写包名而非构建产物路径,所以同一文件既是 bundle patch,也是已构建 Web 启动的 `--patch` overlay。 + +可选 bundle 是安装的运行时依赖,其依赖图会随每次 `dsh` 安装一起下载。因此名单只接纳依赖图已在安装闭包内的包;Auto review 不增加任何依赖。Inspector 保留显式安装方式,不在默认插件列表中显示。浏览器操作与电脑操作提供方仍保持显式组合:Playwright MCP、Chrome DevTools MCP 与原生 Cua Driver 运行时二进制会让每次安装多出约 85 MB、21 个包,无论 bundle 是否启用;而随附的 Cua Driver MCP 开关会提供一个安装本身并不携带其可执行文件的能力。这些提供方包保留 locale 显示元数据,供组件行使用。另有两个包因其他原因不纳入:`ptc-runtime-python` 会替换 PTC 运行时,而 `workflow-ptc` 在加载时拒绝非 TypeScript 运行时,且 Web preset 内含 bundle patch 无法触及的 `workflow-ptc` 行;`browser-use-stagehand-native` 在 schema 校验时就要求原生模型名称与 API 密钥,而插件页没有对应的配置表单。 + +## 考虑过的替代方案 + +**把所有提供方都做成可选 bundle。** 组合与展示都正确,但会为多数安装从不启用的能力把提供方运行时塞进每次安装;语音输入的 `sherpa-onnx-node` 是唯一被接受的先例。 + +**在 `dsh-base` 中挂载仅负责注册的 `computer-use` 与 `browser-use` 服务。** 共享组合将携带只有可选提供方 bundle 才需要的行;提供方 bundle 可以从自己的 patch 和依赖插入服务行。 + +## 后果 + +官方分组从两项增至三项,每项都因实验包名而带实验性标签。安装的运行时依赖闭包保持不变。浏览器操作或电脑操作提供方仍需在 profile patch 或组合中同时挂载其 Service Definition 与提供方。 diff --git a/.agents/notes/implemented/architecture/2026-09-21-live-config-inspect-provider.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-21-live-config-inspect-provider.i18n.yaml index eae4bb9b59..a9e885fe52 100644 --- a/.agents/notes/implemented/architecture/2026-09-21-live-config-inspect-provider.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-21-live-config-inspect-provider.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-21-live-config-inspect-provider.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-21-live-config-inspect-provider.md -2026-09-21-live-config-inspect-provider.md: b4be50852693665780da37b03c130339afa0ef57 -2026-09-21-live-config-inspect-provider.zh.md: e1eead7b68f12be320e5c34b621178f44cd26282 +/agent-note-live-plugin-config-inspection-replaces-the-host-builtin-provider: + en: f57edbb8b3fa60ae + zh: 8d0fa0eb73bbdaf1 +/agent-note-live-plugin-config-inspection-replaces-the-host-builtin-provider/problem: + en: e01cc31ce200b24b + zh: 7462a52c3e59ec87 +/agent-note-live-plugin-config-inspection-replaces-the-host-builtin-provider/decision: + en: a7d21366030c31ac + zh: 047299df13e504b7 +/agent-note-live-plugin-config-inspection-replaces-the-host-builtin-provider/alternatives-considered: + en: a19dba57a4108fc6 + zh: 2e64893e8bcf6513 +/agent-note-live-plugin-config-inspection-replaces-the-host-builtin-provider/consequences: + en: efa454977043c76d + zh: d6bf61ac47310d3e diff --git a/.agents/notes/implemented/architecture/2026-09-22-fatal-diagnostics-and-crash-reports.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-22-fatal-diagnostics-and-crash-reports.i18n.yaml index 89a855ae78..567f3220b2 100644 --- a/.agents/notes/implemented/architecture/2026-09-22-fatal-diagnostics-and-crash-reports.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-22-fatal-diagnostics-and-crash-reports.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-22-fatal-diagnostics-and-crash-reports.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-22-fatal-diagnostics-and-crash-reports.md -2026-09-22-fatal-diagnostics-and-crash-reports.md: 01cbb24fc84b19465a15e9f82c03ae87621b5fe9 -2026-09-22-fatal-diagnostics-and-crash-reports.zh.md: 38f6a6802b61b128ab6b8ffda0465691c5244523 +/agent-note-fatal-diagnostics-and-desktop-crash-reports: + en: a87890699e70ccc6 + zh: 189d21b852a20760 +/agent-note-fatal-diagnostics-and-desktop-crash-reports/problem: + en: f7d0c561d7576f9a + zh: ac96a7d1c470c8cf +/agent-note-fatal-diagnostics-and-desktop-crash-reports/decision: + en: ac461e0ea1702ecc + zh: 745def8581dc7974 +/agent-note-fatal-diagnostics-and-desktop-crash-reports/relationship-to-earlier-decisions: + en: 157e52fc4036044a + zh: e474d9c9a36f1381 +/agent-note-fatal-diagnostics-and-desktop-crash-reports/relationship-to-the-desktop-logging-design: + en: 7dc438912d10574a + zh: 07d05f9f17043d67 +/agent-note-fatal-diagnostics-and-desktop-crash-reports/testing: + en: 864a8e71e3b3378b + zh: a71807db24d9409c +/agent-note-fatal-diagnostics-and-desktop-crash-reports/consequences: + en: a9bf0176caf92221 + zh: 169d31d00bd28585 +/agent-note-fatal-diagnostics-and-desktop-crash-reports/alternatives-considered: + en: 5b5cf601759d1ff1 + zh: 2171128e2b3aa799 diff --git a/.agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.i18n.yaml new file mode 100644 index 0000000000..d962ba868a --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-22-platform-browser-storage.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.md +/agent-note-account-scoped-platform-browser-storage: + en: ade088e230a39dd2 + zh: 437a9be5fe2ef704 +/agent-note-account-scoped-platform-browser-storage/problem: + en: 84cfcf61f58fab58 + zh: 14844d5e3d3638fe +/agent-note-account-scoped-platform-browser-storage/decision: + en: 7c8ec7ea318f3689 + zh: 2c45ac28670dfda1 +/agent-note-account-scoped-platform-browser-storage/alternatives-considered: + en: 101fa0ff0b01b096 + zh: 6c6b0a4136531d6b +/agent-note-account-scoped-platform-browser-storage/consequences: + en: 0aa0a16abba90b43 + zh: 6fcb59f3ecea2e54 diff --git a/.agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.md b/.agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.md new file mode 100644 index 0000000000..31fd984af9 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.md @@ -0,0 +1,23 @@ +# Agent Note: Account-scoped Platform browser storage + +Status: implemented + +English | [中文](2026-09-22-platform-browser-storage.zh.md) + +## Problem + +Embedded Platform notices store dismissal in localStorage. Disposable browser partitions lose that preference whenever the view closes. + +## Decision + +Desktop partitions browser storage by a SHA-256 hash of the Platform origin and stable account ID. Persistent partitions retain localStorage page preferences across view and application lifetimes, including sign-out and later sign-in to the same account. Raw account IDs and tokens do not appear in partition names. While the Host has no account ID from a successful profile read, the view uses a disposable partition, so preparing a Platform session never waits for a profile request. An ID that arrives for the credential already open leaves the mounted disposable document in place; the next open uses the account-scoped partition. + +A persistent partition keeps only localStorage; opening one clears cookies, filesystem, IndexedDB, Cache Storage, the HTTP and shader caches, service workers, and HTTP authentication before the document loads, while a disposable partition clears all of its storage. Closing a view destroys its document, detaches the credential-bearing request interceptors, and schedules the same cleanup, so authentication left by an unclean exit is cleared before the next document loads. The next open and application shutdown await that cleanup, and an update install awaits it before the installer takes over the exit; shutdown reports a failure instead of blocking the quit. A failed cleanup rejects that open and keeps its account from opening again until a later cleanup succeeds, while other accounts keep opening. Host-only credentials still enter the trusted page through the existing preload and are not written to browser storage by the bridge. + +## Alternatives considered + +One shared partition mixes account preferences. Token-derived names discard preferences when credentials change. A notice-specific native API would duplicate Platform preference ownership and require coordinated frontend changes. Clearing storage only when a view closes leaves authentication from an unclean exit readable by the next document. + +## Consequences + +Preferences remain local to this Desktop browser-data directory and are not synchronized across devices. Platform scripts remain trusted to handle the credential they receive; persistent site storage is not a credential vault. Storage for a signed-out account stays on disk until that account signs in again or the browser-data directory is removed. The real Electron regression checks notice dismissal across view recreation, account switches, and process restart, and that cookies, Cache Storage, and IndexedDB are cleared, a page beforeunload handler does not hold the close, a disposable session neither inherits nor retains preferences, and cookie residue from a previous process is cleared. diff --git a/.agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.zh.md b/.agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.zh.md new file mode 100644 index 0000000000..ebaea7b642 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.zh.md @@ -0,0 +1,23 @@ +# Agent Note: 按账号隔离的 Platform 浏览器存储 + +Status: implemented + +[English](2026-09-22-platform-browser-storage.md) | 中文 + +## Problem + +内嵌 Platform 通知将关闭状态写入 localStorage。一次性浏览器分区会在每次关闭视图后丢失该偏好。 + +## Decision + +Desktop 使用 Platform 来源和稳定账号 ID 的 SHA-256 哈希划分浏览器存储。持久分区跨视图和应用生命周期保留 localStorage 页面偏好,包括退出登录后再次登录同一账号。分区名不包含原始账号 ID 或 token。在 Host 尚未从成功的资料读取获得账号 ID 期间,视图使用一次性分区,因此准备 Platform 会话不会等待资料请求。同一凭证下账号 ID 迟到时,已挂载的一次性文档保持不变;下次打开使用账号分区。 + +持久分区只保留 localStorage;打开持久分区会先清理 Cookie、文件系统、IndexedDB、Cache Storage、HTTP 与着色器缓存、Service Worker 及 HTTP 认证状态,而一次性分区会清理其全部存储。关闭视图会销毁文档、移除携带凭证的请求拦截器并安排相同的清理,因此异常退出遗留的认证会在下一个文档加载前被清除。下次打开和应用退出都会等待该清理完成,更新安装也会在安装器接管退出前等待;退出流程上报清理失败,而不阻塞退出。清理失败会使该次打开失败,并在后续清理成功前阻止同一账号再次打开,其他账号不受影响。仅限 Host 的凭证仍通过现有 preload 传入受信任页面,bridge 不会将其写入浏览器存储。 + +## Alternatives considered + +共享分区会混用账号偏好。以 token 命名会在凭证变化时丢失偏好。专用于通知的原生 API 会重复承担 Platform 偏好管理职责,并要求前端同步修改。只在关闭视图时清理,会让异常退出遗留的认证被下一个文档读取。 + +## Consequences + +偏好仅保存在此 Desktop 浏览器数据目录中,不跨设备同步。Platform 脚本仍须可信地处理收到的凭证;持久站点存储不是凭证保险库。已退出账号的存储会保留在磁盘上,直到该账号再次登录或浏览器数据目录被删除。真实 Electron 回归测试验证视图重建、账号切换和进程重启后的通知关闭状态,并断言 Cookie、Cache Storage 和 IndexedDB 已清理、页面 beforeunload 处理函数不会阻止关闭、一次性会话既不继承也不保留偏好,以及上一进程遗留的 Cookie 已清除。 diff --git a/.agents/notes/implemented/architecture/2026-09-22-schedule-hard-delete-and-bounded-history.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-22-schedule-hard-delete-and-bounded-history.i18n.yaml new file mode 100644 index 0000000000..575b3ca146 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-22-schedule-hard-delete-and-bounded-history.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-22-schedule-hard-delete-and-bounded-history.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-22-schedule-hard-delete-and-bounded-history.md +/agent-note-schedule-deletes-task-rows-and-bounds-delivery-history: + en: 17a73230ad22ec0b + zh: 5bcf27d7c0e86764 +/agent-note-schedule-deletes-task-rows-and-bounds-delivery-history/problem: + en: 98e82a0add324882 + zh: c10e85a3f2a522f8 +/agent-note-schedule-deletes-task-rows-and-bounds-delivery-history/decision: + en: 56328745115714b5 + zh: f30d39f59aa06a13 +/agent-note-schedule-deletes-task-rows-and-bounds-delivery-history/alternatives-considered: + en: 0c4eb01054be1141 + zh: 95980f8097fa36fd +/agent-note-schedule-deletes-task-rows-and-bounds-delivery-history/consequences: + en: 05121f4b77b8ee12 + zh: 1751c9b1a752ce6b diff --git a/.agents/notes/implemented/architecture/2026-09-22-schedule-hard-delete-and-bounded-history.md b/.agents/notes/implemented/architecture/2026-09-22-schedule-hard-delete-and-bounded-history.md new file mode 100644 index 0000000000..90127d6887 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-22-schedule-hard-delete-and-bounded-history.md @@ -0,0 +1,33 @@ +# Agent Note: Schedule deletes task rows and bounds delivery history + +Status: implemented + +English | [中文](2026-09-22-schedule-hard-delete-and-bounded-history.zh.md) + +## Problem + +The Schedule domain is one whole-unit JSON document that the backend rewrites on every mutation, so every retained byte in a task row grows every write. Saved delivery records were unbounded: each acknowledgment appended to the array, and a deleted task kept its row and records so the open detail could still read them. The document's size therefore followed a task's delivery count, and deletion added a state every reader had to skip. + +## Decision + +Deletion is hard deletion. `ScheduleService.delete` removes the storage row through `tasks.delete`, so the task stops scheduling, leaves `list` and `catalog`, and `history` answers `schedule_not_found` for the same `(sessionId, id)`; the row's saved delivery records are removed with it. The task schema has no `deleted` field, and no client surface offers a recycle bin or a read of an already deleted task's records. + +Delivery history is bounded by plugin `Config`: `deliveryHistoryDays` (default 30, 1–3650) and `deliveryHistoryRecords` (default 200, 1–10000). `appendDelivery` applies both bounds on the only write path. It keeps the records whose `deliveredAt` is at or after the appended receipt's `deliveredAt` minus the configured day window, keeps the newest `deliveryHistoryRecords` of those, and always retains the appended latest receipt; a pruned window sets `earlierRecordsUnavailable` and `earlierRecordsPruned`, which later appends preserve. The latter flag is optional in stored rows and confirms actual removal; legacy unavailability alone does not imply pruning. The history response includes the current retention limits, and the Client shows the cleanup notice only for confirmed pruning after loading the final nonempty page. + +The [Host-owned scheduled messages](2026-09-16-host-schedule-storage.md) note keeps the rest of its decision: one authoritative version-1 task domain, timer restoration for active tasks only, cold-Session delivery through the Session controller, the catalog and detail surfaces, and the historical-versus-Host decoder split. Its status vocabulary is `active` or `inactive`; `inactive` is the sole non-active name, and the client filter row reads All, Enabled, and Inactive. That note stays active: this supersession is partial, so it is neither archived nor frozen, and it remains the owner of everything above while the deletion and retention decisions it recorded are replaced here. + +## Alternatives considered + +**Keep the retained `deleted` row.** The flag existed so `history` could answer after deletion. Nothing read those records after deletion, the row kept every prompt snapshot in the storage document, and the state had to be excluded by hand from `list`, `catalog`, and the timer. Removing the row makes deletion mean one thing. + +**Bound only by record count.** A count cap alone keeps arbitrarily old receipts when deliveries are sparse, and it drops a burst of recent ones when they are not. The day window bounds staleness while the cap bounds the document. + +**Measure the window from the task instead of from each receipt.** Anchoring the window to the task's creation or committed target would discard a newly written receipt of an old task. Measuring back from the appended receipt's `deliveredAt` keeps the window anchored to the data being kept. + +**Keep history unbounded and let operators clean up.** The domain publishes one whole-unit document per write, so unbounded history makes the storage document's size a function of delivery counts. Retention is a bound the storage layout requires, not a retention preference. + +## Consequences + +Deletion now offers no recovery: a deleted task's saved deliveries cannot be read back, and a task that still needs its full history must be read before deletion. Configured retention also discards receipts the task once had; the retained flag records that a window was pruned rather than pretending the history is complete. + +In exchange, the persisted task set has one deletion semantics, the storage document's size is bounded by configuration instead of by delivery counts, and `inactive` is the only non-active lifecycle name. The plugin `Config` is the place to raise the bounds when a deployment needs longer delivery history. diff --git a/.agents/notes/implemented/architecture/2026-09-22-schedule-hard-delete-and-bounded-history.zh.md b/.agents/notes/implemented/architecture/2026-09-22-schedule-hard-delete-and-bounded-history.zh.md new file mode 100644 index 0000000000..dfc8ab4ff3 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-22-schedule-hard-delete-and-bounded-history.zh.md @@ -0,0 +1,33 @@ +# Agent Note: Schedule 删除任务行并限制投递历史 + +Status: implemented + +[English](2026-09-22-schedule-hard-delete-and-bounded-history.md) | 中文 + +## Problem + +Schedule domain 是后端每次变更都会重写的单个整 unit JSON 文档,因此任务行中保留的每个字节都会随每次写入增长。已保存的发送记录没有上限:每次确认都会向数组追加,而被删除的任务会保留其行与记录,以便已打开的详情仍能读取。于是文档大小随任务的投递次数变化,删除还引入了一个所有读取方都必须跳过的状态。 + +## Decision + +删除是硬删除。`ScheduleService.delete` 通过 `tasks.delete` 移除存储行,因此任务停止调度、离开 `list` 与 `catalog`,`history` 对相同的 `(sessionId, id)` 返回 `schedule_not_found`;该行已保存的投递记录随行一并移除。任务 schema 没有 `deleted` 字段,也没有任何界面提供回收站或读取已删除任务记录的能力。 + +投递历史受插件 `Config` 限制:`deliveryHistoryDays`(默认 30,1–3650)与 `deliveryHistoryRecords`(默认 200,1–10000)。`appendDelivery` 在唯一的写入路径上同时应用这两个上限。它保留 `deliveredAt` 不早于「本次追加回执的 `deliveredAt` 减去配置的天数窗口」的记录,在其中保留最新的 `deliveryHistoryRecords` 条,并始终保留本次追加的最近一次回执;发生裁剪时设置 `earlierRecordsUnavailable` 和 `earlierRecordsPruned`,后续追加会保留这两个标志。后者在存储行中可选,用于确认实际删除;仅有旧格式的不可用标志不表示发生过裁剪。历史响应携带当前保留上限,客户端仅在加载完最后一页且历史非空、确认裁剪时显示清理提示。 + +[Host-owned scheduled messages](2026-09-16-host-schedule-storage.zh.md) 笔记保留其余决策:唯一的权威版本 1 任务 domain、只为活动任务恢复定时器、通过 Session controller 投递到冷会话、目录与详情界面,以及历史解码器与宿主解码器的划分。其状态词汇为 `active` 或 `inactive`;`inactive` 是唯一的非活动名称,客户端筛选行为全部、活动和未运行。该笔记保持活动状态:这是一次部分取代,因此它既未归档也未冻结,仍是上述内容的归属笔记,而它记录的删除与保留决策由本笔记取代。 + +## Alternatives considered + +**保留带 `deleted` 标志的任务行。** 该标志的存在是为了让 `history` 在删除后仍能回答。删除后没有任何代码读取这些记录,而该行把每个提示文本快照都留在存储文档中,还必须手工把它排除在 `list`、`catalog` 和定时器之外。移除该行让删除只有一种含义。 + +**只按条数设上限。** 仅有条数上限时,投递稀疏的任务会保留任意久远的回执,投递密集时又会丢弃近期的一批回执。天数窗口限制陈旧程度,条数上限限制文档大小。 + +**以任务而非每条回执为窗口起点。** 把窗口锚定在任务的创建时间或已提交目标上,会丢弃旧任务刚写入的回执。从本次追加回执的 `deliveredAt` 向前计算,使窗口锚定在所要保留的数据上。 + +**保留无上限的历史,由运维清理。** 该 domain 每次写入都发布整个 unit 文档,因此无上限的历史会让存储文档的大小随投递次数增长。保留上限是存储布局所要求的约束,而不是保留策略偏好。 + +## Consequences + +删除不再提供恢复能力:已删除任务的已保存投递无法再读回,仍需要完整历史的必须在删除前读取。配置的保留策略也会丢弃任务曾经拥有的回执;保留的标志记录窗口发生过裁剪,而不是假装历史完整。 + +换取的是:持久任务集合只有一种删除语义,存储文档大小由配置而非投递次数决定,且 `inactive` 是唯一的非活动生命周期名称。当某个部署需要更长的投递历史时,应提高插件 `Config` 中的上限。 diff --git a/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.i18n.yaml index bfbfe3cdf3..48da0f768d 100644 --- a/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-22-tool-call-three-phases.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.md -2026-09-22-tool-call-three-phases.md: e7b42a4ed9e340b73257f7053bddd5221ccc0d20 -2026-09-22-tool-call-three-phases.zh.md: 5a68575fd8e2a68199cbedf1ac180a22254b7c54 +/agent-note-tool-calls-own-preparation-dispatch-and-results-by-callid: + en: d8d1cdcedf0b5d8e + zh: 79e4466489558365 +/agent-note-tool-calls-own-preparation-dispatch-and-results-by-callid/problem: + en: 0539e5f25f594681 + zh: 5446bd08229eab9b +/agent-note-tool-calls-own-preparation-dispatch-and-results-by-callid/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-tool-calls-own-preparation-dispatch-and-results-by-callid/decision/one-tool-owns-three-stages: + en: ea65da88c3df35bb + zh: a71afb4683a75290 +/agent-note-tool-calls-own-preparation-dispatch-and-results-by-callid/decision/start-marks-an-initialization-candidate: + en: 696a180246e23391 + zh: aeb2b1fdcfdf9631 +/agent-note-tool-calls-own-preparation-dispatch-and-results-by-callid/decision/converge-on-final-state-without-replaying-preparation: + en: 603cbcf3379ad4f7 + zh: e34d87ea348c756b +/agent-note-tool-calls-own-preparation-dispatch-and-results-by-callid/decision/shared-rows-reuse-their-existing-presentation: + en: 24536588cd0c979b + zh: 992d4c4657d6d034 +/agent-note-tool-calls-own-preparation-dispatch-and-results-by-callid/decision/relationship-to-existing-records: + en: bd4984f66c507785 + zh: 4d2372fdbc4c3cec +/agent-note-tool-calls-own-preparation-dispatch-and-results-by-callid/alternatives-considered: + en: 505095bec889700e + zh: b77c492de3e8641a +/agent-note-tool-calls-own-preparation-dispatch-and-results-by-callid/consequences: + en: 3cf36b54240013da + zh: 67e663b431bc67d2 diff --git a/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.md b/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.md index e7b42a4ed9..f43eaf1a68 100644 --- a/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.md +++ b/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.md @@ -18,7 +18,7 @@ The [Tool Definition](../../../../packages/client/ui-chat/src/client/conversatio | Stage | Creation or update evidence | Available data and presentation | |---|---|---| -| `preparing` | A live delta with a call ID and tool name | Call identity, name, and time; no argument body, and one non-expandable row. | +| `preparing` | A live delta with a call ID and tool name | Call identity, name, and time; no complete arguments, and one non-expandable row. An opt-in Hook can read the raw argument prefix. | | `start` | `tool/call` | Complete arguments; enables the tool's existing call presentation. | | `result` | `tool/result` | The result and any complete arguments paired within the loaded window. | @@ -30,7 +30,7 @@ The [Conversation Definition](../../../../packages/client/ui-conversation/src/cl A named tool delta and `tool/call` are both initialization candidates. A live delta can create preparation; a historical `tool/call` creates the dispatched stage directly. Matching still reads only the current event, without Context lookup, additional roles, registries, or separate caches. -When stream settlement removes temporary deltas, the Assembler selects the start from the remaining Matches, refreshes predecessor indexes, and recomputes State. A published preparation node hides when no call evidence remains; a later dispatch retains the same callId. Undispatched calls do not receive synthetic execution results. +Successful stream settlement publishes the final Assistant message while retaining transient deltas until `step/end`. Each `tool/call` updates its existing callId; the Assistant keeps its live ordering anchor until the same cleanup. Failed, interrupted, or abandoned streams retire their deltas immediately. On retirement the Assembler reselects starts and recomputes State from remaining Matches. Undispatched preparations hide without synthetic execution results. ### Converge on final state without replaying preparation @@ -40,7 +40,7 @@ Groups include Tool nodes from preparation onward and classify and count them by ### Shared rows reuse their existing presentation -[ToolRow](../../../../packages/client/ui-tool/src/client/tool/components/ToolRow.tsx) reuses the existing icon, title, and row component across all stages. The shared row model selects the tool title and combines any generic tool-name prefix with the available argument summary. Preparation has no arguments or result, and the shared argument parser returns null without parsing JSON. ToolRow prevents preparation rows from expanding. +[ToolRow](../../../../packages/client/ui-tool/src/client/tool/components/ToolRow.tsx) reuses the existing icon, title, and row component across all stages. The shared row model selects the tool title and combines any generic tool-name prefix with the available argument summary. Preparation has no complete arguments or result, and the shared argument parser returns null without parsing JSON. The existing slot Hook binding optionally exposes a call-scoped raw prefix; it adds no preparation registration mechanism. ToolRow prevents preparation rows from expanding. Read, read_image, write/edit, search, web, todo, question, details, and the generic fallback use this path. Custom rows such as Bash, Skill, Present, and Cordis keep their own preparation branches. No automatic/custom registration declaration or second tool-classification list in ToolTree is introduced. @@ -62,6 +62,6 @@ This decision replaces the [business-node assembly](2026-08-09-client-conversati - A tool may appear before its arguments are complete, but preparation neither implies execution nor exposes interactions requiring arguments. - Multiple starts with one ID belong to one lifecycle. Independent calls must use distinct IDs; a second-start error no longer detects identity reuse. -- Shared rows do not replace the whole row component when preparation becomes dispatch. Custom rows may still switch their internal components by stage. -- Partial JSON parsing and `useToolCallDelta` are not provided; argument-driven early presentation is outside this implementation. +- The shared row primitive is reused across stages. Write/edit separate preparing and dispatched components so only the former subscribes to raw arguments; custom rows may also switch internal components by stage. +- Partial JSON parsing and `useToolCallDelta` are not provided. `useToolCallArgumentsPartial` exposes the existing Step's raw prefix without a second accumulator; write/edit use only its length for preparation progress. - Assembly tests separately cover live preparation, withdrawal, active-stream reconstruction, durable history, and paged convergence. Component tests cover argument-free presentation and stage changes; a recorded session covers browser preparation and reload results. diff --git a/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.zh.md b/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.zh.md index 5a68575fd8..accbd2e966 100644 --- a/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-22-tool-call-three-phases.zh.md @@ -18,7 +18,7 @@ Status: implemented | 阶段 | 创建或更新依据 | 可用数据与展示 | |---|---|---| -| `preparing` | 带调用 ID 和工具名的实时 delta | 调用身份、名称和时间;不提供参数正文,只显示不可展开的一行。 | +| `preparing` | 带调用 ID 和工具名的实时 delta | 调用身份、名称和时间;不提供完整参数,只显示不可展开的一行。可选钩子可读取原始参数前缀。 | | `start` | `tool/call` | 完整参数;启用工具原有的调用展示。 | | `result` | `tool/result` | 调用结果,以及当前窗口内可配对的完整参数。 | @@ -30,7 +30,7 @@ Status: implemented Tool 的具名 delta 和 `tool/call` 都是创建入口。实时先收到 delta,就从 preparing 创建;历史先收到 `tool/call`,就从 start 创建。匹配函数仍然只读取当前事件,不查询 Context,不增加角色、注册表或旁路缓存。 -流结束移除临时 delta 后,Assembler 从剩余 Match 重新选择 start,刷新前序索引并重算 State。没有剩余调用证据时,已发布的准备节点隐藏;后续正式调用仍使用相同 callId。未派发的调用不合成执行结果。 +成功流结束时发布最终 Assistant 消息,瞬态 delta 保留到 `step/end`。每个 `tool/call` 更新已有 callId;Assistant 的实时排序锚点也保留到同一次清理。失败、中断或废弃的流立即移除 delta。清理时,Assembler 从剩余 Match 重新选择 start 并重算 State;未派发的准备节点隐藏,不合成执行结果。 ### 最终状态收敛,不重现准备过程 @@ -40,7 +40,7 @@ Group 从准备阶段起就聚合 Tool 节点,按工具名分类和计数。As ### 通用行复用现有外壳 -[ToolRow](../../../../packages/client/ui-tool/src/client/tool/components/ToolRow.tsx) 在三个阶段复用既有图标、标题和行组件。公共行模型选择工具标题,并组合通用工具名前缀与已有参数摘要。准备阶段没有参数或结果,共享参数解析入口直接返回 null,不解析 JSON;ToolRow 禁止准备行展开。 +[ToolRow](../../../../packages/client/ui-tool/src/client/tool/components/ToolRow.tsx) 在三个阶段复用既有图标、标题和行组件。公共行模型选择工具标题,并组合通用工具名前缀与已有参数摘要。准备阶段没有完整参数或结果,共享参数解析入口直接返回 null,不解析 JSON。既有 slot 钩子绑定可选地提供当前调用的原始前缀,不增加准备态注册机制;ToolRow 禁止准备行展开。 read、read_image、write/edit、search、web、todo、question、details 和通用回退使用这条路径。Bash、Skill、Present、Cordis 等自定义外壳保留自己的准备态分支。不增加自动/自管注册声明,不在 ToolTree 维护另一份工具分类名单。 @@ -62,6 +62,6 @@ read、read_image、write/edit、search、web、todo、question、details 和通 - 工具可以在参数完整前出现,但准备展示不表示工具已经执行,也不暴露依赖参数的交互。 - 同一 ID 的多个 start 被视为同一个生命周期;业务必须为独立调用提供不同 ID,不能再依赖第二个 start 报错检测身份复用。 -- 通用行不因准备/派发分支替换整行组件;自定义外壳仍可按阶段切换内部组件。 -- 不提供部分 JSON 解析或 `useToolCallDelta`,参数驱动的提前展示不属于本次实现。 +- 各阶段复用通用行基础组件。write/edit 分离准备态与派发后组件,只有前者订阅原始参数;自定义外壳也可按阶段切换内部组件。 +- 不提供部分 JSON 解析或 `useToolCallDelta`。`useToolCallArgumentsPartial` 暴露既有 Step 的原始前缀,不另建累积器;write/edit 只使用其长度展示准备进度。 - 组装测试分别覆盖实时准备态、撤回、活跃流重建、持久历史与分页收敛;组件测试检查无参数展示和阶段切换,录制会话覆盖浏览器中的准备态与重载结果。 diff --git a/.agents/notes/implemented/architecture/2026-09-23-best-effort-persistent-ptc.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-23-best-effort-persistent-ptc.i18n.yaml index 89b99cd7d7..2206de0b42 100644 --- a/.agents/notes/implemented/architecture/2026-09-23-best-effort-persistent-ptc.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-23-best-effort-persistent-ptc.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-23-best-effort-persistent-ptc.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-23-best-effort-persistent-ptc.md -2026-09-23-best-effort-persistent-ptc.md: ab35a716ff6c0c7330e0c62500b84ee6173b988a -2026-09-23-best-effort-persistent-ptc.zh.md: 0ec7ae1f7c789eadd87c80365354f914fc720b98 +/agent-note-best-effort-persistent-ptc-memory: + en: 002038f955af77c1 + zh: 4a49c3f5a2b7cb43 +/agent-note-best-effort-persistent-ptc-memory/problem: + en: e42db40b879fdbf4 + zh: 3018bd35363e7051 +/agent-note-best-effort-persistent-ptc-memory/decision: + en: 3d3f7d0ff75dfe1c + zh: 10c12e18dc348896 +/agent-note-best-effort-persistent-ptc-memory/alternatives-considered: + en: 20e0ec55331dbcf6 + zh: e9eb7e0339c9a545 +/agent-note-best-effort-persistent-ptc-memory/consequences: + en: 544f61693ab010d5 + zh: 4c24fbd7fe849c0f diff --git a/.agents/notes/implemented/architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.i18n.yaml new file mode 100644 index 0000000000..28b2efa813 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-23-desktop-close-to-background-and-quit-confirmation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.md +/agent-note-hide-the-desktop-window-on-close-and-confirm-interruptible-quits: + en: 9e029938c58bf143 + zh: f60f9cf2067a02ee +/agent-note-hide-the-desktop-window-on-close-and-confirm-interruptible-quits/problem: + en: 782e934449eae28c + zh: 0941465dff3a26d9 +/agent-note-hide-the-desktop-window-on-close-and-confirm-interruptible-quits/decision: + en: 54c0d8811a8a4390 + zh: 2baa107b3d25a138 +/agent-note-hide-the-desktop-window-on-close-and-confirm-interruptible-quits/alternatives-considered: + en: 74dcbb66adffd7be + zh: 1be3d3fa8e68d81f +/agent-note-hide-the-desktop-window-on-close-and-confirm-interruptible-quits/consequences: + en: dc219aecdf03014e + zh: 621cd97cef5dc858 diff --git a/.agents/notes/implemented/architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.md b/.agents/notes/implemented/architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.md new file mode 100644 index 0000000000..67c7bf92e0 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.md @@ -0,0 +1,35 @@ +# Agent Note: Hide the Desktop window on close and confirm interruptible quits + +Status: implemented + +English | [中文](2026-09-23-desktop-close-to-background-and-quit-confirmation.zh.md) + +Window timing and shutdown ownership otherwise follow [showing the window before the Host starts](2026-09-09-desktop-immediate-window-and-direct-start.md); the task rule reuses the [update restart check](2026-08-25-electron-desktop-packaging-and-updates.md). This partially supersedes the [standard macOS window menus](../bug-fix/2026-09-16-desktop-window-menus.md) decision: ⌘W no longer destroys the window through Electron's role, and Dock activation reopens the hidden window when no window is visible instead of only when none exists. That note's menu declarations stay in force. + +## Problem + +Closing the Desktop window destroyed it. On macOS the Host kept running but the Dock rebuilt a fresh page, losing the current session, draft, and scroll position; on Windows the close quit the application and cut running tasks without any warning. Quit itself never asked, although the Host knows which agents, jobs, and scheduled reminders would stop. + +## Decision + +Closing the main window hides it on both platforms; the page and the Host keep running and the next show presents the same document. Windows gets a permanent tray icon (single click opens, context menu offers Open and Quit) because Windows users expect × to quit and need a visible way back, plus a first-close acknowledgement through the shared update-dialog overlay before hiding. Only Confirm records acknowledgement; cancellation keeps the window visible. Closing sends no system notification. macOS keeps the Dock and ships no menu bar icon. Closing the welcome window before the workspace opens quits on Windows and drops the unused main window on macOS, so the Dock rebuilds the welcome. + +Every ordinary quit entry asks the Host over the private IPC channel for two facts: active tasks under the update-restart rule, and armed scheduled reminders reported by the `schedule` family of `workspace/session-activity` for the sessions loaded in this run. Both absent, the quit proceeds silently; otherwise a native message box without an owner window shows one of three fixed explanations with Quit as the default and Cancel on Esc. Repeated quit requests join the open box, the copy is frozen while it is open, and approval does not re-inspect. A Host that is not ready cannot run tasks and the quit proceeds; an inspection failure or a missed two-second deadline counts as running tasks because a needless prompt is cheaper than a silent interruption. The installer restart, fatal recovery, the development restart command, and operating-system session end skip the confirmation. + +The Windows tray bitmaps are rendered from the vector icon at seven sizes and committed as an ICO; the confirmation on Windows uses the application icon in a task dialog and stays light because the control does not follow the application theme. The installer and uninstaller copy for a running application points at the tray. + +## Alternatives considered + +**Keep quitting on close and add a confirmation there.** It asks on every close, and Windows users would still lose background work whenever they dismissed the window. Hiding matches the product requirement that tasks continue. + +**Render the quit confirmation in the shell's HTML overlay.** The overlay needs a visible parent window and a working renderer; the quit must also work when the window is hidden or the page is stuck, so the native dialog is the reliable choice. + +**Reuse the update-tasks IPC request with a flag.** The quit needs a second fact and a shorter deadline; a distinct request keeps the update admission lock semantics untouched and lets both share one correlation id space. + +**Downscale one large bitmap for the tray.** Rasterizing the vector source per size keeps edges crisp at 100 % through 400 % display scale, which a single downscale does not guarantee. + +## Consequences + +Users can close the window freely; background tasks and scheduled reminders continue, and reopening restores the same page. Quitting warns only when it interrupts something. Windows carries a tray icon for the whole run, and a hidden window that finishes a user-initiated update download defers its install confirmation until the window is shown again. Reminders in sessions never loaded during the run are neither counted nor resumed until those sessions open, and Desktop does not enable scheduled tasks by default, so the scheduled-task copy appears only once that feature is on. + +Verification covers the four inspection outcomes, inspection failure and deadline, each quit entry's bypass or confirmation, the close-to-hide path with the tray and the first-close acknowledgement, the deferred update prompt, the Host-side inspection, the IPC correlation and deadline, and the committed tray icon's bitmap set. Windows tray and dialog behavior needs a manual pass on a Windows machine at several display scales. diff --git a/.agents/notes/implemented/architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.zh.md b/.agents/notes/implemented/architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.zh.md new file mode 100644 index 0000000000..e5a59bcd0b --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.zh.md @@ -0,0 +1,35 @@ +# Agent Note: Hide the Desktop window on close and confirm interruptible quits + +Status: implemented + +[English](2026-09-23-desktop-close-to-background-and-quit-confirmation.md) | 中文 + +窗口时序和关闭归属仍遵循[在 Host 启动前显示窗口](2026-09-09-desktop-immediate-window-and-direct-start.zh.md);任务判定复用[更新重启检查](2026-08-25-electron-desktop-packaging-and-updates.zh.md)。本记录部分取代[标准 macOS 窗口菜单](../bug-fix/2026-09-16-desktop-window-menus.zh.md)决策:⌘W 不再通过 Electron 的 role 销毁窗口,Dock 激活在没有可见窗口时重新打开隐藏窗口,而不再只在没有任何窗口时才创建。该记录中的菜单声明仍然有效。 + +## 问题 + +关闭 Desktop 窗口会销毁它。macOS 上 Host 继续运行,但 Dock 会重建一个全新页面,丢失当前会话、草稿和滚动位置;Windows 上关闭即退出应用,正在运行的任务被直接切断,没有任何提示。退出本身从不询问,尽管 Host 知道哪些 agent、后台任务和定时提醒会因此停止。 + +## 决策 + +两个平台上关闭主窗口都只隐藏它;页面和 Host 继续运行,下次显示仍是同一个文档。Windows 增加常驻托盘图标(单击打开,右键菜单提供"打开"和"退出"),因为 Windows 用户习惯 × 即退出,需要一个看得见的回路;首次关闭时先通过复用的更新弹窗确认,再隐藏窗口。只有点击“确认”才记录已读;取消时保持窗口可见。关闭窗口不发送系统通知。macOS 沿用 Dock,不提供菜单栏图标。进入工作区前关闭欢迎窗口,Windows 上退出,macOS 上丢弃未使用的主窗口,让 Dock 重建欢迎窗口。 + +所有普通退出入口都通过私有 IPC 通道向 Host 询问两项事实:按更新重启口径判定的运行中任务,以及本次运行中已加载会话里由 `workspace/session-activity` 的 `schedule` family 报告的已挂定时器的提醒。两项都没有时直接退出;否则弹出一个没有父窗口的原生消息框,显示三种固定说明之一,"退出"为默认按钮,Esc 对应"取消"。重复的退出请求并入已打开的弹框,弹框打开期间文案冻结,批准后不再重新查询。Host 未就绪时不可能有任务在跑,直接退出;查询失败或超过两秒截止时间按运行中任务处理,因为多提示一次的代价低于无声中断。安装更新的重启、致命错误恢复、开发版重启命令和操作系统会话结束跳过确认。 + +Windows 托盘位图由矢量图标按七种尺寸分别渲染并提交为 ICO;Windows 上的确认框在任务对话框中显示应用图标,且始终为浅色,因为该系统控件不跟随应用主题。安装程序和卸载程序针对应用仍在运行的文案指向托盘。 + +## 备选方案 + +**保留关闭即退出,只在关闭时加确认。** 每次关闭都要询问,而 Windows 用户只要想收起窗口,后台工作就仍会丢失。隐藏才符合"任务继续运行"的产品要求。 + +**用壳的 HTML 遮罩渲染退出确认框。** 遮罩需要可见的父窗口和正常工作的渲染进程;退出必须在窗口隐藏或页面卡死时也能完成,因此原生对话框才是可靠选择。 + +**在 update-tasks IPC 请求上加一个标志复用。** 退出需要第二项事实和更短的截止时间;独立请求不触碰更新准入锁的语义,同时两者共用一个关联 id 空间。 + +**为托盘缩小一张大位图。** 按尺寸分别栅格化矢量源,才能在 100% 到 400% 缩放下都保持边缘清晰,单次缩小无法保证这一点。 + +## 影响 + +用户可以随意关闭窗口;后台任务和定时提醒继续运行,重新打开时恢复同一页面。退出只在会中断工作时提醒。Windows 在整个运行期间携带托盘图标;窗口隐藏期间完成的用户主动发起的更新下载,把安装确认推迟到窗口再次显示时。本次运行中从未加载的会话里的提醒既不计入,也要等到这些会话打开后才会继续,而 Desktop 默认未开启定时任务,因此定时任务文案只在该功能开启后出现。 + +验证覆盖四种查询结果、查询失败与截止时间、每个退出入口的跳过或确认、带托盘和首次关闭确认的关闭即隐藏路径、推迟的更新提示、Host 侧查询、IPC 关联与截止时间,以及已提交托盘图标的位图集合。Windows 托盘和对话框的表现需要在 Windows 机器上以多种显示缩放人工验收。 diff --git a/.agents/notes/implemented/architecture/2026-09-23-schedule-local-menu.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-23-schedule-local-menu.i18n.yaml new file mode 100644 index 0000000000..5bd54753a0 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-23-schedule-local-menu.i18n.yaml @@ -0,0 +1,22 @@ +# Bilingual-pair consistency record for 2026-09-23-schedule-local-menu.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-23-schedule-local-menu.md +/agent-note-own-the-schedule-detail-menus-inside-the-schedule-client: + en: a9ed8f9cf0bdfd66 + zh: ff11822efe6b48b7 +/agent-note-own-the-schedule-detail-menus-inside-the-schedule-client/problem: + en: 076e6ca799bf2045 + zh: d3f87030015cdf3c +/agent-note-own-the-schedule-detail-menus-inside-the-schedule-client/decision: + en: c35ab9fa2549866d + zh: 01855f87b884dc93 +/agent-note-own-the-schedule-detail-menus-inside-the-schedule-client/alternatives-considered: + en: 3648e55bb76a4381 + zh: 83c98e0789a6df9c +/agent-note-own-the-schedule-detail-menus-inside-the-schedule-client/consequences: + en: f6380c38e35bce37 + zh: 1379ff1763d0eb10 +/agent-note-own-the-schedule-detail-menus-inside-the-schedule-client/testing: + en: f1de601175678a9a + zh: 58fddec29a462b98 diff --git a/.agents/notes/implemented/architecture/2026-09-23-schedule-local-menu.md b/.agents/notes/implemented/architecture/2026-09-23-schedule-local-menu.md new file mode 100644 index 0000000000..fd3266bbc4 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-23-schedule-local-menu.md @@ -0,0 +1,43 @@ +# Agent Note: Own the Schedule detail menus inside the Schedule client + +Status: implemented + +English | [中文](2026-09-23-schedule-local-menu.zh.md) + +## Problem + +The Automation tasks detail needs a menu whose list carries a pinned control: the Time zone row's search field must stay above the scrolling zone rows. The shared `Menu` in `@deepseek-ai/dsh-client-ui-primitives` renders rows, separators, labels, a selection mark, and a keyboard walk, but it has no header slot. The Delivery records tab shows a saved record's message id behind an info glyph, and the reader must be able to read and copy that id. + +Serving either need by extending `ui-primitives` puts one feature's behavior into the package every client plugin consumes. The same branch had already removed unrelated `ui-layout` and `ui-sidebar-right` edits after review asked why a Schedule change touched them, and a shared primitive extended for a single caller still costs every future reader of that primitive. + +## Decision + +`packages/client/ui-schedule` owns its menu. `src/client/TaskMenu.tsx` with `TaskMenu.module.css` holds a schedule-local copy that renders rows, separators, labels, disabled and destructive rows, a trailing `selectedId` mark, the pointer and keyboard walk, portaled placement, the pinned `header` slot, and the `data-menu-field` focus handover. It imports the shared `useAnchoredPosition` and `useDismissOnOutsidePointer` hooks, which are the placement and dismissal behavior any anchored panel needs, and it imports no runtime value from `ui-primitives`. The four detail menus use it. + +The Delivery records tab names and copies a record's message id through an info button. The button's accessible name states the action and the record (`Copy message ID: `), the shared `Tooltip` states the id on hover and on keyboard focus, and activation copies it through the shared `writeClipboard` helper and reports `Copied` in a status region beside the glyph. `Tooltip` therefore keeps its master shape: the mode that held one bubble open under the pointer is gone, and the Delivery records view does not use the `HoverCard` that opens on the pointer alone. + +`packages/client/ui-primitives` returns to master except the clock glyph's stroke. The client bundle purity gate in `packages/client/tsdown.client.ts` is the neighboring rule for the other direction of this boundary: a client plugin may import another plugin's package only as types or as a module-table request, so shared runtime vocabulary travels through an inline-safe layer or a cordis service rather than a package edge. + +## Alternatives considered + +**Add a `header` prop to the shared `Menu`.** This is what the branch first did: an optional slot plus the `data-menu-field` focus handover, with tests in the shared package. It gives the smallest diff and keeps one menu implementation, and it was rejected because the only caller is the Schedule detail: `ui-primitives` would carry API that exists for one feature, and every client plugin's bundle would read a header contract none of them use. + +**Add an `interactive` mode to the shared `Tooltip`.** Shipped first and then removed: a grace period between anchor and bubble, pointer hold, click toggling, and selectable text, with six tests. It lost because the shared tooltip already opens on focus and the shared clipboard helper already performs the copy, so the mode added a second way to hold one bubble open for a single caller. + +**Name and copy the message id through `HoverCard`.** Shipped second and then replaced: the card holds while the pointer rests on it, selects its text, and copies on activation. It lost because `HoverCard` opens on `onPointerEnter` alone, so the already-focusable glyph showed a keyboard reader nothing and offered no copy path. + +**Render the zone search field outside the menu list.** A search input above the trigger, or a separate row in the rule card, needs no primitive change. It was rejected because the field would scroll away from the list it filters or sit in a different surface than the rows it filters. + +**Build the zone picker on the schedule-local `PickerPopover`.** The Date and Time pickers already use that panel, so the zone list could reuse it. It was rejected because `PickerPopover` positions and dismisses a panel but renders no list semantics: the keyboard walk, the row roles, and the selected-row mark would have to be rebuilt inside the Schedule client anyway, which is the copy this note describes with more surface than the menu it replaces. + +## Consequences + +The Schedule client carries a second menu implementation: 346 lines of component, 189 lines of CSS, and 403 lines of tests, in exchange for `ui-primitives` returning to master except the clock glyph's stroke. The copy is trimmed to what the detail uses, and the absent capabilities stay absent: submenus, component-rendered rows, a pinned footer, multiple selection ids, the fill selection mode, dense and compact spacing, mount-time autofocus, a caller-supplied anchor rect, pointer-leave closing, and a side parameter. A later Schedule menu that needs one of them extends the copy or revisits this decision. + +Copying is an activation, not a text selection: the tooltip shows the id but does not accept the pointer, so the desktop gesture that copies the id is a click on the glyph. That is the capability the removed interactive mode had and this shape gives up. Shared behavior stays shared: placement, dismissal, focus handover, the duplication gate's exclusion markers naming both owners, and per-file coverage all apply to the copy. The copied region carries `jscpd:ignore-start` and `jscpd:ignore-end` with the two owners named, following the [cross-package value dependencies note](../../archived/process/2026-08-23-client-cross-package-value-dependencies.md); the schedule-specific header, handover, and Tab semantics sit outside that region. + +The copy places its list with `useAnchoredPosition`, which clamps every edge by the same 12px margin, while the shared menu's top edge used the frame-top clearance helper. A list that must clamp upward against the top of a macOS window can therefore sit about 12px lower than the shared menu did in the same situation; the stylesheet still reserves the clearance for the list's own maximum height, so the common case is unchanged. + +## Testing + +`packages/client/ui-schedule/tests/task-menu.client.spec.tsx` pins the pointer and keyboard walk, the `header` field's Home/End ownership, the `data-menu-field` handover after placement, the selected-row mark, disabled rows, portal placement, outside dismissal, and focus return; the three menu-header tests that lived in `ui-primitives` moved there with the capability. `delivery-history.client.spec.tsx` pins the tooltip that keyboard focus raises, the button's accessible name, the clipboard write, and the copy confirmation that clears. The coverage gate reports 100% per file for `packages/client/ui-schedule/src`, and the duplication gate reports no clones across `packages/client/ui-schedule` and `packages/client/ui-primitives`. diff --git a/.agents/notes/implemented/architecture/2026-09-23-schedule-local-menu.zh.md b/.agents/notes/implemented/architecture/2026-09-23-schedule-local-menu.zh.md new file mode 100644 index 0000000000..924f14f5ad --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-23-schedule-local-menu.zh.md @@ -0,0 +1,43 @@ +# Agent Note: Schedule 详情菜单由 Schedule 客户端自己拥有 + +Status: implemented + +[English](2026-09-23-schedule-local-menu.md) | 中文 + +## Problem + +Automation tasks 详情需要一个列表顶部钉住控件的菜单:Time zone 行的搜索框必须停在滚动时区行之上。`@deepseek-ai/dsh-client-ui-primitives` 里的共享 `Menu` 会渲染行、分隔线、标题行、选中标记和键盘走位,但没有 header 槽。Delivery records 页把一条已保存记录的 message id 放在 info 图标背后,读者要能读到并复制这个 id。 + +用扩展 `ui-primitives` 来满足其中任一需求,都会把单个功能的行为放进每个 client 插件都消费的包里。同一条分支此前已经因为 review 质询“Schedule 的改动为什么碰它们”而撤掉了无关的 `ui-layout` 与 `ui-sidebar-right` 编辑;而一个只为单一调用方扩展的共享原语,对之后每一个读它的人都是成本。 + +## Decision + +`packages/client/ui-schedule` 自己拥有菜单。`src/client/TaskMenu.tsx` 与 `TaskMenu.module.css` 保存一份 schedule 本地副本,渲染行、分隔线、标题行、disabled 与 dangerous 行、`selectedId` 尾随标记、指针与键盘走位、portal 定位、钉住的 `header` 槽,以及 `data-menu-field` 焦点交接。它导入共享的 `useAnchoredPosition` 与 `useDismissOnOutsidePointer` hook——任何锚定面板都需要的定位与关闭行为——不从 `ui-primitives` 导入任何运行时值。详情的四个菜单都改用它。 + +Delivery records 页用一个 info 按钮给出并复制记录的消息 id。该按钮的可访问名称同时说明动作与记录(`Copy message ID: `),共享 `Tooltip` 在悬停与键盘聚焦时给出该 id,激活时通过共享的 `writeClipboard` 复制,并在图标旁用 status 区域报告 `Copied`。因此 `Tooltip` 保持 master 形态:那个让气泡在指针下保持展开的模式已不存在,Delivery records 页也不使用只在指针下打开的 `HoverCard`。 + +`packages/client/ui-primitives` 除时钟图标描边外回到 master。`packages/client/tsdown.client.ts` 的 client bundle purity gate 是这条边界另一方向上的相邻规则:client 插件只能以类型或 module-table request 的形式导入另一个插件的包,因此共享运行时词汇要么走 inline-safe 层,要么走 cordis service,而不是包与包之间的边。 + +## Alternatives considered + +**给共享 `Menu` 加 `header` prop。** 这是分支最初的做法:一个可选槽加 `data-menu-field` 焦点交接,并在共享包里带测试。它的 diff 最小、只保留一份菜单实现;被否决是因为唯一的调用方是 Schedule 详情:`ui-primitives` 会背上只为单个功能存在的 API,而每个 client 插件的 bundle 都要读一份没人使用的 header 契约。 + +**给共享 `Tooltip` 加 `interactive` 模式。** 先落地后撤除:锚点与气泡之间的宽限期、指针停留、点击切换、可选中的文字,外加六个测试。被否决是因为共享 tooltip 本来就支持聚焦展开、共享剪贴板助手本来就负责复制,这个模式只是为单一调用方多出了一种保持气泡展开的方式。 + +**用 `HoverCard` 给出并复制消息 id。** 第二个落地又被替换的版本:指针停在卡片上时保持展开、文字可选中、激活即复制。被否决是因为 `HoverCard` 只在 `onPointerEnter` 打开,于是那个本来就可聚焦的图标对键盘读者什么都不显示,也没有复制入口。 + +**把时区搜索框渲染在菜单列表之外。** 放在触发器上方的输入框,或规则卡里的独立一行,都不需要改原语。被否决是因为该输入框会与它所过滤的列表分离滚动,或落在与它过滤的行不同的界面层上。 + +**用 schedule 本地的 `PickerPopover` 实现时区选择器。** Date 与 Time picker 已经用它。被否决是因为 `PickerPopover` 只负责定位与关闭面板,不渲染列表语义:键盘走位、行 role、选中行标记都要在 Schedule 客户端里重建,那正是本 note 描述的副本,而且比它所替代的菜单要维护更多东西。 + +## Consequences + +Schedule 客户端多出一份菜单实现:346 行组件、189 行 CSS、403 行测试,换来 `ui-primitives` 除时钟图标描边外回到 master。副本按详情实际使用裁剪,缺失的能力保持缺失:submenu、组件渲染行、钉住的 footer、多个 selectedId、fill 选中模式、dense 与 compact 间距、挂载时 autofocus、调用方提供锚点矩形、指针离开即关闭,以及 side 参数。日后某个 Schedule 菜单需要其中一项时,要么扩展副本,要么重新审视这个决定。 + +复制是一次激活,而不是选中文本:tooltip 给出 id 但不接受指针,所以桌面端复制该 id 的手势是点击图标;这正是被撤掉的交互模式所具备、而当前形态放弃的能力。共享行为仍是共享的:定位、关闭、焦点交接、点名两个 owner 的 duplication gate 排除标记,以及 per-file 覆盖率都适用于这份副本。被拷贝的区域带 `jscpd:ignore-start` 与 `jscpd:ignore-end` 并点名两个 owner,遵循 [cross-package value dependencies note](../../archived/process/2026-08-23-client-cross-package-value-dependencies.md);schedule 专有的 header、交接与 Tab 语义不在该区域内。 + +副本用 `useAnchoredPosition` 定位列表,它对四条边都用同一个 12px margin,而共享菜单的顶边用的是 frame-top clearance helper。因此在 macOS 窗口顶部需要向上钳制的列表,可能比共享菜单原先的位置低约 12px;样式表仍为该列表自身的最大高度保留 clearance,常见情形不变。 + +## Testing + +`packages/client/ui-schedule/tests/task-menu.client.spec.tsx` 钉住指针与键盘走位、`header` 输入框对 Home/End 的独占、落位后的 `data-menu-field` 交接、选中行标记、disabled 行、portal 定位、外部关闭与焦点回返;原先位于 `ui-primitives` 的三个菜单 header 测试随该能力一起迁入。`delivery-history.client.spec.tsx` 钉住键盘聚焦展开的工具提示、按钮的可访问名称、剪贴板写入,以及会自行清除的复制确认。覆盖率门禁对 `packages/client/ui-schedule/src` 报告 per-file 100%,duplication 门禁在 `packages/client/ui-schedule` 与 `packages/client/ui-primitives` 上报告 0 克隆。 diff --git a/.agents/notes/implemented/architecture/2026-09-24-bounded-session-log-upload.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-24-bounded-session-log-upload.i18n.yaml new file mode 100644 index 0000000000..64f1ca3e65 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-24-bounded-session-log-upload.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-24-bounded-session-log-upload.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-24-bounded-session-log-upload.md +/agent-note-bounded-deepseek-session-log-upload: + en: d35839d24f5704a7 + zh: 8bc7e460fd3bd936 +/agent-note-bounded-deepseek-session-log-upload/problem: + en: b6b54d7ee8810f7e + zh: b0fdfa6c2c3cc224 +/agent-note-bounded-deepseek-session-log-upload/decision: + en: d2fe09351a82f7d6 + zh: ad0741f63e14a8ad +/agent-note-bounded-deepseek-session-log-upload/alternatives-considered: + en: 88985b4e1f5c7a4f + zh: 32617f7ff75ee825 +/agent-note-bounded-deepseek-session-log-upload/consequences: + en: e19fb6136ffd2250 + zh: 01dacd7a44c3f837 diff --git a/.agents/notes/implemented/architecture/2026-09-24-bounded-session-log-upload.md b/.agents/notes/implemented/architecture/2026-09-24-bounded-session-log-upload.md new file mode 100644 index 0000000000..b980765eed --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-24-bounded-session-log-upload.md @@ -0,0 +1,30 @@ +# Agent Note: Bounded DeepSeek Session-log upload + +Status: implemented + +English | [中文](2026-09-24-bounded-session-log-upload.zh.md) +## Problem + +Without a watermark of the current Session format generation, a request carries the whole canonical log: the first request after upload becomes enabled, the first request after a format migration, and the first request of a fork all do. A long log can exceed the V8 string limit of 2^29 − 24 UTF-16 code units on 64-bit hosts. The adapter's merged `JSON.stringify` then throws `RangeError`, the adapter reports `TRANSPORT`, the default retry policy repeats the same serialization, and no request reaches the 2xx that would advance the watermark, so every model request in that Session fails. Below the limit, one request can still carry hundreds of MiB: on Node v24.17.0 and macOS arm64, a 269 MiB first upload of a 96,341-event Session waited 34 s for its 2xx. + +## Decision + +`session-log-deepseek.Config.maxBytes`, 8 MiB by default, bounds the complete serialized `dsh_session_log` field in UTF-8 bytes. Each request carries the longest contiguous run after the watermark whose field, including the header and numeric envelope fields, fits the limit. Acceptance advances the watermark to that run's `throughSeq`, and later requests continue from there. When the first pending event alone exceeds the limit, the request omits the field, the plugin logs a warning, and the watermark stays before that event until `maxBytes` admits it. An event whose JSON text exceeds the runtime's string limit counts as exceeding every limit, so it blocks upload without failing the request, and the plugin serializes it once per request. + +The DeepSeek adapter treats a merged request body that fails to serialize as an extension failure rather than a transport failure. It sends the base body without any extension field, skips the joint acceptance transaction, and reports the omitted field names through the provider plugin's logger, so contributors resend unaccepted state on a later request. A base body that cannot serialize still fails the request. + +This supersedes complete-suffix delivery and fail-closed serialization in the [request-extension decision](2026-08-21-deepseek-llm-api-request-extensions.md). That note still owns field ownership, cancellation, acceptance, and the remaining fail-closed failures. + +## Alternatives considered + +**Serialize the whole pending run first and bound it only on overflow.** Measuring bytes requires serializing every candidate event either way. In a synthetic benchmark, a 14 KiB step took 14.3 µs whole versus 13.8 µs per event, while a 135 MiB backlog took 182 ms to serialize before any fallback versus 10 ms to fill 8 MiB. The whole-run attempt also still overflows the string limit for the logs that motivated this change. + +**Send an oversized first event alone.** Exceeding the configured limit reintroduces the provider body-size rejections that still fail the model request. Omission keeps every request bounded, and the warning names the blocked event. + +**Omit only the field that fails to serialize.** Acceptance is one joint transaction across fields, so per-field omission would split the registry's acceptance contract. Dropping every extension field on this path only leaves the small `dsh_plugin_packages` inventory out of one request. + +## Consequences + +A backlog drains at up to 8 MiB per accepted request by default. At the end-to-end rate measured for the 269 MiB upload, about 8 MiB/s, an 8 MiB field adds about 1 s to each request while a backlog drains, and a 0.86 GB backlog drains in about 100 requests. In the same 96,341-event Session, the median per-step append is 11 KiB and the largest event is 414 KiB, so ordinary steps stay far below the limit and only an unusual event or a small configured limit reaches the oversized-event path. While a backlog drains, the endpoint receives a `throughSeq` behind the Session's current tip. Preparation failures, acceptance failures, and provider rejections still fail the model request. + +Plugin tests cover the exact byte boundary, UTF-8 counting, backlog draining across accepted requests, the oversized-event warning with its unchanged watermark, an event past the string limit, and the 8 MiB default through plugin configuration. Adapter tests cover the base-body fallback through the provider plugin's logger and through an adapter without a reporter. diff --git a/.agents/notes/implemented/architecture/2026-09-24-bounded-session-log-upload.zh.md b/.agents/notes/implemented/architecture/2026-09-24-bounded-session-log-upload.zh.md new file mode 100644 index 0000000000..13dd90ed0a --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-24-bounded-session-log-upload.zh.md @@ -0,0 +1,30 @@ +# Agent Note: 有上限的 DeepSeek 会话日志上传 + +Status: implemented + +[English](2026-09-24-bounded-session-log-upload.md) | 中文 +## 问题 + +没有当前会话格式代的水位时,请求会携带整份规范日志:开启上传后的第一次请求、格式迁移后的第一次请求,以及 fork 的第一次请求都是如此。长会话日志可能超过 64 位宿主上 V8 的字符串上限,即 2^29 − 24 个 UTF-16 码元。此时适配器合并正文的 `JSON.stringify` 会抛出 `RangeError`,适配器报告 `TRANSPORT`,默认重试策略重复同样的序列化,任何请求都无法拿到推进水位所需的 2xx,于是该会话的每次模型请求都会失败。即使低于上限,单次请求仍可能携带数百 MiB:在 Node v24.17.0 与 macOS arm64 上,一个 96,341 条事件的会话首次上传 269 MiB,等待 34 秒才收到 2xx。 + +## 决策 + +`session-log-deepseek.Config.maxBytes` 默认 8 MiB,按 UTF-8 字节限制完整的序列化 `dsh_session_log` 字段。每次请求携带水位之后字段能放进上限的最长连续事件段,字段大小包括 header 与数值型 envelope 字段。接受操作把水位推进到该段的 `throughSeq`,后续请求从那里继续。第一条待发事件本身就超过上限时,请求省略该字段,插件记录一条告警,水位停在该事件之前,直到 `maxBytes` 能容纳它。JSON 文本超过运行时字符串上限的事件视为超过任何上限,因此它会阻塞上传但不会使请求失败,插件每次请求只序列化它一次。 + +DeepSeek 适配器把合并后请求正文的序列化失败视为扩展失败,而非传输失败。它发送不含任何扩展字段的基础正文,跳过联合接受事务,并通过提供方插件的 logger 报告被省略的字段名,因此贡献方会在之后的请求中重发未接受的状态。基础正文本身无法序列化时,请求仍然失败。 + +本决策取代[请求扩展决策](2026-08-21-deepseek-llm-api-request-extensions.zh.md)中的完整后缀交付与 fail-closed 序列化。该记录仍负责字段所有权、取消、接受以及其余 fail-closed 失败。 + +## 考虑过的替代方案 + +**先序列化整个待发事件段,只在超限时再按上限截取。** 无论哪种方式,量字节都要序列化每个候选事件。合成基准中,14 KiB 的一步整体序列化耗时 14.3 µs,逐条累加耗时 13.8 µs;135 MiB 的积压在回退前整体序列化就要 182 ms,逐条装满 8 MiB 只需 10 ms。对促成本改动的日志,整体尝试仍会超过字符串上限。 + +**单独发送超限的第一条事件。** 超过配置上限会重新引入提供方请求体大小拒绝,而这类拒绝仍会使模型请求失败。省略字段能让每次请求都有上限,告警也会指出被阻塞的事件。 + +**只省略序列化失败的那个字段。** 接受是跨字段的一个联合事务,按字段省略会拆分注册表的接受契约。在这条路径上丢弃全部扩展字段,只会让体积很小的 `dsh_plugin_packages` 清单缺席一次请求。 + +## 后果 + +默认情况下,积压按每次已接受请求最多 8 MiB 补传。按那次 269 MiB 上传实测的端到端速度(约 8 MiB/s),补传期间 8 MiB 的字段让每次请求多约 1 秒,0.86 GB 的积压约 100 次请求补完。在同一个 96,341 条事件的会话中,每步追加量的中位数是 11 KiB,最大单条事件是 414 KiB,因此普通步骤远低于上限,只有异常事件或很小的配置上限才会走到超限事件路径。积压补传期间,端点收到的 `throughSeq` 会落后于会话当前末尾。准备失败、接受失败与提供方拒绝仍会使模型请求失败。 + +插件测试覆盖精确字节边界、UTF-8 计数、跨已接受请求的积压补传、超限事件告警及其不变的水位、超过字符串上限的事件,以及经插件配置生效的 8 MiB 默认值。适配器测试覆盖经提供方插件 logger 报告的基础正文回退,以及没有 reporter 的适配器上的同一回退。 diff --git a/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.i18n.yaml new file mode 100644 index 0000000000..fec9a85467 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.i18n.yaml @@ -0,0 +1,22 @@ +# Bilingual-pair consistency record for 2026-09-24-web-default-schedule-composition.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.md +/agent-note-schedule-in-the-shipped-web-composition: + en: 39229d7ab6ed433b + zh: 54287471d371a11c +/agent-note-schedule-in-the-shipped-web-composition/problem: + en: 2871fd5ed881c007 + zh: d03c78d402d186da +/agent-note-schedule-in-the-shipped-web-composition/decision: + en: bb19ad12b2ab0ffc + zh: 971f33e95474a36c +/agent-note-schedule-in-the-shipped-web-composition/recorded-sessions: + en: 5539a42052f4ddb7 + zh: 98cc190ae63b4549 +/agent-note-schedule-in-the-shipped-web-composition/alternatives-considered: + en: ca032a407c2ee8cb + zh: 748a4fcf2485a3da +/agent-note-schedule-in-the-shipped-web-composition/consequences: + en: 4f23bda8fda37987 + zh: 9f7c4a3538bd2979 diff --git a/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.md b/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.md new file mode 100644 index 0000000000..91f533950a --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.md @@ -0,0 +1,39 @@ +# Agent Note: Schedule in the shipped Web composition + +Status: implemented + +English | [中文](2026-09-24-web-default-schedule-composition.zh.md) + +## Problem + +The Automation tasks page, the Session reminder catalog, and the `schedule_*` tools reached a Web deployment only through `--patch apps/cli/config/examples/schedule/cordis.yml`. `packages/bundle/web-app/cordis.patch.yml` carried the `ui-schedule` client row with `disabled: true`, and the Host rows `time-context` and `schedule` existed in that overlay alone. A person running the shipped `web` profile therefore saw no Automation tasks entry and no reminder tools, while every consumer that wanted them repeated the same three rows: the repository preview image kept its own overlay list, and two Web suites hard-coded the overlay path. + +## Decision + +`packages/bundle/web-app/cordis.patch.yml` inserts `time-context` and `schedule` in its Host row list and leaves `ui-schedule` enabled; `packages/bundle/web-app/package.json` declares both packages, which `verify-cordis-config` requires for a bare row name in a bundle patch. The `web` profile consequently ships the Automation tasks page, the Session-header reminder clock, the idle Session row's clock mark and hover list, the right-Sidebar task tab, and `schedule_create`, `schedule_list`, `schedule_update`, and `schedule_delete` on every live root Agent. + +`apps/cli/config/examples/schedule/cordis.yml` is deleted. `applyEntryPatches` appends an `insert` list without de-duplicating ids, so keeping the overlay would mount `time-context` and `schedule` a second time; the two Web suites and the preview packer that named the overlay compose the shipped profile alone. + +`time-context` ships with Schedule because a reminder request states a wall-clock target. The plugin appends one durable user message per eligible step carrying the sampled instant, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message. The sampling instant is what lets the model turn a request such as "tomorrow at nine" into an offset-bearing `at` value; the [Schedule subsystem](../../../../docs/subsystems/schedule.md) owns that interpretation boundary and the explicit-zone requirement it feeds. + +The Host service, its storage domain, and the client half are unchanged. This decision moves which composition mounts them, and the [Host-owned scheduled messages decision](2026-09-16-host-schedule-storage.md) continues to own task storage, activation, dispatch, and delivery records. + +## Recorded sessions + +A Web scenario that drives a live step now logs one time-context reading per step, so its committed Session fixture and header sidecars were refreshed. A reading's sampled instant, browser zone, and elapsed duration are volatile, and `normalizeWebSessionVolatiles` in `apps/web/tests/scaffold.ts` replaces them with `{{timeContextTimestamp}}`, `{{clientTimeZone}}`, and `{{elapsed}}`. The turn and step numbers and the preceding-event baseline stay readable, so a fixture still shows what the model received. Refresh writes the current writer generation (`session.v4.jsonl`) beside the retained predecessors, which remain committed replay baselines. + +## Alternatives considered + +**Keep the overlay and change nothing.** The shipped surface would keep contradicting the product documentation that describes the Automation tasks entry, and each consumer would keep its own copy of the three rows. The overlay also cannot satisfy the request that the default `dsh web` process exposes the page without a flag. + +**Ship the Schedule rows without `time-context`.** The model would then have no sampling instant of its own, so an unqualified date or time in a reminder request would depend on a separate clock source; the overlay paired the two rows for that reason. + +**Reach for a separate optional bundle.** `OPTIONAL_BUNDLES` exists for bundles a person switches on from the plugin manager, which is the same opt-in shape as the overlay; the decision here is that a default Web surface owns the page and the tools. + +## Consequences + +- Every Web session's request header carries four additional tool schemas, and every eligible step appends one durable user message. A conversation that never creates a reminder pays that token cost. +- The clock reading is model-visible and durable, so it replays, compacts, and appears in exported Session logs like any other user message. +- A deployment that wants the previous behavior disables the `time-context`, `schedule`, and `ui-schedule` rows in its own profile patch layer; the capability itself is untouched. +- The `cordis_inspect_query` `listTools` answer for a full preset table now passes the base composition's 12,500-token inline budget, so the spill policy retains that answer's head and tail with a spill path instead of the complete JSON. +- The repository preview image and both Web suites drop their overlay arguments, so one composition change reaches every surface at once. diff --git a/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.zh.md b/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.zh.md new file mode 100644 index 0000000000..af561fe63e --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.zh.md @@ -0,0 +1,39 @@ +# Agent Note: 默认 Web 组合中的 Schedule + +Status: implemented + +[English](2026-09-24-web-default-schedule-composition.md) | 中文 + +## Problem + +自动化任务页面、Session 提醒目录以及 `schedule_*` 工具此前只能通过 `--patch apps/cli/config/examples/schedule/cordis.yml` 进入某个 Web 部署:`packages/bundle/web-app/cordis.patch.yml` 里的 `ui-schedule` 客户端行带 `disabled: true`,而宿主行 `time-context` 与 `schedule` 只存在于那个 overlay 中。因此运行发布版 `web` profile 的人既看不到自动化任务入口,也拿不到提醒工具;同时每个需要它们的消费者都要重复同样的三行:仓库预览镜像自行维护了一份 overlay 列表,两个 Web 测试套件各自硬编码了 overlay 路径。 + +## Decision + +`packages/bundle/web-app/cordis.patch.yml` 在其宿主行列表中插入 `time-context` 与 `schedule`,并让 `ui-schedule` 保持启用;`packages/bundle/web-app/package.json` 声明这两个包,这是 `verify-cordis-config` 对 bundle patch 中裸包名的要求。因此 `web` profile 会交付自动化任务页面、Session 页头的提醒时钟、空闲 Session 行的时钟标记与悬停列表、右侧栏任务页签,并在每个 live 根 Agent 上注册 `schedule_create`、`schedule_list`、`schedule_update` 与 `schedule_delete`。 + +`apps/cli/config/examples/schedule/cordis.yml` 已删除。`applyEntryPatches` 追加 `insert` 列表时不对 id 去重,保留该 overlay 会把 `time-context` 与 `schedule` 挂载两次;原本引用它的两个 Web 测试套件与预览打包器现在只组合发布版 profile。 + +`time-context` 随 Schedule 一起发布,因为提醒请求本身给出的是墙上时钟目标。该插件在每个符合条件的步骤追加一条持久 user 消息,包含采样瞬时、附加到当前开放请求的浏览器时区,以及自前一条模型可见消息以来的经过时长。正是采样瞬时让模型能把「明天九点」这类请求落成带偏移量的 `at` 值;该解释边界及其要求的显式时区由 [Schedule 子系统](../../../../docs/subsystems/schedule.zh.md)负责。 + +宿主服务、其存储 domain 与客户端半边都没有改动。本决策改变的是由哪个组合挂载它们,任务存储、激活、投递与投递记录仍由[宿主定时消息决策](2026-09-16-host-schedule-storage.zh.md)负责。 + +## Recorded sessions + +驱动 live 步骤的 Web 场景现在每步记录一条 time-context 读数,因此其已提交的 Session 夹具与页头 sidecar 都已重刷。一条读数中的采样瞬时、浏览器时区与经过时长是易变值,`apps/web/tests/scaffold.ts` 的 `normalizeWebSessionVolatiles` 会把它们替换为 `{{timeContextTimestamp}}`、`{{clientTimeZone}}` 和 `{{elapsed}}`。turn 与 step 序号以及"前一条事件"的基线保持可读,因此夹具仍能显示模型收到的内容。重刷会在已保留的上一代旁写入当前 writer 代次(`session.v4.jsonl`),旧代次继续作为已提交的回放基线保留。 + +## Alternatives considered + +**保留 overlay,不做任何改动。** 发布版界面会继续与描述该自动化任务入口的产品文档相矛盾,而每个消费者都要各自保留那三行的副本。overlay 也无法满足「默认 `dsh web` 进程不带 flag 就暴露该页面」这一要求。 + +**只发布 Schedule 两行,不带 `time-context`。** 模型将没有自己的采样瞬时,于是提醒请求中未明确限定时区的日期或时间要依赖另一个时钟来源;overlay 当初正是为此把两行配对。 + +**另建一个可选 bundle。** `OPTIONAL_BUNDLES` 面向的是用户在插件管理器里主动开启的 bundle,与 overlay 是同一种 opt-in 形态;本决策要的是默认 Web 界面自己拥有该页面与这些工具。 + +## Consequences + +- 每个 Web 会话的请求头多出四个工具 schema,且每个符合条件的步骤追加一条持久 user 消息。从不创建提醒的对话也要承担这份 token 成本。 +- 时钟读数对模型可见且持久,因此它与其他 user 消息一样参与回放、压缩,并出现在导出的 Session 日志中。 +- 想要恢复旧行为的部署,可在自己的 profile patch 层禁用 `time-context`、`schedule` 与 `ui-schedule` 三行;能力本身没有改动。 +- 完整预设表的 `cordis_inspect_query` `listTools` 答案现在超过基础组合 12,500 token 的内联预算,因此 spill 策略改为保留该答案的首尾并给出 spill 路径,而不是完整 JSON。 +- 仓库预览镜像与两个 Web 测试套件都不再传 overlay 参数,一处组合改动即同时作用于所有界面。 diff --git a/.agents/notes/implemented/bug-fix/2026-07-20-jsonl-storage-identity.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-07-20-jsonl-storage-identity.i18n.yaml index 84feb26de2..5247ed21c3 100644 --- a/.agents/notes/implemented/bug-fix/2026-07-20-jsonl-storage-identity.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-07-20-jsonl-storage-identity.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-20-jsonl-storage-identity.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-07-20-jsonl-storage-identity.md -2026-07-20-jsonl-storage-identity.md: 5224ebf6bebc42b4b72e14243c1af6c02f366372 -2026-07-20-jsonl-storage-identity.zh.md: 05b7150edb99cdf336b9df90bc8e3cc1df9848a3 +/agent-note-bind-jsonl-session-identity-before-mutation: + en: 1d52db2391f1433e + zh: 3bcb9dca6b77bfdd +/agent-note-bind-jsonl-session-identity-before-mutation/problem: + en: 960d783083269ddd + zh: ef52b53d99b520d1 +/agent-note-bind-jsonl-session-identity-before-mutation/decision: + en: 3fc8ab92d1f0f98b + zh: 855b863c7d90cdd9 +/agent-note-bind-jsonl-session-identity-before-mutation/alternatives-considered: + en: 5269f154c37cb8de + zh: 983f18775457361a +/agent-note-bind-jsonl-session-identity-before-mutation/consequences: + en: 2c88ff974542760f + zh: 489996a16ba6907b diff --git a/.agents/notes/implemented/bug-fix/2026-07-31-fail-loud-releases-the-terminal.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-07-31-fail-loud-releases-the-terminal.i18n.yaml index 438bf04d9c..dbd450eb86 100644 --- a/.agents/notes/implemented/bug-fix/2026-07-31-fail-loud-releases-the-terminal.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-07-31-fail-loud-releases-the-terminal.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-31-fail-loud-releases-the-terminal.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-07-31-fail-loud-releases-the-terminal.md -2026-07-31-fail-loud-releases-the-terminal.md: 9c8aa41e960764c6d9311c49a8757a25b3996b78 -2026-07-31-fail-loud-releases-the-terminal.zh.md: e44d4672dcf768c33d94b801809cf7aa653aa62f +/agent-note-fail-loud-releases-the-terminal-before-exiting: + en: c070ae81b744a18b + zh: 8379e89b11e263c4 +/agent-note-fail-loud-releases-the-terminal-before-exiting/problem: + en: 705893ebb3a11d92 + zh: 7d19929c62213a3c +/agent-note-fail-loud-releases-the-terminal-before-exiting/decision: + en: a28315c307acdf90 + zh: fb7b2df986ffdffc +/agent-note-fail-loud-releases-the-terminal-before-exiting/alternatives-considered: + en: 5ee239978e8f1ece + zh: 55267740c7726c25 +/agent-note-fail-loud-releases-the-terminal-before-exiting/consequences: + en: 19241cdfdb6c4e56 + zh: 24534e8660ae2f96 +/agent-note-fail-loud-releases-the-terminal-before-exiting/testing: + en: 8a7b0c74ec32d5a0 + zh: 5bbb564ecc8a9870 diff --git a/.agents/notes/implemented/bug-fix/2026-08-03-cli-signal-shutdown-escalation.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-03-cli-signal-shutdown-escalation.i18n.yaml index 07c0e1b202..23c1697c7e 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-03-cli-signal-shutdown-escalation.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-08-03-cli-signal-shutdown-escalation.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-03-cli-signal-shutdown-escalation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-03-cli-signal-shutdown-escalation.md -2026-08-03-cli-signal-shutdown-escalation.md: 2f8bdce548318b2172e8e0a5807958e5f8189179 -2026-08-03-cli-signal-shutdown-escalation.zh.md: 8e3b90ff158b896f363165708e34d4a300cf4677 +/agent-note-bounded-escalating-signal-shutdown-for-web-and-headless: + en: d8f8ef8811dfe378 + zh: ca728da97cb35920 +/agent-note-bounded-escalating-signal-shutdown-for-web-and-headless/problem: + en: 1042d3e1c2cb1e45 + zh: d32f05dd83eee04b +/agent-note-bounded-escalating-signal-shutdown-for-web-and-headless/decision: + en: 5738aa92d9185c4f + zh: 1999e41d43063c12 +/agent-note-bounded-escalating-signal-shutdown-for-web-and-headless/alternatives-considered: + en: 53239a7e43d70aa1 + zh: d5ab1cc4c52513e6 +/agent-note-bounded-escalating-signal-shutdown-for-web-and-headless/consequences: + en: 888679c978b87125 + zh: c68d962f516f675e +/agent-note-bounded-escalating-signal-shutdown-for-web-and-headless/testing: + en: e2dd8e925ff94a13 + zh: b9430f38c27982ff diff --git a/.agents/notes/implemented/bug-fix/2026-08-06-bwrap-private-pid-namespace.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-06-bwrap-private-pid-namespace.i18n.yaml index ada86f1ca9..a261460c22 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-06-bwrap-private-pid-namespace.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-08-06-bwrap-private-pid-namespace.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-06-bwrap-private-pid-namespace.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-06-bwrap-private-pid-namespace.md -2026-08-06-bwrap-private-pid-namespace.md: c7c83fd274c5dcd6634bdb78a909f1366e1926ba -2026-08-06-bwrap-private-pid-namespace.zh.md: fa53d4eb66669236d3e4ed82b2a4df3adff6dfc5 +/agent-note-isolate-bwrap-from-the-host-pid-namespace: + en: 56e719d5aa015e57 + zh: 2568d89bb33ab663 +/agent-note-isolate-bwrap-from-the-host-pid-namespace/problem: + en: 2da6f0dd324f054d + zh: 4a414f04e638aa47 +/agent-note-isolate-bwrap-from-the-host-pid-namespace/decision: + en: d1000f28dd8cd2c6 + zh: 9b35f7085ae68b99 +/agent-note-isolate-bwrap-from-the-host-pid-namespace/alternatives-considered: + en: e794f6d8578bffef + zh: 61feee3ed99c615d +/agent-note-isolate-bwrap-from-the-host-pid-namespace/verification: + en: 7f9a12f088ce869f + zh: 8d1ea7519de1605d +/agent-note-isolate-bwrap-from-the-host-pid-namespace/consequences: + en: 4543b72f4d669fdf + zh: 7576f60bac467013 diff --git a/.agents/notes/implemented/bug-fix/2026-08-06-host-backed-web-preferences.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-06-host-backed-web-preferences.i18n.yaml index 67810e388a..82875f587c 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-06-host-backed-web-preferences.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-08-06-host-backed-web-preferences.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-06-host-backed-web-preferences.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-06-host-backed-web-preferences.md -2026-08-06-host-backed-web-preferences.md: 4b8d52887554899f2aee9253e65354e4c0fc7e46 -2026-08-06-host-backed-web-preferences.zh.md: 9c61de71981c9e4950889cf94eba2645b9247aa8 +/agent-note-persist-web-user-preferences-through-host-settings: + en: da28d8677a4d9f9c + zh: a5311ab734f576d3 +/agent-note-persist-web-user-preferences-through-host-settings/problem: + en: 18b583ecb58b9e06 + zh: 55570d758b75852a +/agent-note-persist-web-user-preferences-through-host-settings/decision: + en: 2846c0d0f8615da7 + zh: 511d61ea4ea6efa6 +/agent-note-persist-web-user-preferences-through-host-settings/alternatives-considered: + en: a91ebb47ec1ee356 + zh: d5ce0b7f48195093 +/agent-note-persist-web-user-preferences-through-host-settings/consequences: + en: 7defab72acfd5e78 + zh: 566cbbd3eb3cd9e3 diff --git a/.agents/notes/implemented/bug-fix/2026-08-07-cancel-convergence-wake-latch.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-07-cancel-convergence-wake-latch.i18n.yaml index ca1680270c..8f8930a2f0 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-07-cancel-convergence-wake-latch.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-08-07-cancel-convergence-wake-latch.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-07-cancel-convergence-wake-latch.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-07-cancel-convergence-wake-latch.md -2026-08-07-cancel-convergence-wake-latch.md: a6540a7b46b3e4af4058c7549ff056b92fcc708d -2026-08-07-cancel-convergence-wake-latch.zh.md: 2c4f368feaaca91386cac0a5a833ecd8e9f2e1e1 +/agent-note-latch-wake-ups-that-land-in-the-cancel-convergence-window: + en: 0b877f8208b50162 + zh: dd6b6af7d96a5f86 +/agent-note-latch-wake-ups-that-land-in-the-cancel-convergence-window/problem: + en: 4539f5fa2c7dc7e4 + zh: f7b6cbe04ca0ffc2 +/agent-note-latch-wake-ups-that-land-in-the-cancel-convergence-window/decision: + en: 23d5dbc6b75ca908 + zh: 116ae93f6a48e6ed +/agent-note-latch-wake-ups-that-land-in-the-cancel-convergence-window/alternatives-considered: + en: 6df22ff84b2dc081 + zh: 38d1559935b66fb9 +/agent-note-latch-wake-ups-that-land-in-the-cancel-convergence-window/consequences: + en: 7d72c68239cd7e31 + zh: 19045871dcceb4bf diff --git a/.agents/notes/implemented/bug-fix/2026-08-07-ptc-executor-collapse.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-07-ptc-executor-collapse.i18n.yaml index 528aa1f781..a3575ac176 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-07-ptc-executor-collapse.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-08-07-ptc-executor-collapse.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-07-ptc-executor-collapse.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-07-ptc-executor-collapse.md -2026-08-07-ptc-executor-collapse.md: e034d30ff54673ecef98faf5c632b92c2d39aa2f -2026-08-07-ptc-executor-collapse.zh.md: 03f93a323533b8507043c2fa8653b4c51c5fd56e +/agent-note-ptc-mode-collapses-the-executor-not-just-the-wire: + en: 7958ca7ba1201af2 + zh: bc7f74c91444eed6 +/agent-note-ptc-mode-collapses-the-executor-not-just-the-wire/problem: + en: a6fcd5114ffde259 + zh: 05940375a30756d0 +/agent-note-ptc-mode-collapses-the-executor-not-just-the-wire/decision: + en: 66f55639766a6d02 + zh: a8819b045463a927 +/agent-note-ptc-mode-collapses-the-executor-not-just-the-wire/alternatives-considered: + en: 6119e2aff3b6be5a + zh: e01a6c669a9ec6aa +/agent-note-ptc-mode-collapses-the-executor-not-just-the-wire/alternatives-considered/filter-get-the-registry-view-by-mode: + en: 31b6fed689eea5db + zh: ace070ad616bca62 +/agent-note-ptc-mode-collapses-the-executor-not-just-the-wire/alternatives-considered/filter-at-the-agent-loop-entry: + en: 9dbdb9939baccd49 + zh: 11437030cd211000 +/agent-note-ptc-mode-collapses-the-executor-not-just-the-wire/alternatives-considered/reject-via-a-shipped-guard: + en: 9011947651f58129 + zh: 1d4a0c622680f13f +/agent-note-ptc-mode-collapses-the-executor-not-just-the-wire/alternatives-considered/keep-schema-omission-only-status-quo: + en: 0d4759646b19917a + zh: 1a1bef7617c52f9c +/agent-note-ptc-mode-collapses-the-executor-not-just-the-wire/consequences: + en: 9120e68ba25bd30a + zh: 6ec4bea5df8668a1 diff --git a/.agents/notes/implemented/bug-fix/2026-08-10-child-agents-join-their-parent-preset.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-10-child-agents-join-their-parent-preset.i18n.yaml index 027bf3babb..e86b334e45 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-10-child-agents-join-their-parent-preset.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-08-10-child-agents-join-their-parent-preset.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-10-child-agents-join-their-parent-preset.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-10-child-agents-join-their-parent-preset.md -2026-08-10-child-agents-join-their-parent-preset.md: 7de247a7a3f75f467ebf5c8387eb8fb8e2f7e009 -2026-08-10-child-agents-join-their-parent-preset.zh.md: c9d392cd75ee9c06005aa53f4f68a8153fc7633b +/agent-note-child-agents-join-their-parent-s-preset-composition: + en: ad623e2fef93c033 + zh: a37abf059f39aefa +/agent-note-child-agents-join-their-parent-s-preset-composition/problem: + en: 0b8d70c073523bc1 + zh: 6bba76a467508149 +/agent-note-child-agents-join-their-parent-s-preset-composition/decision: + en: 13a3452527f35bc6 + zh: 6c319f554184e578 +/agent-note-child-agents-join-their-parent-s-preset-composition/alternatives-considered: + en: 88a48e6bba3d30e2 + zh: 842d835a7a9db434 +/agent-note-child-agents-join-their-parent-s-preset-composition/testing: + en: 458a2aa1ae046253 + zh: 59fad52e881989ed +/agent-note-child-agents-join-their-parent-s-preset-composition/consequences: + en: 09fd94b5ceaa95e6 + zh: bf8e4e22f5b70b45 diff --git a/.agents/notes/implemented/bug-fix/2026-08-17-durable-web-queue-recovery.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-17-durable-web-queue-recovery.i18n.yaml index 5c76962fef..63f61fbc54 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-17-durable-web-queue-recovery.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-08-17-durable-web-queue-recovery.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-17-durable-web-queue-recovery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-17-durable-web-queue-recovery.md -2026-08-17-durable-web-queue-recovery.md: 0f18cd7a2b9491d6a8bdfa960409d97a5338f95d -2026-08-17-durable-web-queue-recovery.zh.md: 476c1b2fe88156ba8c34e281ff1d1e5663c7913c +/agent-note-recover-the-web-queue-from-durable-inbox-state: + en: df261933e13adb0a + zh: 369772acd6fe0e48 +/agent-note-recover-the-web-queue-from-durable-inbox-state/problem: + en: 79fe907a6201ed27 + zh: 55d0de6b6518f946 +/agent-note-recover-the-web-queue-from-durable-inbox-state/decision: + en: 2e64d021a2009eec + zh: b3f7d5ba2a6f6322 +/agent-note-recover-the-web-queue-from-durable-inbox-state/verification: + en: bab880ec7de69673 + zh: 769f2641856fde60 +/agent-note-recover-the-web-queue-from-durable-inbox-state/alternatives-considered: + en: df29962ab5d779ee + zh: 2593f0973b725d54 +/agent-note-recover-the-web-queue-from-durable-inbox-state/consequences: + en: ffa16214aa1f0efd + zh: 7915524221acac0c diff --git a/.agents/notes/implemented/bug-fix/2026-08-17-subagent-message-settlement-ordering.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-17-subagent-message-settlement-ordering.i18n.yaml index 3ef4fd1d6c..fcd7dd96b2 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-17-subagent-message-settlement-ordering.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-08-17-subagent-message-settlement-ordering.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-17-subagent-message-settlement-ordering.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-17-subagent-message-settlement-ordering.md -2026-08-17-subagent-message-settlement-ordering.md: b383dc290949a3a22ed48e1e639b145e39dbb211 -2026-08-17-subagent-message-settlement-ordering.zh.md: 330c19b20b966d9f719fb61ee1bf5272e0cc8287 +/agent-note-child-agent-messages-precede-their-settlement-notices: + en: b46c628c107fbdfe + zh: 829b71dae5e73e0f +/agent-note-child-agent-messages-precede-their-settlement-notices/problem: + en: 82e6c4d5db64a818 + zh: 3610573f1521409e +/agent-note-child-agent-messages-precede-their-settlement-notices/decision: + en: 94a44265545ff53e + zh: 06db7c1bacb6b120 +/agent-note-child-agent-messages-precede-their-settlement-notices/decision/ordering-across-parent-states: + en: 2bceedd85283e6ed + zh: 6c11a3519fe9b941 +/agent-note-child-agent-messages-precede-their-settlement-notices/decision/verification: + en: b2d6b562739ea61c + zh: 33f56b3220b00953 +/agent-note-child-agent-messages-precede-their-settlement-notices/alternatives-considered: + en: a81f4efd6c32125e + zh: d38898c6b3352ad8 +/agent-note-child-agent-messages-precede-their-settlement-notices/consequences: + en: 3b8532d48efb656a + zh: 971bced6f6bed59d diff --git a/.agents/notes/implemented/bug-fix/2026-08-24-alpha-routed-image-quality-ladders.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-24-alpha-routed-image-quality-ladders.i18n.yaml index e2e60901af..d82479170d 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-24-alpha-routed-image-quality-ladders.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-08-24-alpha-routed-image-quality-ladders.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-24-alpha-routed-image-quality-ladders.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-24-alpha-routed-image-quality-ladders.md -2026-08-24-alpha-routed-image-quality-ladders.md: cdf5e7bd908782781e66a4f6494428f0f174e258 -2026-08-24-alpha-routed-image-quality-ladders.zh.md: fbe8215b0ca1c606cd66d60fe1109d2f9aa1cbad +/agent-note-alpha-routed-image-quality-ladders-replace-colour-count-codec-routing: + en: b2c958d45911a787 + zh: b826c61174b3640f +/agent-note-alpha-routed-image-quality-ladders-replace-colour-count-codec-routing/problem: + en: bcb73f4711d40348 + zh: 6e26853ea4728e4d +/agent-note-alpha-routed-image-quality-ladders-replace-colour-count-codec-routing/decision: + en: aabf20046a7a15e9 + zh: dba0c5261a3af1e5 +/agent-note-alpha-routed-image-quality-ladders-replace-colour-count-codec-routing/alternatives-considered: + en: 95a42e3e2313790b + zh: 116043c295d7aa12 +/agent-note-alpha-routed-image-quality-ladders-replace-colour-count-codec-routing/consequences: + en: 3ce6acd960671b52 + zh: 1ec81d76130d338d diff --git a/.agents/notes/implemented/bug-fix/2026-08-31-win32-picker-path-string-read.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-31-win32-picker-path-string-read.i18n.yaml index 989c66f145..3ffc1ac876 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-31-win32-picker-path-string-read.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-08-31-win32-picker-path-string-read.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-31-win32-picker-path-string-read.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-31-win32-picker-path-string-read.md -2026-08-31-win32-picker-path-string-read.md: 63b2a2ea5ee88b5fa3ac79aca98350f58067fd1e -2026-08-31-win32-picker-path-string-read.zh.md: 8afc6610a0cf1c7c8649f9e1c62c26b3d89f5a03 +/agent-note-read-the-win32-picker-path-without-a-fixed-size-unmanaged-view: + en: abd03a3bff03600e + zh: 8a4a21ecc7cae78b +/agent-note-read-the-win32-picker-path-without-a-fixed-size-unmanaged-view/problem: + en: 1835aa6f42229a1f + zh: 928cb408e879fc41 +/agent-note-read-the-win32-picker-path-without-a-fixed-size-unmanaged-view/decision: + en: 831ea941c84193ef + zh: b7a1842d9843bf0d +/agent-note-read-the-win32-picker-path-without-a-fixed-size-unmanaged-view/alternatives-considered: + en: 8c0a9a1620504f50 + zh: 7f439ecb6ca5a618 +/agent-note-read-the-win32-picker-path-without-a-fixed-size-unmanaged-view/consequences: + en: 616bc4293a0b1856 + zh: ed8cf574d7a126cc diff --git a/.agents/notes/implemented/bug-fix/2026-09-03-normalized-unread-fs-tool-diagnostic.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-03-normalized-unread-fs-tool-diagnostic.i18n.yaml index 573390ed70..40c0a993a5 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-03-normalized-unread-fs-tool-diagnostic.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-03-normalized-unread-fs-tool-diagnostic.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-03-normalized-unread-fs-tool-diagnostic.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-03-normalized-unread-fs-tool-diagnostic.md -2026-09-03-normalized-unread-fs-tool-diagnostic.md: 01287a080641e1272f9759532ae7333866c6352e -2026-09-03-normalized-unread-fs-tool-diagnostic.zh.md: 5aba96ce761376e8609267f251433fee11c9f114 +/agent-note-normalized-unread-filesystem-tool-diagnostic: + en: 103e786a598d2ee3 + zh: 13d637140685f63a +/agent-note-normalized-unread-filesystem-tool-diagnostic/problem: + en: 89cfcff2f9895623 + zh: dd1cd21d431e5161 +/agent-note-normalized-unread-filesystem-tool-diagnostic/decision: + en: 0c59c5193131ca44 + zh: da48f204aef62c99 +/agent-note-normalized-unread-filesystem-tool-diagnostic/alternatives-considered: + en: dbb9cbdafd0f2764 + zh: ed8bef943f12b21d +/agent-note-normalized-unread-filesystem-tool-diagnostic/consequences: + en: 20abbdbfa3aa4edc + zh: d0555aac68cb7a1f diff --git a/.agents/notes/implemented/bug-fix/2026-09-03-root-marker-metadata-failures.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-03-root-marker-metadata-failures.i18n.yaml index 3c4cb67d7d..9789836b6d 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-03-root-marker-metadata-failures.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-03-root-marker-metadata-failures.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-03-root-marker-metadata-failures.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-03-root-marker-metadata-failures.md -2026-09-03-root-marker-metadata-failures.md: e31ef646d7190a1239684f7b66a118deb9ae1087 -2026-09-03-root-marker-metadata-failures.zh.md: 4b62f4e01ba56074a10dbcb3ae37c4478fe82379 +/agent-note-root-marker-metadata-failures: + en: c351be96177b2ea5 + zh: a094d77aaffd1fbe +/agent-note-root-marker-metadata-failures/problem: + en: 3d88594600ede55b + zh: fd9e36f5b72d8aee +/agent-note-root-marker-metadata-failures/decision: + en: 8131fbf06980774f + zh: 21a3c48edbe9ab99 +/agent-note-root-marker-metadata-failures/alternatives-considered: + en: 2070e244fd8ffc91 + zh: 31324cd0d5ace0a9 +/agent-note-root-marker-metadata-failures/consequences: + en: a459fc1a7a8353a3 + zh: 144b373b0988b633 +/agent-note-root-marker-metadata-failures/verification: + en: 4c912e5effdaedb7 + zh: 1b28ba3dea9170dd diff --git a/.agents/notes/implemented/bug-fix/2026-09-03-user-owned-goal-pause-activation.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-03-user-owned-goal-pause-activation.i18n.yaml index f4d9692b37..c75a62877c 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-03-user-owned-goal-pause-activation.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-03-user-owned-goal-pause-activation.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-03-user-owned-goal-pause-activation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-03-user-owned-goal-pause-activation.md -2026-09-03-user-owned-goal-pause-activation.md: d58566938ef87ca2f25fd94d726dc28209f61b2b -2026-09-03-user-owned-goal-pause-activation.zh.md: 675d61009f0a7d0f98c8f6d7568466d6651f2a42 +/agent-note-user-owned-goal-pause-exposes-live-activation: + en: 07749eb6ac180964 + zh: b9c1165739fc45bf +/agent-note-user-owned-goal-pause-exposes-live-activation/problem: + en: 9f044f22e6782773 + zh: 6c17c53aa75280fd +/agent-note-user-owned-goal-pause-exposes-live-activation/decision: + en: 2cc4ab097350a88f + zh: db10825a6285f3c5 +/agent-note-user-owned-goal-pause-exposes-live-activation/alternatives-considered: + en: 640afdb17164b06b + zh: 92d33c139c40b2a1 +/agent-note-user-owned-goal-pause-exposes-live-activation/consequences: + en: d73e412f853612ee + zh: 96630d28e3c431e1 +/agent-note-user-owned-goal-pause-exposes-live-activation/testing: + en: 9d103a90036f5d06 + zh: df5440c8a4640e93 diff --git a/.agents/notes/implemented/bug-fix/2026-09-04-busy-send-button-follows-enter-setting.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-04-busy-send-button-follows-enter-setting.i18n.yaml index 0dfc11edca..4248c352c7 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-04-busy-send-button-follows-enter-setting.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-04-busy-send-button-follows-enter-setting.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-04-busy-send-button-follows-enter-setting.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-04-busy-send-button-follows-enter-setting.md -2026-09-04-busy-send-button-follows-enter-setting.md: 2db0848e3ce3b7a1b6b07ff6d6d23c06b23be5ef -2026-09-04-busy-send-button-follows-enter-setting.zh.md: 7062f60320c4bc56f15f57388e79df9ce0e45c2f +/agent-note-the-busy-send-button-follows-the-enter-setting: + en: d0e9f804958ee8ce + zh: e5cd102fbdd12ff1 +/agent-note-the-busy-send-button-follows-the-enter-setting/problem: + en: c378dfa9efcc0758 + zh: 785c3b9ee99c66a4 +/agent-note-the-busy-send-button-follows-the-enter-setting/decision: + en: 101e21100f8afd7d + zh: 76979af8aee15976 +/agent-note-the-busy-send-button-follows-the-enter-setting/verification: + en: eb886930b09445bd + zh: 1e671f8f81868490 +/agent-note-the-busy-send-button-follows-the-enter-setting/alternatives-considered: + en: d47aa278a2103890 + zh: 313f75c7fb8ccd5c +/agent-note-the-busy-send-button-follows-the-enter-setting/consequences: + en: a067e427615a682a + zh: d72074056e1def4a diff --git a/.agents/notes/implemented/bug-fix/2026-09-05-continuous-client-recovery.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-05-continuous-client-recovery.i18n.yaml index a2bba51f16..f08907aa62 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-05-continuous-client-recovery.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-05-continuous-client-recovery.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-continuous-client-recovery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-05-continuous-client-recovery.md -2026-09-05-continuous-client-recovery.md: 2eacaca4f8d4b76ab8d82bb10bb8cfa4c80cbd65 -2026-09-05-continuous-client-recovery.zh.md: 96908b1217ca1caa17514e16522080fa342e6813 +/agent-note-continuous-client-connection-recovery: + en: f0fee6b344250d4c + zh: 713ea72ca8d6565a +/agent-note-continuous-client-connection-recovery/problem: + en: 70259bdedbf6b449 + zh: b0a3014c27483a09 +/agent-note-continuous-client-connection-recovery/decision: + en: db9ac3c08a3eaf0b + zh: 68c9ce30d8d5c7e2 +/agent-note-continuous-client-connection-recovery/alternatives-considered: + en: 2e94feca66d912af + zh: 8fc4e81b797d4553 +/agent-note-continuous-client-connection-recovery/consequences: + en: cd99c771043a23d5 + zh: 8559757fa8098fbe +/agent-note-continuous-client-connection-recovery/testing: + en: 39fdcfb5c6b52a96 + zh: 276de310ed1bbc39 diff --git a/.agents/notes/implemented/bug-fix/2026-09-05-nested-terminal-cards.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-05-nested-terminal-cards.i18n.yaml index d62438d1f3..e0fdd0b674 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-05-nested-terminal-cards.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-05-nested-terminal-cards.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-nested-terminal-cards.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-05-nested-terminal-cards.md -2026-09-05-nested-terminal-cards.md: c5946a332f2879588cb6ee334404fdaa92a8cb28 -2026-09-05-nested-terminal-cards.zh.md: 74056014ce5b9ac38574c5551420a4e25808b9b4 +/agent-note-nested-terminal-cards: + en: acc1dadeee5e1aeb + zh: a589c28cf1aff307 +/agent-note-nested-terminal-cards/problem: + en: 1bd9adbd90b66871 + zh: 0a87672dffc07bae +/agent-note-nested-terminal-cards/decision: + en: 075b10a41974411e + zh: cc3341afff14f61b +/agent-note-nested-terminal-cards/alternatives-considered: + en: c585eb14efb10514 + zh: c5a1cc87fc4edacc +/agent-note-nested-terminal-cards/consequences: + en: a7abcb5b95a020cc + zh: 27fe3216944de8c3 +/agent-note-nested-terminal-cards/verification: + en: 0133972e958fccce + zh: 52d4d3e29b7346e0 diff --git a/.agents/notes/implemented/bug-fix/2026-09-05-patch-plugin-file-urls.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-05-patch-plugin-file-urls.i18n.yaml index 2653e7d928..3bcf021adf 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-05-patch-plugin-file-urls.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-05-patch-plugin-file-urls.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-patch-plugin-file-urls.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-05-patch-plugin-file-urls.md -2026-09-05-patch-plugin-file-urls.md: bad63355ce74b520b5e49b94deeefb2d648b71f4 -2026-09-05-patch-plugin-file-urls.zh.md: 775a576324dd2856f490cf3ce3ba907965737fc2 +/agent-note-file-urls-for-inserted-patch-plugins: + en: 0da1360de4441566 + zh: aa617df23150096d +/agent-note-file-urls-for-inserted-patch-plugins/problem: + en: 68de71db96c5e4b5 + zh: c88db125cddb54a4 +/agent-note-file-urls-for-inserted-patch-plugins/decision: + en: 09bb824857b8fb60 + zh: 859da30ff296688c +/agent-note-file-urls-for-inserted-patch-plugins/alternatives-considered: + en: e53a86bc1c71a6ff + zh: 514b48c8734fca17 +/agent-note-file-urls-for-inserted-patch-plugins/consequences: + en: 9b9628919e52c617 + zh: 195935e5d905d81d diff --git a/.agents/notes/implemented/bug-fix/2026-09-05-pi-ai-upgrade-compatibility.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-05-pi-ai-upgrade-compatibility.i18n.yaml index e188205736..88960b1f51 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-05-pi-ai-upgrade-compatibility.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-05-pi-ai-upgrade-compatibility.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-pi-ai-upgrade-compatibility.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-05-pi-ai-upgrade-compatibility.md -2026-09-05-pi-ai-upgrade-compatibility.md: e28d911facae33fcf278a6824376f889e3416d77 -2026-09-05-pi-ai-upgrade-compatibility.zh.md: 408669ddc963a505254529acaab4c19e9774c6b1 +/agent-note-pi-ai-upgrade-compatibility: + en: faa0207498bd36c7 + zh: 2c6c209849dcce32 +/agent-note-pi-ai-upgrade-compatibility/problem: + en: 0a106a9d74115ce5 + zh: a65945e32455944e +/agent-note-pi-ai-upgrade-compatibility/decision: + en: 978b93bba58cfaf9 + zh: 847360ba75d67abc +/agent-note-pi-ai-upgrade-compatibility/alternatives-considered: + en: bcfd595bb17c3cd6 + zh: b7d4346e9c50f95d +/agent-note-pi-ai-upgrade-compatibility/consequences: + en: 0b634c9d7567aa57 + zh: c8ae82694e5fae12 diff --git a/.agents/notes/implemented/bug-fix/2026-09-05-session-reference-model-budget.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-05-session-reference-model-budget.i18n.yaml index 623fcdf1b1..57f613df55 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-05-session-reference-model-budget.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-05-session-reference-model-budget.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-session-reference-model-budget.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-05-session-reference-model-budget.md -2026-09-05-session-reference-model-budget.md: 0654f2b89187727668fddb97ab6e982bacd82dc1 -2026-09-05-session-reference-model-budget.zh.md: 84f4fee76c7fb54f3ec37f0ae3417cc56d772af7 +/agent-note-model-relative-session-reference-budgets: + en: 6d4d5e9c678c93cb + zh: 7023bca0480a27df +/agent-note-model-relative-session-reference-budgets/problem: + en: 2bc7bc4083a96c5d + zh: d0d290871def4abf +/agent-note-model-relative-session-reference-budgets/decision: + en: e686c4ed659fc44c + zh: 41484c0431a53177 +/agent-note-model-relative-session-reference-budgets/alternatives-considered: + en: 77148c41d109895a + zh: dba534347f0e0877 +/agent-note-model-relative-session-reference-budgets/consequences: + en: 6ee6a4b3229ff378 + zh: 9e30e71ac15da8c4 diff --git a/.agents/notes/implemented/bug-fix/2026-09-05-session-reference-spill-reuse.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-05-session-reference-spill-reuse.i18n.yaml index 577e94fdc8..05f653cf57 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-05-session-reference-spill-reuse.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-05-session-reference-spill-reuse.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-session-reference-spill-reuse.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-05-session-reference-spill-reuse.md -2026-09-05-session-reference-spill-reuse.md: 2a24e3adf28c70df8feb726700376df6f06dee87 -2026-09-05-session-reference-spill-reuse.zh.md: 346ed1a39ee65a560cf9e74e519ae45c2ce133e1 +/agent-note-reuse-spill-storage-for-truncated-session-references: + en: 9691f4ba51c41f8b + zh: 5c1719f1ef901639 +/agent-note-reuse-spill-storage-for-truncated-session-references/problem: + en: 50a1ef10604acb5f + zh: 128abfd3e43740dc +/agent-note-reuse-spill-storage-for-truncated-session-references/decision: + en: 058598a9e6c65fcf + zh: 7760170bbc53396d +/agent-note-reuse-spill-storage-for-truncated-session-references/alternatives-considered: + en: fccf1c25876b92a0 + zh: 7d5c7c3d240132c3 +/agent-note-reuse-spill-storage-for-truncated-session-references/consequences: + en: 2bff957549afe59b + zh: 30c6be54168fe183 +/agent-note-reuse-spill-storage-for-truncated-session-references/verification: + en: e015a599fc71a65f + zh: 0812b5b9a64a8673 +/agent-note-reuse-spill-storage-for-truncated-session-references/related-decisions: + en: 7a53914026e82df7 + zh: 3c802bbf63117485 diff --git a/.agents/notes/implemented/bug-fix/2026-09-06-environment-prompt-suffix.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-06-environment-prompt-suffix.i18n.yaml index 69715a797c..1e5d9065c2 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-06-environment-prompt-suffix.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-06-environment-prompt-suffix.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-environment-prompt-suffix.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-06-environment-prompt-suffix.md -2026-09-06-environment-prompt-suffix.md: 3438df0fec7b3296084c94b7db68d2800c6d6c98 -2026-09-06-environment-prompt-suffix.zh.md: 102d1196639ac7d7a754a24fc5a93bc93c1d05ba +/agent-note-environment-facts-follow-reusable-prompt-instructions: + en: 8677e5d20233627f + zh: 684772490164fbdf +/agent-note-environment-facts-follow-reusable-prompt-instructions/problem: + en: 7b20207cd4dc1583 + zh: ca5014aa437a5239 +/agent-note-environment-facts-follow-reusable-prompt-instructions/decision: + en: 0f28a61d659c0f4d + zh: d2ef431d15a54d57 +/agent-note-environment-facts-follow-reusable-prompt-instructions/alternatives-considered: + en: 9fb4ff8a8786ce2d + zh: 25820720365b489f +/agent-note-environment-facts-follow-reusable-prompt-instructions/consequences: + en: 212b29160c254854 + zh: e6a1ea253e8f7780 +/agent-note-environment-facts-follow-reusable-prompt-instructions/testing: + en: d5132186efc6afcd + zh: e5cc036c7c8ed68e diff --git a/.agents/notes/implemented/bug-fix/2026-09-06-windows-python-console-spawn-wait.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-06-windows-python-console-spawn-wait.i18n.yaml index 65ea0bac5e..be90b83299 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-06-windows-python-console-spawn-wait.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-06-windows-python-console-spawn-wait.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-windows-python-console-spawn-wait.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-06-windows-python-console-spawn-wait.md -2026-09-06-windows-python-console-spawn-wait.md: 036062bdf459e4cbb69a6c31d3160c78ec1fad4c -2026-09-06-windows-python-console-spawn-wait.zh.md: d0870be84066b885e1622438a9fbc277f56a6bcf +/agent-note-wait-for-the-windows-python-console-runtime: + en: 97ffbd17152279cc + zh: 9a223670f273471b +/agent-note-wait-for-the-windows-python-console-runtime/problem: + en: 26ea75714d6fbbea + zh: 49441436e362a868 +/agent-note-wait-for-the-windows-python-console-runtime/decision: + en: 6ef15038eb5e0786 + zh: 92e319fbb8133d52 +/agent-note-wait-for-the-windows-python-console-runtime/alternatives-considered: + en: 2cc100a4b8724d40 + zh: 6ba47c76f304a460 +/agent-note-wait-for-the-windows-python-console-runtime/consequences: + en: ec5c2a7082012ed5 + zh: 32027ea20bd32acf diff --git a/.agents/notes/implemented/bug-fix/2026-09-07-pi-ai-settings-catalog-recovery.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-07-pi-ai-settings-catalog-recovery.i18n.yaml index 43f6f3b14c..130a3812c0 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-07-pi-ai-settings-catalog-recovery.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-07-pi-ai-settings-catalog-recovery.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-pi-ai-settings-catalog-recovery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-07-pi-ai-settings-catalog-recovery.md -2026-09-07-pi-ai-settings-catalog-recovery.md: 21fe532a491775ff875f6b9bcb000d917a95e13c -2026-09-07-pi-ai-settings-catalog-recovery.zh.md: 80bd0758e13b767671f4cec52ee3832c9250651f +/agent-note-repairable-pi-ai-settings-after-catalog-changes: + en: 69bf6edd0515636c + zh: cb5039a98dc8b736 +/agent-note-repairable-pi-ai-settings-after-catalog-changes/problem: + en: acc6a5afd829fde0 + zh: a2173b59b670efe2 +/agent-note-repairable-pi-ai-settings-after-catalog-changes/decision: + en: 37034d76d7542f46 + zh: a6423ba488fe272c +/agent-note-repairable-pi-ai-settings-after-catalog-changes/alternatives-considered: + en: 1dcabe193953fa1b + zh: 02263349cdbdc843 +/agent-note-repairable-pi-ai-settings-after-catalog-changes/consequences: + en: d2f89ce8cec55c6e + zh: 20fab7854366ae05 +/agent-note-repairable-pi-ai-settings-after-catalog-changes/testing: + en: 30c8172b88231251 + zh: 54aee9d1dffa8566 diff --git a/.agents/notes/implemented/bug-fix/2026-09-07-typert-package-local-forwarding-imports.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-07-typert-package-local-forwarding-imports.i18n.yaml index 71b7d891d1..53a10eeede 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-07-typert-package-local-forwarding-imports.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-07-typert-package-local-forwarding-imports.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-typert-package-local-forwarding-imports.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-07-typert-package-local-forwarding-imports.md -2026-09-07-typert-package-local-forwarding-imports.md: 33e4334edef732b9c498ad2397151bd9c2c16f1f -2026-09-07-typert-package-local-forwarding-imports.zh.md: ea4babdb4b58981fb16f499c7986279fa18dbc58 +/agent-note-follow-package-local-forwarding-modules-in-typert-references: + en: ebacf2fc1c764589 + zh: c14b1752a01b2775 +/agent-note-follow-package-local-forwarding-modules-in-typert-references/problem: + en: 0ed0703cdd876132 + zh: ab759d1a2137bdd8 +/agent-note-follow-package-local-forwarding-modules-in-typert-references/decision: + en: e828847b069ef3f8 + zh: 95e9425c02dd8215 +/agent-note-follow-package-local-forwarding-modules-in-typert-references/alternatives-considered: + en: 49a0984c31c2b993 + zh: fb6d093474130a75 +/agent-note-follow-package-local-forwarding-modules-in-typert-references/consequences: + en: 7e196e1cffcb31e1 + zh: 7d096507578c1731 diff --git a/.agents/notes/implemented/bug-fix/2026-09-07-win32-picker-foreground-alt-key.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-07-win32-picker-foreground-alt-key.i18n.yaml index 0a54d83ab9..6088c5898e 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-07-win32-picker-foreground-alt-key.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-07-win32-picker-foreground-alt-key.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-win32-picker-foreground-alt-key.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-07-win32-picker-foreground-alt-key.md -2026-09-07-win32-picker-foreground-alt-key.md: cd1bae56845c74bf8fb0b3c0e6b8e6bab8032daf -2026-09-07-win32-picker-foreground-alt-key.zh.md: 8cbacaee97892b2ba6feb3d0250212fa9d393376 +/agent-note-foreground-activation-for-the-win32-picker-via-a-synthesized-alt-press: + en: bbd08341a635d6a8 + zh: 94d4ea2412237630 +/agent-note-foreground-activation-for-the-win32-picker-via-a-synthesized-alt-press/problem: + en: b21a34182868057e + zh: 54cb143a2a11479b +/agent-note-foreground-activation-for-the-win32-picker-via-a-synthesized-alt-press/decision: + en: d4cff7cc9b5c9379 + zh: a8f3e238799a18ce +/agent-note-foreground-activation-for-the-win32-picker-via-a-synthesized-alt-press/alternatives-considered: + en: dd3491b3b760f330 + zh: 81ca7b6603379713 +/agent-note-foreground-activation-for-the-win32-picker-via-a-synthesized-alt-press/consequences: + en: 6e7c7c46cc48a95d + zh: bbed46fb61e53700 diff --git a/.agents/notes/implemented/bug-fix/2026-09-10-built-bundle-css-exemption.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-10-built-bundle-css-exemption.i18n.yaml index 4f985d74f7..7fc8e02b71 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-10-built-bundle-css-exemption.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-10-built-bundle-css-exemption.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-built-bundle-css-exemption.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-10-built-bundle-css-exemption.md -2026-09-10-built-bundle-css-exemption.md: e5a55689696f885b8ea9411a5b3a7598295fff35 -2026-09-10-built-bundle-css-exemption.zh.md: 1c1aab35df72497946b02bf2a7f67a2271c804e5 +/agent-note-built-bundle-exemption-for-a-failing-stylesheet: + en: 7eea80c07cea261d + zh: 936523023c0b527d +/agent-note-built-bundle-exemption-for-a-failing-stylesheet/problem: + en: ca5c97dd0ad51b66 + zh: 8491ee495b0c625e +/agent-note-built-bundle-exemption-for-a-failing-stylesheet/decision: + en: cd272aa1bfd34a14 + zh: d184be63053f73b8 +/agent-note-built-bundle-exemption-for-a-failing-stylesheet/alternatives-considered: + en: 7f0eb995b7f00d73 + zh: aaf7b18f7bb2c20d +/agent-note-built-bundle-exemption-for-a-failing-stylesheet/consequences: + en: 767857f0bbd93ca8 + zh: f49bf34e304a7dee diff --git a/.agents/notes/implemented/bug-fix/2026-09-10-deepseek-image-token-calculator-v41.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-10-deepseek-image-token-calculator-v41.i18n.yaml index 2ff4007876..f98968b567 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-10-deepseek-image-token-calculator-v41.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-10-deepseek-image-token-calculator-v41.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-deepseek-image-token-calculator-v41.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-10-deepseek-image-token-calculator-v41.md -2026-09-10-deepseek-image-token-calculator-v41.md: 668738221ebe3e634be7e4fe9d07c9627e0ceb4a -2026-09-10-deepseek-image-token-calculator-v41.zh.md: a483282c6da667c2b8e32accb091e065419d44fc +/agent-note-deepseek-image-token-estimator-on-the-v41-calculator: + en: 3e0b96f522d5e2c9 + zh: a05009e8f9cbe5d4 +/agent-note-deepseek-image-token-estimator-on-the-v41-calculator/problem: + en: c47a183a3192d1ae + zh: bbc157ff44423dd3 +/agent-note-deepseek-image-token-estimator-on-the-v41-calculator/decision: + en: 17f8c045d3222266 + zh: aead3e0de01980d9 +/agent-note-deepseek-image-token-estimator-on-the-v41-calculator/alternatives-considered: + en: 8f5bb52220ead193 + zh: f267fda075b19963 +/agent-note-deepseek-image-token-estimator-on-the-v41-calculator/consequences: + en: 0a41bb795e221c3f + zh: b4840b79c78691cf diff --git a/.agents/notes/implemented/bug-fix/2026-09-10-deepseek-v41-request-image-projection.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-10-deepseek-v41-request-image-projection.i18n.yaml index ece05b1229..eb27fa1ee7 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-10-deepseek-v41-request-image-projection.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-10-deepseek-v41-request-image-projection.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-deepseek-v41-request-image-projection.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-10-deepseek-v41-request-image-projection.md -2026-09-10-deepseek-v41-request-image-projection.md: 2bf7ac3f7f09ff7aea1067030f4474306d3f9a8e -2026-09-10-deepseek-v41-request-image-projection.zh.md: 4f0a8cfd3a71d54a54bf74d6819235ed7d0749f8 +/agent-note-deepseek-request-images-on-the-published-token-grid: + en: 67401dae42c79c06 + zh: 19ab8d82fec9ec25 +/agent-note-deepseek-request-images-on-the-published-token-grid/problem: + en: 3c86cfcbd6895dc5 + zh: 68cb8bd4c1ef2d24 +/agent-note-deepseek-request-images-on-the-published-token-grid/decision: + en: 0c1257b4fd77d7ad + zh: b1134f24c8f58ded +/agent-note-deepseek-request-images-on-the-published-token-grid/alternatives-considered: + en: c5d3470b62129fde + zh: 26c9abf1e4a4f49f +/agent-note-deepseek-request-images-on-the-published-token-grid/consequences: + en: 95bc8d0d09928dee + zh: 090292fa154e854f diff --git a/.agents/notes/implemented/bug-fix/2026-09-11-incremental-terminal-retention.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-11-incremental-terminal-retention.i18n.yaml index 29767853c0..aa5f93f3c7 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-11-incremental-terminal-retention.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-11-incremental-terminal-retention.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-incremental-terminal-retention.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-11-incremental-terminal-retention.md -2026-09-11-incremental-terminal-retention.md: 7e2507775bc39ed2599c2af1173f949bbf352145 -2026-09-11-incremental-terminal-retention.zh.md: 6c6fb95fa0c593ae2b7abb0007d5e7c6fc9f4e7d +/agent-note-incremental-terminal-retention: + en: b00300b3ace789da + zh: c267be719b3c8814 +/agent-note-incremental-terminal-retention/problem: + en: 0c3232a4a2429315 + zh: c6b3c6224bc9031d +/agent-note-incremental-terminal-retention/decision: + en: 43bb3c2d0d561231 + zh: 8dacb0720f28d490 +/agent-note-incremental-terminal-retention/measurement-design: + en: 925815f8ae326179 + zh: 188ee3f695ece8de +/agent-note-incremental-terminal-retention/measurement-design/local-reference-measurements: + en: a049c0a118648de7 + zh: 2c31044ff11b9029 +/agent-note-incremental-terminal-retention/alternatives-considered: + en: 0af1fcbc28320b5b + zh: 8e1cfc843821dd77 +/agent-note-incremental-terminal-retention/consequences: + en: c60008ba652dffd2 + zh: 3210329182096f39 diff --git a/.agents/notes/implemented/bug-fix/2026-09-12-linux-scope-direct-kill-settlement.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-12-linux-scope-direct-kill-settlement.i18n.yaml index d3c3388a18..192ea7ceec 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-12-linux-scope-direct-kill-settlement.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-12-linux-scope-direct-kill-settlement.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-linux-scope-direct-kill-settlement.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-12-linux-scope-direct-kill-settlement.md -2026-09-12-linux-scope-direct-kill-settlement.md: e89d8f801d6f7fb1309f50e0bc3dbad69aa797d0 -2026-09-12-linux-scope-direct-kill-settlement.zh.md: 7ab43107491ec24d5e39a62c401d245b61bb744d +/agent-note-join-direct-termination-before-rejecting-linux-scope-cleanup: + en: 6a72b66b6d0cf21b + zh: be432bfebb8e9919 +/agent-note-join-direct-termination-before-rejecting-linux-scope-cleanup/problem: + en: be042a28c1154171 + zh: 7b8356c9dcb159be +/agent-note-join-direct-termination-before-rejecting-linux-scope-cleanup/decision: + en: 75b071e48715ff29 + zh: 3f1d710f54ed3b1b +/agent-note-join-direct-termination-before-rejecting-linux-scope-cleanup/alternatives-considered: + en: ea3f33dd6c9bab88 + zh: 6f274fcd86b231a7 +/agent-note-join-direct-termination-before-rejecting-linux-scope-cleanup/consequences: + en: 4f7e7535b49b22fe + zh: 10447b3c42a341a2 diff --git a/.agents/notes/implemented/bug-fix/2026-09-13-partitioned-coverage-location-canonicalization.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-13-partitioned-coverage-location-canonicalization.i18n.yaml index 2f76639c0d..baae5ed39f 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-13-partitioned-coverage-location-canonicalization.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-13-partitioned-coverage-location-canonicalization.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-13-partitioned-coverage-location-canonicalization.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-13-partitioned-coverage-location-canonicalization.md -2026-09-13-partitioned-coverage-location-canonicalization.md: 54e5aaefe9551d1357f1c60201212873a1c7aef7 -2026-09-13-partitioned-coverage-location-canonicalization.zh.md: 1aa4b8de844a1f0e544d2bbb223641dbbfeff3da +/agent-note-canonicalize-partition-coverage-locations-before-the-blob-merge: + en: 9346bcf9fc59bea8 + zh: 170ebd969ac038bd +/agent-note-canonicalize-partition-coverage-locations-before-the-blob-merge/problem: + en: c2f8792fb6ec46d1 + zh: cc01e2e2ff14f367 +/agent-note-canonicalize-partition-coverage-locations-before-the-blob-merge/decision: + en: 07f37eb8430ef8ee + zh: bc2910040b90291c +/agent-note-canonicalize-partition-coverage-locations-before-the-blob-merge/divergent-statement-maps-across-vite-environments: + en: 4f6d088fd7e272fc + zh: d44463ee8485b060 +/agent-note-canonicalize-partition-coverage-locations-before-the-blob-merge/testing: + en: 59a8515f97eb4c63 + zh: 86d655d454da2c63 +/agent-note-canonicalize-partition-coverage-locations-before-the-blob-merge/alternatives-considered: + en: 8c7efd287cf0e56b + zh: 2ed0477918e10f4e +/agent-note-canonicalize-partition-coverage-locations-before-the-blob-merge/consequences: + en: c7a2e99922697cb6 + zh: 0c98a57b00263bf8 diff --git a/.agents/notes/implemented/bug-fix/2026-09-14-chat-presentation-defaults.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-14-chat-presentation-defaults.i18n.yaml index 9ce88177ba..e671a8aa27 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-14-chat-presentation-defaults.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-14-chat-presentation-defaults.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-chat-presentation-defaults.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-14-chat-presentation-defaults.md -2026-09-14-chat-presentation-defaults.md: 6703a14e2ad108c4b43dd50692a44c159cf3ea5a -2026-09-14-chat-presentation-defaults.zh.md: 67ca433339ecf6e44d3f74b6c3ff9e465f802b0b +/agent-note-keep-chat-presentation-independent-of-trajectory-inspection: + en: 72d5bc0911e0bc3f + zh: 1fc58f89bdc53b56 +/agent-note-keep-chat-presentation-independent-of-trajectory-inspection/problem: + en: 2102a58c1baafe54 + zh: 939872d86e013f94 +/agent-note-keep-chat-presentation-independent-of-trajectory-inspection/decision: + en: f77e394352fe8d8e + zh: 7c4c9b066874dc9b +/agent-note-keep-chat-presentation-independent-of-trajectory-inspection/alternatives-considered: + en: f4c1b9c9998e3355 + zh: f684e39ffabce5e6 +/agent-note-keep-chat-presentation-independent-of-trajectory-inspection/consequences: + en: bb15d68e46b10b8e + zh: 8506ab5775d04fe8 diff --git a/.agents/notes/implemented/bug-fix/2026-09-14-web-diff-context.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-14-web-diff-context.i18n.yaml index 286919457a..8a44818fd8 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-14-web-diff-context.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-14-web-diff-context.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-web-diff-context.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-14-web-diff-context.md -2026-09-14-web-diff-context.md: 072af0966689d475d7fdd1df83861fa847f3745f -2026-09-14-web-diff-context.zh.md: cd165a443451fc5ba580078b1b431a2788671dbe +/agent-note-web-diff-cards-compare-contextual-content: + en: 2dc5ae1577ba6173 + zh: 0b580f4e70eddc72 +/agent-note-web-diff-cards-compare-contextual-content/problem: + en: 73aa63782984835f + zh: 41982214968dcca8 +/agent-note-web-diff-cards-compare-contextual-content/decision: + en: d8c9e2af5843c87d + zh: 5487925fa1a66da8 +/agent-note-web-diff-cards-compare-contextual-content/alternatives-considered: + en: b5d00cc913db27c9 + zh: ef72c91cff5ebcce +/agent-note-web-diff-cards-compare-contextual-content/measurement: + en: 839be054edf51392 + zh: 3d2a51e634b39eb2 +/agent-note-web-diff-cards-compare-contextual-content/consequences: + en: 1900b6984a59765c + zh: 8f3755fcdf8f2562 diff --git a/.agents/notes/implemented/bug-fix/2026-09-14-windows-lock-release-probe.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-14-windows-lock-release-probe.i18n.yaml index d98d216298..4816998bc8 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-14-windows-lock-release-probe.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-14-windows-lock-release-probe.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-windows-lock-release-probe.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-14-windows-lock-release-probe.md -2026-09-14-windows-lock-release-probe.md: 76a21f655fc8c1b299e3507beffabfacde3ac0d9 -2026-09-14-windows-lock-release-probe.zh.md: 292203d3931225f0000d56cd5cb5d700ecb0bcc7 +/agent-note-windows-lock-release-before-contention-probing: + en: ec7e0474bd96df26 + zh: 20a70a6284cb0269 +/agent-note-windows-lock-release-before-contention-probing/problem: + en: cc9630ce8e232e8a + zh: 16f3541a58eac0ef +/agent-note-windows-lock-release-before-contention-probing/decision: + en: 9230417f2af237d4 + zh: 6fbef7a6d6e1e4d0 +/agent-note-windows-lock-release-before-contention-probing/alternatives-considered: + en: ba6d9e4c01c8f25b + zh: 8899bcf11d45b258 +/agent-note-windows-lock-release-before-contention-probing/consequences: + en: fc268a94ceeb3a96 + zh: b14be62df4a4bfad diff --git a/.agents/notes/implemented/bug-fix/2026-09-15-client-session-blank-reconciliation.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-15-client-session-blank-reconciliation.i18n.yaml index 154afe129e..196679568b 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-15-client-session-blank-reconciliation.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-15-client-session-blank-reconciliation.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-client-session-blank-reconciliation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-15-client-session-blank-reconciliation.md -2026-09-15-client-session-blank-reconciliation.md: 7213636e32702c4c51887adba3da019f49b8703c -2026-09-15-client-session-blank-reconciliation.zh.md: 4b50340fea668b6d850c1d00787dda3874b61e0c +/agent-note-keep-accepted-session-presentation-across-list-refreshes: + en: cb6cc54ba8dbdb04 + zh: 49155298ed676aa9 +/agent-note-keep-accepted-session-presentation-across-list-refreshes/problem: + en: 43f5cb3e859ff15c + zh: 6aaf24dbd90601ba +/agent-note-keep-accepted-session-presentation-across-list-refreshes/decision: + en: a96b274615d2b533 + zh: 1610d9bc4bddd29f +/agent-note-keep-accepted-session-presentation-across-list-refreshes/alternatives-considered: + en: c1d81465f7ae6906 + zh: 668641e19a3e5088 +/agent-note-keep-accepted-session-presentation-across-list-refreshes/consequences: + en: 488d87360f50c682 + zh: 68408e517189ac93 +/agent-note-keep-accepted-session-presentation-across-list-refreshes/verification: + en: 4c16904319ae2745 + zh: 06bf9126b7f504ec +/agent-note-keep-accepted-session-presentation-across-list-refreshes/related-decisions: + en: 99d6b7e450a8dc09 + zh: 46a6df4730514668 diff --git a/.agents/notes/implemented/bug-fix/2026-09-15-linear-session-list-cache.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-15-linear-session-list-cache.i18n.yaml index d3b6770fac..a4a8a32d4e 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-15-linear-session-list-cache.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-15-linear-session-list-cache.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-linear-session-list-cache.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-15-linear-session-list-cache.md -2026-09-15-linear-session-list-cache.md: fb09950f77c224d2b85bb76792bdf8c3c87e33f5 -2026-09-15-linear-session-list-cache.zh.md: b877f0659fff4e1b3d48aa4250e634120ddc365f +/agent-note-linear-session-list-cache-reconciliation: + en: 7b6289de90982e71 + zh: 0c020de607402bbd +/agent-note-linear-session-list-cache-reconciliation/problem: + en: b94ff168ba0310a8 + zh: 8d9fe4af8b047c86 +/agent-note-linear-session-list-cache-reconciliation/decision: + en: 1d85980590014837 + zh: 2e03befc8ac84f0e +/agent-note-linear-session-list-cache-reconciliation/alternatives-considered: + en: 2085e3ccec11084a + zh: 55f5f5156d03e20c +/agent-note-linear-session-list-cache-reconciliation/consequences: + en: 54f1788954da5704 + zh: dad3478c7f3b46f6 diff --git a/.agents/notes/implemented/bug-fix/2026-09-15-messages-v1-base-url.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-15-messages-v1-base-url.i18n.yaml index 106b30af30..312f8cf353 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-15-messages-v1-base-url.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-15-messages-v1-base-url.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-messages-v1-base-url.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-15-messages-v1-base-url.md -2026-09-15-messages-v1-base-url.md: d9014756eacd1752495bfecb52860634ece08ae1 -2026-09-15-messages-v1-base-url.zh.md: 8f5803e4bdc68195164e187d1aa8cd537f71c5d6 +/agent-note-exact-v1-recognition-for-messages-base-urls: + en: 8e65836ea970f866 + zh: 54ef0765d2c39be8 +/agent-note-exact-v1-recognition-for-messages-base-urls/problem: + en: d6d0baca328ce1cd + zh: 152d5c7793674ed2 +/agent-note-exact-v1-recognition-for-messages-base-urls/decision: + en: 037fe11400e2e666 + zh: 5941d8f7364e45b8 +/agent-note-exact-v1-recognition-for-messages-base-urls/alternatives-considered: + en: 5615cd72ec115068 + zh: 772d9a557d46c43d +/agent-note-exact-v1-recognition-for-messages-base-urls/consequences: + en: 90a3b42b98cf99e0 + zh: 50e45634f1bd5ecb diff --git a/.agents/notes/implemented/bug-fix/2026-09-15-trajectory-attachment-presentation.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-15-trajectory-attachment-presentation.i18n.yaml index cc6eb7ff26..da4262d0ea 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-15-trajectory-attachment-presentation.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-15-trajectory-attachment-presentation.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-trajectory-attachment-presentation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-15-trajectory-attachment-presentation.md -2026-09-15-trajectory-attachment-presentation.md: 03d737d67e626497bbcb957911b1578e0dadd5fb -2026-09-15-trajectory-attachment-presentation.zh.md: 55c63bf3d97de2e3e102e92730ce4d2637547d6b +/agent-note-consistent-trajectory-attachment-presentation: + en: 44651b6372b8e74e + zh: 8e1df22f6c969427 +/agent-note-consistent-trajectory-attachment-presentation/problem: + en: 3a02d475408db611 + zh: 49ef7f0e91917e13 +/agent-note-consistent-trajectory-attachment-presentation/decision: + en: 9a37a61d84813db3 + zh: 546cf3d1734289ee +/agent-note-consistent-trajectory-attachment-presentation/decision/ownership: + en: d453afd765988e76 + zh: eeb4c7d40fe578dc +/agent-note-consistent-trajectory-attachment-presentation/alternatives-considered: + en: f32a7ff301caf058 + zh: fbea3a171a300aef +/agent-note-consistent-trajectory-attachment-presentation/consequences: + en: da70caa5b98ac85d + zh: 52a5379c3adaa62f +/agent-note-consistent-trajectory-attachment-presentation/verification: + en: 145819ab133854c3 + zh: f9a440d57c12a257 diff --git a/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.i18n.yaml index 9c2cdd061a..fdf261af26 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-desktop-window-menus.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.md -2026-09-16-desktop-window-menus.md: 8a5343404e0cb3d2e7c4e20248a8b29f3bfbec47 -2026-09-16-desktop-window-menus.zh.md: d6ee6412462aecf49557a7994a683d37bf8e7253 +/agent-note-desktop-standard-macos-window-menus: + en: 7a3fc575043bc839 + zh: 5ab70cfa35509b3e +/agent-note-desktop-standard-macos-window-menus/problem: + en: 75c201a0a687b59d + zh: 34593038f673d06f +/agent-note-desktop-standard-macos-window-menus/decision: + en: 0ce30c3a1e6202d7 + zh: badac0021fae4a6f +/agent-note-desktop-standard-macos-window-menus/alternatives-considered: + en: 957382dbfb6cac48 + zh: 2db98b7dbf3e01c0 +/agent-note-desktop-standard-macos-window-menus/consequences: + en: 1fa44c82ca450bcd + zh: b618f5ec0a90ed13 +/agent-note-desktop-standard-macos-window-menus/testing: + en: 0c05c0044532f891 + zh: cff254b44b3c7a2d diff --git a/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.md b/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.md index 8a5343404e..d8f8bdb9cc 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.md +++ b/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.md @@ -10,9 +10,9 @@ The Desktop shell replaces Electron's default application menu with a custom tem ## Decision -On macOS the template declares `{ role: 'fileMenu' }` before the Edit menu and `{ role: 'windowMenu' }` after it, and a separator-delimited run of `hide`, `hideOthers`, and `unhide` before Quit in the application submenu. Those roles contribute only the standard items; no Services submenu, window list, or other macOS default is declared. Windows and Linux keep the application and Edit menus. +On macOS the template declares `{ role: 'windowMenu' }` after the Edit menu, and a separator-delimited run of `hide`, `hideOthers`, and `unhide` before Quit in the application submenu. Those roles contribute only the standard items; no Services submenu, window list, or other macOS default is declared. Windows and Linux keep the application and Edit menus. The [page-close decision](../architecture/2026-09-21-desktop-page-close-shortcuts.md) owns the custom File menu and close behavior. -Electron supplies English defaults for the File, Window, and Edit roles. Explicit labels override role defaults while retaining native actions and shortcuts; the localized application commands are documented in the [Desktop README](../../../../apps/desktop/README.md). No custom close, minimize, or hide code is added: ⌘W destroys the window through Electron's own role. +Electron supplies English defaults for the Window and Edit roles. Explicit labels override role defaults while retaining native actions and shortcuts; the localized application commands are documented in the [Desktop README](../../../../apps/desktop/README.md). Minimize and hide execute through Electron's roles without custom handlers. Close and activation behavior is partly superseded by [close-to-background](../architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.md); the menu declarations here remain in effect. ## Alternatives considered @@ -22,13 +22,13 @@ Electron supplies English defaults for the File, Window, and Edit roles. Explici **Add a bare `{ role: 'close' }` item to the application submenu.** It avoids a File menu containing a single command, but places a window command among the app-wide Plugins, Updates, Hide, and Quit items where no macOS application puts it. -**Declare the File and Window menus on every platform.** The same template declares Ctrl+W there; with one window, closing it invokes `window-all-closed` and quits the application, turning a window shortcut into an unrequested quit path. +**Declare the File and Window menus on every platform.** The same template declares Ctrl+W there; with one window, closing it invokes `window-all-closed` and quits the application. The menu-restoration task did not request this quit path; the page-close decision explicitly specifies the Desktop fallback. **Recreate the main window on Dock activation regardless of other windows.** The plugin window can outlive the main window, so gating `activate` on `mainWindow` instead of `BrowserWindow.getAllWindows()` would let a Dock click always restore the main window. That changes window lifecycle beyond restoring the suppressed platform commands, so the existing `activate` condition stays. ## Consequences -macOS regains the window and application commands the custom menu suppressed. File, Window, and Edit retain Electron’s default English labels; application commands use the Desktop locale. +macOS retains native Window and application hide commands through four menu roles. Window and Edit retain Electron’s default English labels; application commands use the Desktop locale. ## Testing diff --git a/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.zh.md b/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.zh.md index d6ee641246..c85ab23df1 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.zh.md +++ b/.agents/notes/implemented/bug-fix/2026-09-16-desktop-window-menus.zh.md @@ -10,9 +10,9 @@ Desktop shell 用自定义模板替换了 Electron 的默认应用菜单,该 ## 决策 -macOS 上的模板在 Edit 菜单之前声明 `{ role: 'fileMenu' }`,在其之后声明 `{ role: 'windowMenu' }`,并在应用子菜单的 Quit 之前声明由分隔符隔开的 `hide`、`hideOthers` 和 `unhide`。这些 role 只提供标准菜单项;不声明 Services 子菜单、窗口列表或其他 macOS 默认项。Windows 和 Linux 保留应用菜单和 Edit 菜单。 +macOS 上的模板在 Edit 菜单之后声明 `{ role: 'windowMenu' }`,并在应用子菜单的 Quit 之前声明由分隔符隔开的 `hide`、`hideOthers` 和 `unhide`。这些 role 只提供标准菜单项;不声明 Services 子菜单、窗口列表或其他 macOS 默认项。Windows 和 Linux 保留应用菜单和 Edit 菜单。[页面关闭决策](../architecture/2026-09-21-desktop-page-close-shortcuts.zh.md)负责自定义 File 菜单和关闭行为。 -Electron 为 File、Window 和 Edit role 提供英文默认标签。显式标签会覆盖 role 的默认标签,同时保留原生命令和快捷键;本地化的应用命令见 [Desktop README](../../../../apps/desktop/README.zh.md)。这里不新增任何自定义的关闭、最小化或隐藏代码:⌘W 通过 Electron 自身的 role 销毁窗口。 +Electron 为 Window 和 Edit role 提供英文默认标签。显式标签会覆盖 role 的默认标签,同时保留原生命令和快捷键;本地化的应用命令见 [Desktop README](../../../../apps/desktop/README.zh.md)。最小化和隐藏通过 Electron 的 role 执行,没有自定义处理器。 关闭与激活行为已被[关闭时隐藏窗口](../architecture/2026-09-23-desktop-close-to-background-and-quit-confirmation.zh.md)部分取代;这里的菜单声明仍然有效。 ## 考虑过的替代方案 @@ -22,13 +22,13 @@ Electron 为 File、Window 和 Edit role 提供英文默认标签。显式标签 **在应用子菜单里直接加一个 `{ role: 'close' }` 项。** 这样可以避免只有一个命令的 File 菜单,但会把窗口命令放到 Plugins、Updates、Hide、Quit 这些应用级命令中间,没有 macOS 应用这样排布。 -**在所有平台都声明 File 和 Window 菜单。** 同一份模板在那些平台会把 Ctrl+W 声明为关闭;应用只有一个窗口,关闭它会触发 `window-all-closed` 并退出应用,把窗口快捷键变成用户没有要求的退出路径。 +**在所有平台都声明 File 和 Window 菜单。** 同一份模板在那些平台会把 Ctrl+W 声明为关闭;应用只有一个窗口,关闭它会触发 `window-all-closed` 并退出应用。恢复菜单的任务没有要求这条退出路径;页面关闭决策明确规定了 Desktop 回退。 **让 Dock 激活时无论其他窗口是否存在都重建主窗口。** 插件窗口可以比主窗口存活更久,因此把 `activate` 的判断从 `BrowserWindow.getAllWindows()` 改为 `mainWindow` 能让点击 Dock 总可以恢复主窗口。但这超出了恢复被压掉的平台命令,属于窗口生命周期的行为变更,因此保留现有的 `activate` 判断。 ## 影响 -macOS 恢复了自定义菜单压掉的窗口和应用命令。File、Window 和 Edit 保留 Electron 的默认英文标签;应用命令使用 Desktop 的语言。 +macOS 通过四个菜单 role 保留原生 Window 和应用隐藏命令。Window 和 Edit 保留 Electron 的默认英文标签;应用命令使用 Desktop 的语言。 ## 测试 diff --git a/.agents/notes/implemented/bug-fix/2026-09-16-messages-historical-tool-input.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-16-messages-historical-tool-input.i18n.yaml index e6974943f5..d0f3da21b3 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-16-messages-historical-tool-input.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-16-messages-historical-tool-input.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-messages-historical-tool-input.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-16-messages-historical-tool-input.md -2026-09-16-messages-historical-tool-input.md: 85e4047bb5274eb7c7adb458d564e1268d4ea81e -2026-09-16-messages-historical-tool-input.zh.md: 5a8c31dbee32094f124102ccac9ffb7b8b81b177 +/agent-note-replay-malformed-historical-tool-input-through-messages: + en: 88cdfca30918b47f + zh: 1203d380805f81e4 +/agent-note-replay-malformed-historical-tool-input-through-messages/problem: + en: b9f848905bb31969 + zh: 7c56aab1a15cfc85 +/agent-note-replay-malformed-historical-tool-input-through-messages/decision: + en: ee7c586820c28e54 + zh: fced4d6c50c7d227 +/agent-note-replay-malformed-historical-tool-input-through-messages/alternatives-considered: + en: c7d7275282a83780 + zh: c0c570f156ac546f +/agent-note-replay-malformed-historical-tool-input-through-messages/consequences: + en: 4d1447eb8ea0f7f4 + zh: cf232f6bb1d60d4e diff --git a/.agents/notes/implemented/bug-fix/2026-09-16-present-delayed-windows-installer.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-16-present-delayed-windows-installer.i18n.yaml index f8d7bd6adf..e64fb33fd5 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-16-present-delayed-windows-installer.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-16-present-delayed-windows-installer.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-present-delayed-windows-installer.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-16-present-delayed-windows-installer.md -2026-09-16-present-delayed-windows-installer.md: d4ffcfdc1183bbc414cfdd82595053c959a9975c -2026-09-16-present-delayed-windows-installer.zh.md: bf97ed8a4f6c7184d1e048c21f7975c90fb4a9cb +/agent-note-present-delayed-windows-installer: + en: 4451eeb66010bc3d + zh: 7b5e60d779a9eb41 +/agent-note-present-delayed-windows-installer/problem: + en: 7835e64ac8ea1825 + zh: aac3b323204b08b9 +/agent-note-present-delayed-windows-installer/decision: + en: adea34850b8df240 + zh: da68a90a4144092f +/agent-note-present-delayed-windows-installer/alternatives-considered: + en: 66f936fe39452162 + zh: 4d0e192fb37afffe +/agent-note-present-delayed-windows-installer/consequences: + en: 6431f3c88199ecaf + zh: 9f30f647fdab4e64 diff --git a/.agents/notes/implemented/bug-fix/2026-09-16-session-writer-held-feedback.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-16-session-writer-held-feedback.i18n.yaml index 61b6c1c780..3d896f268f 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-16-session-writer-held-feedback.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-16-session-writer-held-feedback.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-session-writer-held-feedback.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-16-session-writer-held-feedback.md -2026-09-16-session-writer-held-feedback.md: 922987996c4abd32857cd0f54cec4394566cf97f -2026-09-16-session-writer-held-feedback.zh.md: 6a1aa7993a8f36c50cb5fed0180d6523af44c177 +/agent-note-session-writer-contention-feedback: + en: 31fc83d11f79fbac + zh: ec2e62f56a83ff3c +/agent-note-session-writer-contention-feedback/problem: + en: ce6f2ed854986c2a + zh: 74b28d3282f610e8 +/agent-note-session-writer-contention-feedback/decision: + en: a2c50e7614d183fd + zh: c4057682bc25cb23 +/agent-note-session-writer-contention-feedback/alternatives-considered: + en: 43f74d015db77ab1 + zh: 38c7ffda0a33ecac +/agent-note-session-writer-contention-feedback/consequences: + en: 230c23cceae0ad46 + zh: 8ec04813b825b509 diff --git a/.agents/notes/implemented/bug-fix/2026-09-16-windows-subprocess-console-visibility.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-16-windows-subprocess-console-visibility.i18n.yaml index b6d4fe5084..879cde4ff0 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-16-windows-subprocess-console-visibility.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-16-windows-subprocess-console-visibility.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-windows-subprocess-console-visibility.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-16-windows-subprocess-console-visibility.md -2026-09-16-windows-subprocess-console-visibility.md: 281525e960b049d5871cde9f5da5c8f928654440 -2026-09-16-windows-subprocess-console-visibility.zh.md: 04abf7154b4b384ca521b9d232c7dfb398f5ed99 +/agent-note-hide-windows-subprocess-console-windows-at-creation: + en: be47c56d2dd977d1 + zh: 3ab8a9a18e7f545d +/agent-note-hide-windows-subprocess-console-windows-at-creation/problem: + en: b76c3b25b8616076 + zh: d14facfdf3948bc4 +/agent-note-hide-windows-subprocess-console-windows-at-creation/decision: + en: 56b951a948c6d007 + zh: 301031638a642517 +/agent-note-hide-windows-subprocess-console-windows-at-creation/alternatives-considered: + en: 9dcf5702a5032d69 + zh: 493c2709d441d52c +/agent-note-hide-windows-subprocess-console-windows-at-creation/consequences: + en: 0bfe83068c6fe3ee + zh: 2bdc9eb64c6f7b66 diff --git a/.agents/notes/implemented/bug-fix/2026-09-17-thinking-markdown.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-17-thinking-markdown.i18n.yaml index 6377a233cb..9290c75e26 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-17-thinking-markdown.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-17-thinking-markdown.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-thinking-markdown.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-17-thinking-markdown.md -2026-09-17-thinking-markdown.md: 6990fc6277d7d1c0a088a50cfb88694b2d9c55c7 -2026-09-17-thinking-markdown.zh.md: 963626088e50a44bcf76c7fc7ec3653e93fcd2c9 +/agent-note-compact-markdown-for-thinking: + en: 2b71ec7a5294e982 + zh: 0c33248c5d07ec74 +/agent-note-compact-markdown-for-thinking/problem: + en: c14bd1618741736a + zh: dc1fff84736cb4f7 +/agent-note-compact-markdown-for-thinking/decision: + en: adb4f711ecf2011a + zh: 791f7bf3b8d23458 +/agent-note-compact-markdown-for-thinking/alternatives-considered: + en: d5bf82e0de012900 + zh: a639fd02e00b5d09 +/agent-note-compact-markdown-for-thinking/consequences: + en: d69b13246a34047c + zh: 4c1a6520053261ef diff --git a/.agents/notes/implemented/bug-fix/2026-09-18-messages-input-history-compatibility.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-18-messages-input-history-compatibility.i18n.yaml index 259613bc28..4d97265632 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-18-messages-input-history-compatibility.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-18-messages-input-history-compatibility.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-18-messages-input-history-compatibility.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-18-messages-input-history-compatibility.md -2026-09-18-messages-input-history-compatibility.md: dd974fb1ae883716002a1381f4c374dee792b3b3 -2026-09-18-messages-input-history-compatibility.zh.md: 6e850328db63d5ae5cb508aa3529e9f2507182b0 +/agent-note-replay-assistant-blocks-in-messages-user-input: + en: 2928aedee63465ba + zh: 0492dcc6604e2292 +/agent-note-replay-assistant-blocks-in-messages-user-input/problem: + en: d42b7147df73f498 + zh: f77ef429363c2da8 +/agent-note-replay-assistant-blocks-in-messages-user-input/decision: + en: 0b5629b321be7181 + zh: 3449958cde376d59 +/agent-note-replay-assistant-blocks-in-messages-user-input/alternatives-considered: + en: 3801041c0f9c4d8a + zh: 71d80b08183e8b30 +/agent-note-replay-assistant-blocks-in-messages-user-input/consequences: + en: c1770c7aa4097c42 + zh: 80ab7f2b66408ad7 diff --git a/.agents/notes/implemented/bug-fix/2026-09-18-schedule-task-tab-restore.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-18-schedule-task-tab-restore.i18n.yaml new file mode 100644 index 0000000000..dc30220e34 --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-18-schedule-task-tab-restore.i18n.yaml @@ -0,0 +1,22 @@ +# Bilingual-pair consistency record for 2026-09-18-schedule-task-tab-restore.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-18-schedule-task-tab-restore.md +/agent-note-task-tab-recovery-after-a-reload: + en: d7edcc16307d350a + zh: 63301b138b2a203b +/agent-note-task-tab-recovery-after-a-reload/problem: + en: 244f309423fff24e + zh: ddd2ab66a3f4fd5b +/agent-note-task-tab-recovery-after-a-reload/decision: + en: 16e1bcb4a0860e91 + zh: 587715df43d5c96f +/agent-note-task-tab-recovery-after-a-reload/alternatives-considered: + en: 2fb8e2e0688d22ac + zh: a584b183723aace7 +/agent-note-task-tab-recovery-after-a-reload/consequences: + en: 20b7e4c551df0bc0 + zh: c17426fb981f0b06 +/agent-note-task-tab-recovery-after-a-reload/testing: + en: 3581ad83c52ee3b0 + zh: fbffd886a46b76c6 diff --git a/.agents/notes/implemented/bug-fix/2026-09-18-schedule-task-tab-restore.md b/.agents/notes/implemented/bug-fix/2026-09-18-schedule-task-tab-restore.md new file mode 100644 index 0000000000..3809dfadce --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-18-schedule-task-tab-restore.md @@ -0,0 +1,45 @@ +# Agent Note: Task tab recovery after a reload + +Status: implemented + +English | [中文](2026-09-18-schedule-task-tab-restore.zh.md) + +## Problem + +The right Sidebar persists a Session's layout as tab records and not the navigation parameters an opener passed, per the [tab type and navigation decision](../architecture/2026-09-05-sidebar-tab-types-and-navigation.md). A `scheduleTask` tab restored by a reload therefore had no task identity: its body could show only its loading feedback and its chip only the constant label, until the user opened the task again from the Session entry. Recovering content belongs to the tab type's provider, as the [layout persistence decision](../architecture/2026-09-14-sidebar-layout-provider-recovery.md) established for terminals, and the Sidebar exposes no parameter store for a page type to reuse. + +## Decision + +The task tab page keeps a durable binding to the task it last showed and resolves a restored record from it. + +The binding key is the Sidebar Session plus the layout record's own id. `dsh.sidebar-right.v1.` persists the tab records and the counter that mints their ids, so a record keeps its id across a reload and no record minted later in that layout reuses it. The record's `contentId` is not a usable key: every tab of one page kind is recorded under the same `sidebar://` address, and page deduplication is per pane, so two panes may each hold a task tab. Each entry also stores the `kind` and `contentId` of the record it was written for, and a read drops and ignores an entry whose pair differs from the record reading it. + +One localStorage document per Session, keyed `dsh.schedule.task-tab.v1.`, holds one entry per tab id, mapping that page to the Session and id of its last task. No task content is stored. A write keeps only the entries whose tab the Session's committed layout still holds, read through `ctx.sidebarRight.tabsIn(sessionId)`; a Session whose layout is not adopted leaves its entries alone. An entry that a read succeeding after the tab appeared cannot resolve is removed, which leaves the tab with the unbound-tab notice, the same state as one that never had a binding. + +The body writes the binding in an effect whenever a navigation carries this type's parameters, and reads it only while the record has no navigation parameters; parameters of another kind leave the record in its missing-task state. A recovered identity then follows the existing rules: the detail whenever the retained records hold the task, the catalog feedback until a read requested after the tab's baseline settles without the task, and the query-failure state with its retry when the read fails. A binding such a read cannot resolve shows the unbound-tab notice instead of the loading feedback, and never the missing-task notice, because that notice states that an opener named a task. + +The body measures the answer from the catalog read request ordinal it observed for its current navigation, and asks for a read whenever the retained records leave it without a task and no read requested after that ordinal has succeeded, reporting the catalog feedback while that read is pending. The Sidebar navigates a tab again without remounting its body, so the navigation's revision moves the baseline; a read requested before the baseline never states that the tab's task is gone. + +## Alternatives considered + +**Key the binding by `contentId`.** Rejected: every tab of one page kind is recorded under the same address, and page deduplication is per pane, so two task tabs in two panes would share one binding and restore the same task. + +**Persist navigation parameters in the Sidebar layout.** Rejected: it moves content parameters into the layout snapshot that the [navigation decision](../architecture/2026-09-05-sidebar-tab-types-and-navigation.md) keeps transient, and every future page type would inherit the format. + +**Declare the kind `multiple: true` so every open mints a unique contentId.** Rejected: it changes what opening a task does — a second task opens a second tab instead of showing in the existing one — to obtain a key, and it cannot recover records restored before the change. + +**Resolve the task from the catalog.** Rejected: the catalog holds no per-tab association, and the Session entry the tab was opened from is gone after a reload. + +**Reuse the client store's localStorage persistence.** Rejected: `createSnapshotStore`'s `persist` option saves one whole store value under one name and rehydrates it when that store is created, so it needs a store per Session; the binding also has to reject reused ids and prune closed tabs on write, which a keyed document does in one place with no subscription for a body to re-render through. + +**Store the task title beside the binding to confirm the recovery.** Rejected: a title is task content, it changes with an edit, and the settled catalog read already decides whether the bound id resolves. + +## Consequences + +A reloaded Session restores every task tab's detail and chip without reopening the task. The binding is window-local browser state: another browser, a cleared origin, or a tab the layout kit duplicated has none, and such a record states that the tab has no task instead of claiming the task is gone. A discarded layout snapshot can mint a tab id that a binding still names; the kind and contentId guard rejects an entry of another kind, and an entry of the same kind is overwritten by the next navigation of that tab or removed once its task stops resolving. + +Entries of Sessions whose layouts are never adopted again remain until their next write; write-time pruning bounds every adopted Session, and no entry holds content. + +## Testing + +Unit tests cover writing on navigation, reading only without parameters, recovery into the detail and the chip, degradation of an unresolvable binding, committed-tab pruning, reused-id rejection, malformed stored documents, and storage that is absent or rejects writes. diff --git a/.agents/notes/implemented/bug-fix/2026-09-18-schedule-task-tab-restore.zh.md b/.agents/notes/implemented/bug-fix/2026-09-18-schedule-task-tab-restore.zh.md new file mode 100644 index 0000000000..84a1a1247b --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-18-schedule-task-tab-restore.zh.md @@ -0,0 +1,45 @@ +# Agent Note: 刷新后任务标签页的恢复 + +Status: implemented + +[English](2026-09-18-schedule-task-tab-restore.md) | 中文 + +## Problem + +右 Sidebar 按 [标签类型与导航决策](../architecture/2026-09-05-sidebar-tab-types-and-navigation.zh.md) 只把 Session 布局持久化为标签记录,不持久化打开方传入的导航参数。因此刷新恢复出的 `scheduleTask` 标签没有任务身份:正文只能显示加载反馈,chip 只能显示固定文案,直到用户从 Session 入口重新打开该任务。按 [布局持久化决策](../architecture/2026-09-14-sidebar-layout-provider-recovery.zh.md) 为终端确立的划分,恢复内容属于标签类型自身 provider 的职责,而 Sidebar 没有可供页面类型复用的参数存储。 + +## Decision + +任务标签页保存到它最后显示任务的持久关联,并据此恢复刷新出的记录。 + +关联键是 Sidebar Session 加布局记录自身的 id。`dsh.sidebar-right.v1.` 持久化标签记录以及铸造其 id 的计数器,因此记录刷新后保持 id,该布局之后铸造的记录也不会复用它。记录的 `contentId` 不能作为键:同一种页面类型的所有标签都记录在同一个 `sidebar://` 地址下,而页面去重按 pane 进行,两个 pane 可以各有一个任务标签。每条记录还保存写入时该记录的 `kind` 和 `contentId`;读取时若这一对与读取它的记录不一致,就删除该条并视为无关联。 + +每个 Session 一个 localStorage 文档,键为 `dsh.schedule.task-tab.v1.`,按 tab id 保存一条记录,把该页面映射到其最后任务的 Session 和 id。不保存任何任务内容。写入时只保留 Session 已提交布局仍然持有的标签对应的记录,该布局通过 `ctx.sidebarRight.tabsIn(sessionId)` 读取;布局未被采用的 Session 保持其记录不变。标签页出现之后成功的一次读取无法解析的记录会被删除,使该标签显示未关联页签提示,与从未有关联的标签相同。 + +只要一次导航携带本类型的参数,正文就在 effect 中写入该关联;只有记录完全没有导航参数时才读取它,其他类型的参数让记录停留在任务缺失状态。恢复出的身份随后遵循既有的渲染规则:保留的记录包含该任务时即显示详情,判据之后请求的读取仍未给出该任务时显示目录反馈,读取失败时显示带重试的查询失败状态。这样的读取仍无法解析的关联显示未关联页签提示,而不是加载反馈,也绝不产生任务缺失提示,因为该提示的含义是打开方指名了一个任务。 + +正文以它为当前导航观察到的目录读取请求序号作为判据,并在保留的记录使标签页没有任务、且该序号之后没有读取成功时补发一次读取,该读取未落地期间显示目录反馈。Sidebar 会在不重新挂载正文的情况下对同一标签再次导航,因此以导航的 revision 移动判据;早于判据发出的读取永远不能断言该标签的任务已消失。 + +## Alternatives considered + +**用 `contentId` 作为关联键。** 否决:同一种页面类型的所有标签都记录在同一地址下,且页面去重按 pane 进行,两个 pane 的任务标签会共用一个关联并恢复出同一个任务。 + +**把导航参数持久化进 Sidebar 布局。** 否决:这会把内容参数放进 [导航决策](../architecture/2026-09-05-sidebar-tab-types-and-navigation.zh.md) 保持为临时的布局快照,且之后每种页面类型都会继承该格式。 + +**把 kind 声明为 `multiple: true`,让每次打开都铸造唯一 contentId。** 否决:为了取得一个键而改变打开任务的行为——打开第二个任务会新开一个标签,而不是在已有标签中显示;而且它无法恢复改动之前已存在的记录。 + +**从目录解析任务。** 否决:目录不保存按标签的关联,而打开该标签的 Session 入口在刷新后已不存在。 + +**复用 client store 的 localStorage 持久化。** 否决:`createSnapshotStore` 的 `persist` 选项把一个 store 的整体值保存在一个键下,并在该 store 创建时回填,因此需要按 Session 各建一个 store;而该关联还必须拒绝复用的 id 并在写入时清理已关闭标签,这些由一份按键文档在一处完成,也不需要正文为其订阅重渲染。 + +**在关联旁保存任务标题以确认恢复。** 否决:标题属于任务内容,会随编辑变化,而已定论的目录读取本身就能判断绑定的 id 是否可解析。 + +## Consequences + +刷新后的 Session 无需重新打开任务即可恢复每个任务标签的详情和 chip。该关联是窗口内的浏览器状态:其他浏览器、被清除的站点数据,或被布局工具包复制出的标签都没有它,这类记录会说明该页签未关联任务,而不会声称任务已不存在。被丢弃的布局快照可能铸造出关联仍然指名的 tab id;kind 与 contentId 守卫会拒绝其他类型的记录,而同类型记录会因该标签的下一次导航被覆盖,或在任务不再可解析时被删除。 + +布局不再被采用的 Session 的记录会保留到其下次写入;写入时的清理使每个已采用的 Session 有界,且任何记录都不含内容。 + +## Testing + +单元测试覆盖:导航时写入、仅在无参数时读取、详情与 chip 的恢复、无法解析关联的降级、已提交标签的清理、复用 id 的拒绝、损坏的存储文档,以及存储缺失或拒绝写入的情况。 diff --git a/.agents/notes/implemented/bug-fix/2026-09-18-windows-directory-junction-listing.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-18-windows-directory-junction-listing.i18n.yaml new file mode 100644 index 0000000000..9a2f10699e --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-18-windows-directory-junction-listing.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-18-windows-directory-junction-listing.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-18-windows-directory-junction-listing.md +/agent-note-list-directory-links-in-the-workspace-file-tree: + en: 70fbeeae3fa4a6e6 + zh: 6ed08f09c9d1d02e +/agent-note-list-directory-links-in-the-workspace-file-tree/problem: + en: eec5c2e8edd0e0ff + zh: 03c0f3490bb891c0 +/agent-note-list-directory-links-in-the-workspace-file-tree/decision: + en: ad36ceb185d15d69 + zh: 71847eaa4641a9d7 +/agent-note-list-directory-links-in-the-workspace-file-tree/alternatives-considered: + en: 8a9daf7bd2d78b65 + zh: 69f46ee1108c2747 +/agent-note-list-directory-links-in-the-workspace-file-tree/consequences: + en: 3cbc15d04a639292 + zh: 4a9c94a1a1e8aeca diff --git a/.agents/notes/implemented/bug-fix/2026-09-18-windows-directory-junction-listing.md b/.agents/notes/implemented/bug-fix/2026-09-18-windows-directory-junction-listing.md new file mode 100644 index 0000000000..8e0edc0b99 --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-18-windows-directory-junction-listing.md @@ -0,0 +1,27 @@ +# Agent Note: List directory links in the workspace file tree + +Status: implemented + +English | [中文](2026-09-18-windows-directory-junction-listing.zh.md) + +## Problem + +Windows profile directories such as `Documents\My Music` are directory junctions: reparse points that `lstat` reports as symlinks rather than directories. The `list` endpoint gated on `lstat` before resolving, so it refused every final link with `workspace-file/not-directory`, while its own listing reported those same children as `directory` because `listDir` resolves each child. The file tree therefore listed the junctions and refused to open them, and the Sidebar reported `My Music`, `My Pictures`, and `My Videos` as not a directory. + +## Decision + +`list` follows a final link and judges what it resolves to. The resolved target must pass workspace containment and must stat as a directory, so a directory link inside the workspace lists through its target, and the returned workspace path names that target. A link resolving outside the workspace is `workspace-file/outside-workspace`; a link to a non-directory, or one whose target is gone, is `workspace-file/not-directory` with kind `symlink`. + +`read`, `readBytes`, `readAll`, `readRelated`, and `stat` keep their `lstat` gate that refuses a final symlink, so no read path follows a link. The [Workspace Files service](../architecture/2026-09-05-workspace-files-service.md) keeps ownership of the service; its earlier rule that `list` rejects a final symlink is superseded here. + +## Alternatives considered + +**Drop the `lstat` gate for every method.** Rejected: reading through a link is a separate exposure decision, and the file methods' no-follow rule is a trust rule the report asked to keep. + +**Special-case Windows junctions.** Rejected: `fs-local` already reports a junction as a `symlink` path entry, and the resolve-then-contain rule is identical for a junction and a POSIX directory symlink. + +**Keep the gate and report a linked directory from the parent listing only.** Rejected: the listing already reports the resolved type, so the endpoint contradicted itself and a reader could not open what the parent presented as a directory. + +## Consequences + +A directory link inside the workspace now lists like its target, and the Windows profile junctions expand in the Sidebar. A link resolving outside the workspace reports `outside-workspace` instead of `not-directory`, which names the actual reason. Read access is unchanged. Tests cover a directory link inside the workspace, a link resolving outside it, and a link whose target is deleted; the spec creates a junction with `symlink(target, path, 'junction')` on Windows and a directory symlink elsewhere, so one spec runs on both. diff --git a/.agents/notes/implemented/bug-fix/2026-09-18-windows-directory-junction-listing.zh.md b/.agents/notes/implemented/bug-fix/2026-09-18-windows-directory-junction-listing.zh.md new file mode 100644 index 0000000000..3236c063d6 --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-18-windows-directory-junction-listing.zh.md @@ -0,0 +1,27 @@ +# Agent Note: 列举工作区文件树中的目录链接 + +Status: implemented + +[English](2026-09-18-windows-directory-junction-listing.md) | 中文 + +## Problem + +Windows 的个人目录如 `Documents\My Music` 是目录联接:`lstat` 把这类重解析点报告为符号链接而不是目录。`list` 端点在解析之前先用 `lstat` 把关,于是把所有末端链接都以 `workspace-file/not-directory` 拒绝;而它自己的列举又把同样的子项报告为 `directory`,因为 `listDir` 会解析每个子项。文件树因此既列出这些联接、又拒绝打开它们,侧栏把 `My Music`、`My Pictures`、`My Videos` 报告为非目录。 + +## Decision + +`list` 跟随末端链接并判定其解析结果。解析后的目标必须通过工作区包含检查,且经 stat 必须为目录,因此工作区内的目录链接经其目标列举,返回的工作区路径也以该目标命名。解析到工作区外的链接为 `workspace-file/outside-workspace`;指向非目录的链接、或目标已消失的链接,为 kind 为 `symlink` 的 `workspace-file/not-directory`。 + +`read`、`readBytes`、`readAll`、`readRelated` 与 `stat` 保留拒绝末端符号链接的 `lstat` 把关,因此没有任何读取路径跟随链接。[工作区文件服务](../architecture/2026-09-05-workspace-files-service.zh.md)继续拥有该服务;它此前「`list` 拒绝末端符号链接」的规则由本记录取代。 + +## Alternatives considered + +**对所有方法去掉 `lstat` 把关。** 被否:经链接读取是另一项暴露决策,文件方法的「不跟随」规则是报告方要求保留的信任规则。 + +**单独处理 Windows 目录联接。** 被否:`fs-local` 已把目录联接报告为 `symlink` 路径项,且「先解析再判包含」的规则对目录联接与 POSIX 目录符号链接完全相同。 + +**保留把关,只靠父层列举报告被链接的目录。** 被否:列举本来就报告解析后的类型,端点因此自相矛盾,读取方无法打开父层呈现为目录的条目。 + +## Consequences + +工作区内的目录链接现在与其目标一样可列举,Windows 个人目录中的联接可在侧栏展开。解析到工作区外的链接报告 `outside-workspace` 而不是 `not-directory`,如实说明原因。读取权限不变。测试覆盖工作区内的目录链接、解析到工作区外的链接,以及目标被删除的链接;spec 在 Windows 上用 `symlink(target, path, 'junction')` 创建目录联接,在其他平台创建目录符号链接,因此同一 spec 两端都跑。 diff --git a/.agents/notes/implemented/bug-fix/2026-09-19-declared-session-attachment-carriers.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-19-declared-session-attachment-carriers.i18n.yaml index a49e4b2351..a1c2b57fdb 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-19-declared-session-attachment-carriers.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-19-declared-session-attachment-carriers.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-declared-session-attachment-carriers.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-19-declared-session-attachment-carriers.md -2026-09-19-declared-session-attachment-carriers.md: 1619624800dc5e1ee8d6a4f4b64b84a6c80078c2 -2026-09-19-declared-session-attachment-carriers.zh.md: bd66b1c80469e2adbd7becc1b015d390978becc6 +/agent-note-declared-session-attachment-carriers: + en: ec696589b6d29694 + zh: fca0e8292a840d47 +/agent-note-declared-session-attachment-carriers/problem: + en: 2c3544ea223fd86c + zh: fee865c0ce374115 +/agent-note-declared-session-attachment-carriers/decision: + en: 7538fa848fbbeff8 + zh: 6fd10f3683cadef0 +/agent-note-declared-session-attachment-carriers/alternatives-considered: + en: 3307cfd109d19377 + zh: a0051b257807e6d0 +/agent-note-declared-session-attachment-carriers/consequences: + en: 9d028f075b96f121 + zh: c5da5f89f7b75efc +/agent-note-declared-session-attachment-carriers/verification: + en: f297ee8e56e7e69e + zh: e6bc44cb7711b778 diff --git a/.agents/notes/implemented/bug-fix/2026-09-19-session-local-subagent-migration.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-19-session-local-subagent-migration.i18n.yaml index e2f0f66dda..5618368313 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-19-session-local-subagent-migration.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-19-session-local-subagent-migration.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-session-local-subagent-migration.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-19-session-local-subagent-migration.md -2026-09-19-session-local-subagent-migration.md: 26911ea6e2cb31126d13e4c8c6488ff3b45563e6 -2026-09-19-session-local-subagent-migration.zh.md: 673040a3dc73d3665e42013a4704ef2d5911b23d +/agent-note-complete-parent-catalogs-without-migrating-child-catalogs: + en: 352c234841bc0905 + zh: 89be7b695aec5931 +/agent-note-complete-parent-catalogs-without-migrating-child-catalogs/problem: + en: 5ca0c3232895a9dd + zh: cb89e5464d4a5f99 +/agent-note-complete-parent-catalogs-without-migrating-child-catalogs/decision: + en: 7a368a5ad8dc3e0c + zh: 11ca2af33de30d8f +/agent-note-complete-parent-catalogs-without-migrating-child-catalogs/alternatives-considered: + en: 7272107ab68ceefd + zh: 8b8bba44c9e0c402 +/agent-note-complete-parent-catalogs-without-migrating-child-catalogs/consequences: + en: 7caecc8516419375 + zh: cc966c325896737d diff --git a/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.i18n.yaml index bf6d6c2fd0..3b1c733004 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-v3-incomplete-child-catalog-evidence.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-19-v3-incomplete-child-catalog-evidence.md -2026-09-19-v3-incomplete-child-catalog-evidence.md: 400a84f376a7babc0a95492ca33a3bcd0761cd79 -2026-09-19-v3-incomplete-child-catalog-evidence.zh.md: 535951630bc600647724d50107e74e83ab626739 +/agent-note-preserve-v3-sessions-with-incomplete-child-catalog-evidence: + en: ff7fbd846f8edf2f + zh: 8f4703ea0b0d7cc9 +/agent-note-preserve-v3-sessions-with-incomplete-child-catalog-evidence/problem: + en: a5d524599f02e77f + zh: b79687f999f4024c +/agent-note-preserve-v3-sessions-with-incomplete-child-catalog-evidence/decision: + en: cfd781300b663010 + zh: 6f7865d5619a1e52 +/agent-note-preserve-v3-sessions-with-incomplete-child-catalog-evidence/alternatives-considered: + en: b7ce0d1b6b280d7f + zh: 3deeaef73a3a7856 +/agent-note-preserve-v3-sessions-with-incomplete-child-catalog-evidence/consequences: + en: 9f8b6446f6cdea60 + zh: d0a07674bf8434c4 diff --git a/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.i18n.yaml index 802ab740bd..270547a0cb 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-20-session-open-read-coordination.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.md -2026-09-20-session-open-read-coordination.md: a4907df1d7dd38e4c532c38fb6ff10362a4a3898 -2026-09-20-session-open-read-coordination.zh.md: 759a45d8c52a62ea7a0b30ceed4003f8804a42c3 +/agent-note-session-opening-cache-identity-and-read-ordering: + en: 1ea618d07f8d8f28 + zh: 25332949ef7af87e +/agent-note-session-opening-cache-identity-and-read-ordering/problem: + en: 490984caf5af4323 + zh: 273ac6284e1ff67f +/agent-note-session-opening-cache-identity-and-read-ordering/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-session-opening-cache-identity-and-read-ordering/decision/identify-the-cache-producer-with-a-service-owned-symbol: + en: 56bec761deb63aad + zh: 8b16c2b7582aeb3f +/agent-note-session-opening-cache-identity-and-read-ordering/decision/auxiliary-rpcs-wait-for-the-current-conversation-s-initial-open-to-succeed: + en: 3a09e82c1fb032e4 + zh: c1ef33b75ab0e734 +/agent-note-session-opening-cache-identity-and-read-ordering/decision/conversations-use-follow-catalog-branches-retain-explicit-reads: + en: 181653d75354df80 + zh: 7984321c5a2715d5 +/agent-note-session-opening-cache-identity-and-read-ordering/implementation-scope: + en: f3e37b63e2e813e3 + zh: 1c709bd0ee6cc3ff +/agent-note-session-opening-cache-identity-and-read-ordering/alternatives-considered: + en: 7d64c8151ffef2a0 + zh: b899a22f4d070a78 +/agent-note-session-opening-cache-identity-and-read-ordering/consequences: + en: 51a45af1622d7e4d + zh: f33fecfa0f889af7 +/agent-note-session-opening-cache-identity-and-read-ordering/verification-and-known-gaps: + en: 13437882143e2025 + zh: 586bcd68eaa03969 +/agent-note-session-opening-cache-identity-and-read-ordering/relationship-to-existing-records: + en: 8b479aee5c808180 + zh: aa0220e664f9e9a6 diff --git a/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.md b/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.md index a4907df1d7..c00f8fa7a3 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.md +++ b/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.md @@ -51,7 +51,7 @@ A known address does not waive authorization checks. When opening child history, - Session formats, migrations, the Host observation's `all | none` policy, and the response fields of `session.projections` are unchanged. - There is no global cold-read singleflight, and Agent lookups are not universally replaced with read-only lookups. - `SessionManager.handleConnected()` still refreshes previously requested catalogs in bulk; this decision does not guarantee one cold read on reconnect. -- Tool-side `listDescendants` can still read child Sessions on cache misses, and expanding a child node in the Client can still cold-read that node. Ordinary main-session opening is not equivalent to every descendant-enumeration scenario. +- Tool-side `listDescendants` observes each reachable child catalog. An observation can reuse live state or a valid prepared Session; otherwise it reads the cold log. Expanding a child node in the Client can also cold-read that node. Ordinary main-session opening is not equivalent to every descendant-enumeration scenario. - `@` Session candidates still enumerate headers and obtain names from live projections or projection caches, falling back to ids on misses. Existing ranking, the default limit of 50, and direct-subagent grouping remain unchanged; discovery does not recursively traverse `subagentCatalog`. ## Alternatives considered diff --git a/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.zh.md b/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.zh.md index 759a45d8c5..ce9eac01db 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.zh.md +++ b/.agents/notes/implemented/bug-fix/2026-09-20-session-open-read-coordination.zh.md @@ -51,7 +51,7 @@ Skill 保留共享目录请求自己的取消信号;`@` 查询将当前候选 - 没有修改 Session 格式、迁移、Host observation 的 `all | none` 策略或 `session.projections` 返回字段。 - 没有实现全局 cold-read singleflight,也没有把所有 Agent lookup 改成只读 lookup。 - 没有删除 `SessionManager.handleConnected()` 对此前请求目录的批量刷新;本决策不保证重连只有一次冷读。 -- 工具侧 `listDescendants` 的缓存缺失仍可能读取子会话;前端展开一个子节点也仍可能冷读该节点。普通主会话首开不等于所有后代枚举场景。 +- 工具侧 `listDescendants` 观察每个可达子级目录。观察可以复用实时状态或有效的 prepared Session,否则会读取冷日志。前端展开子节点也可能冷读该节点。普通主会话首开不等于所有后代枚举场景。 - `@` 会话候选仍枚举 header,并从 live projection 或 projection cache 取名称;缓存缺失回退到 id。原有排序、默认 50 条上限和直接 subagent 分组规则不变,没有改成沿 `subagentCatalog` 递归发现。 ## 考虑过的替代方案 diff --git a/.agents/notes/implemented/bug-fix/2026-09-20-windows-embedded-mandatory-update.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-20-windows-embedded-mandatory-update.i18n.yaml index 259202f1a0..48e79b967c 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-20-windows-embedded-mandatory-update.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-20-windows-embedded-mandatory-update.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-20-windows-embedded-mandatory-update.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-20-windows-embedded-mandatory-update.md -2026-09-20-windows-embedded-mandatory-update.md: 99577a4d85adc3fe13ea0ae262d5aa1af6128237 -2026-09-20-windows-embedded-mandatory-update.zh.md: abe4a9577d8e11d8de2089dc53ef07433e10bbdb +/agent-note-windows-embedded-mandatory-update: + en: fb52005dc1f55b5d + zh: dda7e46555da6d03 +/agent-note-windows-embedded-mandatory-update/problem: + en: df8f2127905913d7 + zh: 64d27253ce39e031 +/agent-note-windows-embedded-mandatory-update/decision: + en: f238482836ae80da + zh: df856cba1b715056 +/agent-note-windows-embedded-mandatory-update/alternatives-considered: + en: 9564f979909f0743 + zh: 6730e42a123b707a +/agent-note-windows-embedded-mandatory-update/consequences: + en: 64cd6585a98f01cd + zh: 8bca9eb88aa55d8e diff --git a/.agents/notes/implemented/bug-fix/2026-09-21-multimodal-tool-result-retention.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-21-multimodal-tool-result-retention.i18n.yaml index 78d945e72c..82aabefd0d 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-21-multimodal-tool-result-retention.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-21-multimodal-tool-result-retention.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-21-multimodal-tool-result-retention.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-21-multimodal-tool-result-retention.md -2026-09-21-multimodal-tool-result-retention.md: 41470724911d3086878d206f82c76ad9a4993146 -2026-09-21-multimodal-tool-result-retention.zh.md: 8e6d4953f7380d45235ac13f9f245e2e005f1abf +/agent-note-multimodal-tool-result-retention: + en: aa04c4148785f8ca + zh: b08c44c8484ea5d2 +/agent-note-multimodal-tool-result-retention/problem: + en: 9e8765ea40441f36 + zh: 3ca2616499d3c9fc +/agent-note-multimodal-tool-result-retention/decision: + en: a65eeedad585fc4b + zh: 82aae7ef0148282b +/agent-note-multimodal-tool-result-retention/alternatives-considered: + en: c670e96a46c93540 + zh: efccc4d3423e5ac0 +/agent-note-multimodal-tool-result-retention/consequences: + en: 7fdf51600bb0ffd7 + zh: 0ad7f06887b1c859 diff --git a/.agents/notes/implemented/bug-fix/2026-09-21-persistent-pwsh-keeps-controlled-prompt.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-21-persistent-pwsh-keeps-controlled-prompt.i18n.yaml index 4f16b7775b..48e34b2079 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-21-persistent-pwsh-keeps-controlled-prompt.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-21-persistent-pwsh-keeps-controlled-prompt.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-21-persistent-pwsh-keeps-controlled-prompt.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-21-persistent-pwsh-keeps-controlled-prompt.md -2026-09-21-persistent-pwsh-keeps-controlled-prompt.md: 3fd42b77d4536215f34c32643526dbb03d21674f -2026-09-21-persistent-pwsh-keeps-controlled-prompt.zh.md: 88d4e2deef26af4ad92ef4a69d8ae17403027f70 +/agent-note-persistent-pwsh-keeps-the-backend-s-controlled-prompt: + en: 78c6e7e3340581dc + zh: 64e16ab608caa610 +/agent-note-persistent-pwsh-keeps-the-backend-s-controlled-prompt/problem: + en: 0cd51c293e96d9eb + zh: 6eb89ee3f1b7a851 +/agent-note-persistent-pwsh-keeps-the-backend-s-controlled-prompt/decision: + en: edd5cbb51ddad62f + zh: d7c41f09a9453992 +/agent-note-persistent-pwsh-keeps-the-backend-s-controlled-prompt/alternatives-considered: + en: a3920fa51dd5ac79 + zh: 29c3f8364f64115e +/agent-note-persistent-pwsh-keeps-the-backend-s-controlled-prompt/consequences: + en: d43b72fb5aa0c6da + zh: c4c9a27d5c7c6338 diff --git a/.agents/notes/implemented/bug-fix/2026-09-22-chat-scroll-follow-and-footer-geometry.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-22-chat-scroll-follow-and-footer-geometry.i18n.yaml index ceb40894c4..e10cbc61b1 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-22-chat-scroll-follow-and-footer-geometry.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-22-chat-scroll-follow-and-footer-geometry.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-22-chat-scroll-follow-and-footer-geometry.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-22-chat-scroll-follow-and-footer-geometry.md -2026-09-22-chat-scroll-follow-and-footer-geometry.md: 56cd1681eef23162df2595a138545ade25e34212 -2026-09-22-chat-scroll-follow-and-footer-geometry.zh.md: 9979688d52373ae7a64a3f4fc22b932b43091b34 +/agent-note-separate-chat-clipping-and-independent-follow-intent: + en: a95aae5eecac228c + zh: 01b7df574c3d010f +/agent-note-separate-chat-clipping-and-independent-follow-intent/problem: + en: 8e4310ee05cf535c + zh: bd57ba36ebe8c201 +/agent-note-separate-chat-clipping-and-independent-follow-intent/decision: + en: afe3cf3bb5a92039 + zh: bb11f9f4bcd8f329 +/agent-note-separate-chat-clipping-and-independent-follow-intent/alternatives-considered: + en: 014e7974ce1cadae + zh: 63c1743c598413e4 +/agent-note-separate-chat-clipping-and-independent-follow-intent/verification: + en: 235dc4e251fa8124 + zh: 2c08ab5e14213b54 +/agent-note-separate-chat-clipping-and-independent-follow-intent/consequences: + en: aa1367b399806ab7 + zh: f98a8b416d9a70c8 diff --git a/.agents/notes/implemented/bug-fix/2026-09-22-input-echo-admission-ownership.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-22-input-echo-admission-ownership.i18n.yaml index 6ba4b3a015..6f58c8d30c 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-22-input-echo-admission-ownership.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-22-input-echo-admission-ownership.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-22-input-echo-admission-ownership.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-22-input-echo-admission-ownership.md -2026-09-22-input-echo-admission-ownership.md: 227857bd8168aa1d7f51b621737c2ed0ab572632 -2026-09-22-input-echo-admission-ownership.zh.md: 1d64de220a3c6d5c9357770175c79266b8f9f063 +/agent-note-input-echoes-retain-display-ownership-through-admission: + en: 987905631fdf4244 + zh: 2b2a1db249903717 +/agent-note-input-echoes-retain-display-ownership-through-admission/problem: + en: a56f673056a7d913 + zh: a06acdb9f3e1afd3 +/agent-note-input-echoes-retain-display-ownership-through-admission/decision: + en: b570ae20a428f554 + zh: b3cf1ebc56fbe78c +/agent-note-input-echoes-retain-display-ownership-through-admission/alternatives-considered: + en: 9ee59841301a61f4 + zh: 7ad35e485294dce1 +/agent-note-input-echoes-retain-display-ownership-through-admission/verification: + en: a1373e299a536929 + zh: 13405143c3bb9331 +/agent-note-input-echoes-retain-display-ownership-through-admission/consequences: + en: 027d6bae744c47e0 + zh: c9f397bc631298b9 diff --git a/.agents/notes/implemented/bug-fix/2026-09-22-windows-open-through-shell-resolution.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-22-windows-open-through-shell-resolution.i18n.yaml index 420cb47036..3a1ef4f137 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-22-windows-open-through-shell-resolution.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-22-windows-open-through-shell-resolution.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-22-windows-open-through-shell-resolution.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-22-windows-open-through-shell-resolution.md -2026-09-22-windows-open-through-shell-resolution.md: 7bfe559e7f26b96fa37d3bbed44f0403d4e51b59 -2026-09-22-windows-open-through-shell-resolution.zh.md: ff33455da1653f9d24f9ddcc21c1594e8875bb5e +/agent-note-windows-opens-go-through-explorer-exe: + en: 315c5e87180365ba + zh: 4bc29f09bb3900d3 +/agent-note-windows-opens-go-through-explorer-exe/problem: + en: bc2c92e4247ea71e + zh: ca20fdeccc58e883 +/agent-note-windows-opens-go-through-explorer-exe/decision: + en: 4cf76bcb52a7beef + zh: a55a5bd9a4b85063 +/agent-note-windows-opens-go-through-explorer-exe/alternatives-considered: + en: 64712f720fca44a1 + zh: aad98e46f0c7a6bb +/agent-note-windows-opens-go-through-explorer-exe/consequences: + en: d06af93b608037c9 + zh: 38b1a4c840b0ce51 +/agent-note-windows-opens-go-through-explorer-exe/verification: + en: c7ff7cb42072737c + zh: 9bbf5ff6596938a0 diff --git a/.agents/notes/implemented/bug-fix/2026-09-23-bounded-pnpm-runs.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-23-bounded-pnpm-runs.i18n.yaml index 727ff382c0..1978750d50 100644 --- a/.agents/notes/implemented/bug-fix/2026-09-23-bounded-pnpm-runs.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-09-23-bounded-pnpm-runs.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-23-bounded-pnpm-runs.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-23-bounded-pnpm-runs.md -2026-09-23-bounded-pnpm-runs.md: 7ce6b1776e4587240072201781c9da5bc78650e8 -2026-09-23-bounded-pnpm-runs.zh.md: 1cb91132cca22a1130fdc48ce3d3dbd354fa5d16 +/agent-note-bounding-a-pnpm-run-that-stops-progressing: + en: c2bd52dec2a41d84 + zh: 80dae83761a09a60 +/agent-note-bounding-a-pnpm-run-that-stops-progressing/problem: + en: 227a287fe7127eae + zh: 5d7eae54a4a75f8c +/agent-note-bounding-a-pnpm-run-that-stops-progressing/decision: + en: 6a574e5b6d536b5b + zh: 92a9bb15d983e7db +/agent-note-bounding-a-pnpm-run-that-stops-progressing/why-a-silence-bound-rather-than-a-duration-bound: + en: 31287e4e71e7f10f + zh: ff57c96539d51972 +/agent-note-bounding-a-pnpm-run-that-stops-progressing/alternatives-considered: + en: 125710ae84911ed4 + zh: 5f35dbcda4447bea +/agent-note-bounding-a-pnpm-run-that-stops-progressing/testing: + en: eb3c4907aec48db3 + zh: 56b7168b732c782a +/agent-note-bounding-a-pnpm-run-that-stops-progressing/related: + en: a9c6d0a071ea9834 + zh: 0702183c645d03b9 +/agent-note-bounding-a-pnpm-run-that-stops-progressing/consequences: + en: c13a64cd3dd381e9 + zh: 83d2db47153e3d8c diff --git a/.agents/notes/implemented/bug-fix/2026-09-24-exited-holder-lock-takeover.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-09-24-exited-holder-lock-takeover.i18n.yaml new file mode 100644 index 0000000000..ad4ccdf4ab --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-24-exited-holder-lock-takeover.i18n.yaml @@ -0,0 +1,22 @@ +# Bilingual-pair consistency record for 2026-09-24-exited-holder-lock-takeover.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-24-exited-holder-lock-takeover.md +/agent-note-taking-over-a-writer-lock-whose-holder-exited: + en: ecf6fb35c9eed3ca + zh: 59c29b64e23608e4 +/agent-note-taking-over-a-writer-lock-whose-holder-exited/problem: + en: cf143bc56530fe17 + zh: a4e3ee8fa3b8c465 +/agent-note-taking-over-a-writer-lock-whose-holder-exited/decision: + en: af22bae72ff97ef8 + zh: 428c09871bba95d1 +/agent-note-taking-over-a-writer-lock-whose-holder-exited/alternatives-considered: + en: ee800ed269cfc4a2 + zh: df983b552ef25273 +/agent-note-taking-over-a-writer-lock-whose-holder-exited/testing: + en: 7eb7c5818049415a + zh: f84c39c55bb3bc5a +/agent-note-taking-over-a-writer-lock-whose-holder-exited/consequences: + en: 03f4cda9290188e5 + zh: 07f800776c061218 diff --git a/.agents/notes/implemented/bug-fix/2026-09-24-exited-holder-lock-takeover.md b/.agents/notes/implemented/bug-fix/2026-09-24-exited-holder-lock-takeover.md new file mode 100644 index 0000000000..dd42c5cae3 --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-24-exited-holder-lock-takeover.md @@ -0,0 +1,51 @@ +# Agent Note: Taking over a writer lock whose holder exited + +Status: implemented + +English | [中文](2026-09-24-exited-holder-lock-takeover.zh.md) + +## Problem + +`withFileLock` in [dsh-atomic-write](../../../../packages/util/atomic-write/README.md) creates `.lock` with exclusive create and removes it in a `finally`. A process that ends without running that `finally` leaves the lock behind, and every later writer of the file times out until someone deletes it by hand. The [original decision](../../archived/architecture/2026-07-30-settings-write-path-integrity.md) accepted this because file age cannot distinguish a crashed holder from a paused one. + +The profile package lock (`/package.json.lock`) made the cost visible. `dsh plugin` installs no signal handler, so Ctrl-C, SIGTERM, or closing its terminal ends the process while pnpm runs, and the lock stays. `dsh` and `dsh web` exit right after application disposal resolves, while a cancelled installation is still restoring files and has not released the lock. A crash, SIGKILL, or out-of-memory kill has the same effect. After any of these, every plugin operation on that profile fails after `lockWaitMs` (two minutes by default) without saying that the holder is gone. + +## Decision + +- The lock keeps the `\n` record earlier releases wrote, so locks left before this change are taken over and processes of both releases interoperate. +- A contender that finds a lock reads its record. When a signal probe of the PID fails with `ESRCH`, the holder is proven gone and the lock is taken over. `EPERM` means the process exists under another user and the lock is kept. A record naming the contender's own process is kept too: that process is running, and the browser Worker's process shim reports its own PID as absent. +- Contenders that read the same record serialize on a claim file, `.lock.takeover-`, created with `wx`. The claimant re-reads the lock and probes its PID again, removes it only if it still holds that record and the PID is still absent, removes the claim, and retries acquisition at once. The record's holder cannot release it once its PID is absent, another takeover needs the same claim, and a new holder that reused the PID fails the second probe, so a claimant never removes a lock that another contender acquired after the exited holder's. +- A record that is empty, incomplete, not a decimal PID, or names PID 0 or a PID beyond the int32 range the probe accepts is waited for. None of these proves that the holder stopped. +- Takeover proves only that the recorded process exited, not that the processes it started stopped writing. The [Plugin Manager](../../../../packages/boot/plugin-manager/README.md) records each pnpm run in `.plugin-manager/run.json` while the run lasts; an operation that finds that record waits up to five seconds for the recorded run to stop and otherwise refuses to run, naming the process and the record. +- The probe runs on the contender's host. Writers on several hosts sharing one `DSH_HOME` over a network filesystem are unsupported; the `flock` that guards Session files does not reliably exclude them either. + +## Alternatives considered + +**Remove a lock older than a fixed age.** Age cannot separate a crashed holder from one running a ten-minute pnpm installation, and the plugin manager legitimately holds the lock that long. + +**Kernel-released locks.** The kernel releases them when the holder dies, which removes the problem instead of detecting it. The [Session write lease](../../../../packages/session/session-persistence-jsonl/src/lease.ts) already holds one on both platforms: `flock` through `@deepseek-ai/node-addon-system` on POSIX and a named semaphore through `koffi` on Windows. Moving `withFileLock` onto it would give the zero-dependency `dsh-atomic-write` both dependencies, and processes of earlier releases still exclude each other only through `.lock`, so a transition would have to hold both locks. This stays the stronger fix if PID reuse or shared-filesystem deployments turn out to matter. + +**Rename the stale lock aside and restore it when the renamed record differs.** Restoring can race a third contender that acquires the empty path in between, which leaves two holders. The claim file prevents that race without restoring anything. + +**Record the hostname and a nonce.** A hostname would keep a writer on another host from probing a PID that is not its own, but no supported deployment shares these files across hosts, and macOS changes its hostname when networks change, which would leave locks from before the change in place. A nonce would make each record unique, but the second probe under the claim already rejects a holder that reused the PID. + +**Terminate the recorded pnpm run instead of refusing.** Its PID can have been reused by an unrelated process, which a signal would then kill. Refusing leaves that case to the operator, whom the diagnostic names the process and the record. + +**Signal handlers in `dsh plugin` only.** This covers one of the paths that leave a lock and leaves crashes, forced exits, and the other lock files behind. + +## Testing + +| Evidence | Behaviour | +|---|---| +| [atomic-write.spec.ts](../../../../packages/util/atomic-write/tests/atomic-write.spec.ts) | Takeover of an exited holder's record, through an injected probe everywhere and a really exited process on POSIX; eight contenders over one exited holder never overlap; live, own-process, other-user, empty, incomplete, non-PID, process-group, and out-of-range records are waited for; a holder that reused the PID after the claim, an unreadable lock, a claim held by another contender, and a record replaced after the claim are left in place; a lock that cannot be removed is waited for; an `EPERM` claim refusal is retried, another claim failure surfaces, and a claim that cannot be removed does not fail the operation. | +| [operations.spec.ts](../../../../packages/boot/plugin-manager/tests/operations.spec.ts) | CLI, service, and repair runs are recorded while they run and the record is removed afterwards; an active recorded run refuses the operation before pnpm starts; a stopped one's record is removed; a record that names no run refuses the operation. | +| [operations-process.spec.ts](../../../../packages/boot/plugin-manager/tests/operations-process.spec.ts) | A real recorded run that is still writing finishes before the next operation's pnpm starts. | + +## Consequences + +- Locks left by an exited process, including those written before this change, no longer need an operator; the next writer proceeds without waiting for its deadline. +- A PID that a live process reused after a reboot keeps the lock in place until an operator removes it, as before. +- Processes that share the lock file but not a PID namespace, such as containers over one volume or hosts over a network filesystem, can see a live holder as exited. Such deployments are not supported. +- A contender that crashes while it holds a claim leaves that claim, and the named lock is then not taken over automatically. +- A pnpm run left by an exited operation blocks later operations until it stops or an operator removes its record. +- A holder that is still alive keeps its lock, so this does not bound how long a live operation holds it. diff --git a/.agents/notes/implemented/bug-fix/2026-09-24-exited-holder-lock-takeover.zh.md b/.agents/notes/implemented/bug-fix/2026-09-24-exited-holder-lock-takeover.zh.md new file mode 100644 index 0000000000..59162daa65 --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-09-24-exited-holder-lock-takeover.zh.md @@ -0,0 +1,51 @@ +# Agent Note: 接管持有者已退出的写锁 + +Status: implemented + +[English](2026-09-24-exited-holder-lock-takeover.md) | 中文 + +## 问题 + +[dsh-atomic-write](../../../../packages/util/atomic-write/README.zh.md) 的 `withFileLock` 以独占创建方式创建 `.lock`,并在 `finally` 中移除它。进程若未执行该 `finally` 就结束,锁会留在原地,该文件后续的每个写入方都会超时,直到有人手动删除它。[原始决策](../../archived/architecture/2026-07-30-settings-write-path-integrity.md)接受了这一点,因为文件存续时间无法区分已崩溃的持有者与暂停的持有者。 + +profile 包锁(`/package.json.lock`)让这个代价显现出来。`dsh plugin` 不安装信号处理器,因此在 pnpm 运行期间按 Ctrl-C、发送 SIGTERM 或关闭其终端都会结束进程,锁随之留下。`dsh` 与 `dsh web` 在应用销毁完成后立即退出,而此时被取消的安装仍在恢复文件,尚未释放锁。崩溃、SIGKILL 或内存不足被杀也有同样效果。发生上述任一情况后,该 profile 上的每个插件操作都会在 `lockWaitMs`(默认两分钟)后失败,且不说明持有者已不存在。 + +## 决策 + +- 锁沿用早期版本写入的 `\n` 记录,因此本变更之前遗留的锁也会被接管,新旧版本的进程可以互操作。 +- 竞争者发现锁时读取其记录。若对该 PID 的信号探测以 `ESRCH` 失败,则证明持有者已不存在,锁会被接管。`EPERM` 表示该进程以其他用户身份存在,锁保留。指向竞争者自身进程的记录同样保留:该进程正在运行,而浏览器 Worker 的进程模拟层会把自身 PID 报告为不存在。 +- 读到同一条记录的竞争者通过一个以 `wx` 创建的认领文件 `.lock.takeover-<记录 SHA-256 的前 16 位十六进制>` 串行化。认领者重新读取锁并再次探测其 PID,仅当锁仍是该记录且该 PID 仍不存在时才移除它,随后移除认领文件并立即重试获取。PID 不存在时记录的持有者无法再释放它,另一次接管需要同一个认领文件,复用了该 PID 的新持有者无法通过第二次探测,因此认领者绝不会移除另一个竞争者在已退出持有者之后获得的锁。 +- 记录为空、不完整、不是十进制 PID,或指向 PID 0 或超出探测所接受的 int32 范围的 PID 时,竞争者继续等待。这些情况都无法证明持有者已经停止。 +- 接管只能证明记录中的进程已退出,不能证明它启动的进程已停止写入。[Plugin Manager](../../../../packages/boot/plugin-manager/README.zh.md) 在每次 pnpm 运行期间把它记录在 `.plugin-manager/run.json` 中;发现该记录的操作最多等待五秒让记录中的运行停止,否则拒绝运行,并指明该进程与记录文件。 +- 探测在竞争者所在主机上进行。不支持多台主机通过网络文件系统共享同一个 `DSH_HOME` 写入;保护 Session 文件的 `flock` 同样无法可靠地排除它们。 + +## 考虑过的替代方案 + +**移除超过固定时长的锁。** 时长无法区分已崩溃的持有者与正在运行十分钟 pnpm 安装的持有者,而插件管理器会合理地持锁这么久。 + +**由内核释放的锁。** 持有者死亡时内核会释放它们,从根源上消除问题而不是检测它。[Session 写租约](../../../../packages/session/session-persistence-jsonl/src/lease.ts)已在两个平台上持有这种锁:POSIX 上通过 `@deepseek-ai/node-addon-system` 使用 `flock`,Windows 上通过 `koffi` 使用命名信号量。把 `withFileLock` 迁移到它上面,会让零依赖的 `dsh-atomic-write` 引入这两个依赖;而早期版本的进程之间只通过 `.lock` 互斥,因此过渡期必须同时持有两种锁。若 PID 复用或共享文件系统部署变得重要,这仍是更强的修复。 + +**把陈旧锁重命名到别处,若重命名后的记录不同再恢复。** 恢复可能与在此间隙获取空路径的第三个竞争者竞态,导致出现两个持有者。认领文件无需任何恢复即可防止这一竞态。 + +**记录主机名和随机数。** 主机名能让其他主机上的写入方不去探测不属于自己的 PID,但没有受支持的部署会跨主机共享这些文件,而且 macOS 切换网络时会改变主机名,导致变更前留下的锁无法接管。随机数能让每条记录唯一,但认领后的第二次探测已经能排除复用了该 PID 的持有者。 + +**终止记录中的 pnpm 运行而不是拒绝。** 其 PID 可能已被无关进程复用,发送信号会杀死该进程。拒绝则把这种情况交给操作者,诊断会指明该进程与记录文件。 + +**只在 `dsh plugin` 中安装信号处理器。** 这只覆盖留下锁的其中一条路径,崩溃、强制退出和其他锁文件仍会遗留。 + +## 验证 + +| 证据 | 行为 | +|---|---| +| [atomic-write.spec.ts](../../../../packages/util/atomic-write/tests/atomic-write.spec.ts) | 接管已退出持有者的记录,各平台通过注入的探测验证,POSIX 上另用真实已退出的进程验证;八个竞争者同时接管一个已退出持有者时从不重叠;存活、自身进程、其他用户、空、不完整、非 PID、进程组和超出范围的记录均继续等待;认领后复用了该 PID 的持有者、无法读取的锁、被另一竞争者持有的认领、认领后被替换的记录都保留原样;无法移除的锁会继续等待;以 `EPERM` 拒绝的认领会重试,其他认领失败会抛出,认领无法移除时操作不失败。 | +| [operations.spec.ts](../../../../packages/boot/plugin-manager/tests/operations.spec.ts) | CLI、service 与修复运行在运行期间被记录,结束后删除记录;仍活动的记录中运行会在 pnpm 启动前拒绝操作;已停止运行的记录被删除;不指向任何运行的记录会拒绝操作。 | +| [operations-process.spec.ts](../../../../packages/boot/plugin-manager/tests/operations-process.spec.ts) | 仍在写入的真实记录中运行会在下一个操作的 pnpm 启动前结束。 | + +## 后果 + +- 已退出进程留下的锁(包括本变更之前留下的)不再需要操作者处理;下一个写入方无需等到期限即可继续。 +- 重启后被存活进程复用的 PID 会让锁保持原样,直到操作者移除,与之前相同。 +- 共享锁文件但不共享 PID 命名空间的进程,例如共享同一卷的容器或通过网络文件系统共享的多台主机,可能把存活持有者视为已退出。不支持此类部署。 +- 竞争者在持有认领文件时崩溃会留下该认领文件,对应的锁随后不会被自动接管。 +- 已退出操作留下的 pnpm 运行会阻止后续操作,直到它停止或操作者删除其记录。 +- 仍存活的持有者会保留其锁,因此本变更不限制存活操作的持锁时长。 diff --git a/.agents/notes/implemented/feature/2026-06-15-ptc.i18n.yaml b/.agents/notes/implemented/feature/2026-06-15-ptc.i18n.yaml index bf097e40c1..c85af1bf90 100644 --- a/.agents/notes/implemented/feature/2026-06-15-ptc.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-06-15-ptc.i18n.yaml @@ -1,6 +1,49 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-15-ptc.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-06-15-ptc.md -2026-06-15-ptc.md: 220f8d27fa912fe708be251e04947cf6e1a46239 -2026-06-15-ptc.zh.md: e244d0173e3734ebe00c07f5362da0662310dd8d +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry: + en: 9506116227b22bd0 + zh: c2d42a9f483cfbe3 +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/problem: + en: 4b312be894531bee + zh: d655648ea5843ef5 +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/decision: + en: 371abc68ce278a5c + zh: 3fa8d28213794932 +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/decision/per-program-execution-controls: + en: da694641e1d009de + zh: 9d7492d39039af66 +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/decision/the-registry-owns-the-mode: + en: 55287fedeaaee6d8 + zh: d2afe242e84acc43 +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/decision/the-run-code-tool-and-the-dispatch-bridge: + en: 8811a9c5e28488fd + zh: 6937645281b79fb9 +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/decision/observability-tool-ptc-dispatch: + en: b8e4cf9433c7ee18 + zh: e5f4e8d7d03d3a7b +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/decision/the-ptc-runtime-seam: + en: 4c423f4e9cef6055 + zh: 5c23a3637eb420c0 +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/decision/the-node-process-runtime: + en: 0b846ed33977e383 + zh: e45158758d657f9a +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/decision/trust-posture: + en: d62b41a6a5c58e5f + zh: ef72c5a9b32b370e +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/decision/what-the-model-sees: + en: 43653fd91ab9165b + zh: 6ddfa853e69b2d80 +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/consequences: + en: 761eb6c1aeb7af18 + zh: 5434456a3d0a1b65 +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/testing: + en: a8bd8cbe4b344fb8 + zh: 82ba8b452fae7f4d +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/alternatives-considered: + en: 90110f91f6f6130f + zh: 25d28433840f91a4 +/agent-note-ptc-mode-the-model-writes-typescript-against-the-tool-registry/risks: + en: 7743b1b621b8e6c7 + zh: 70c33a5b306ca71c diff --git a/.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.i18n.yaml b/.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.i18n.yaml index 4e2bd8d28d..4b48c194fe 100644 --- a/.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.i18n.yaml @@ -1,6 +1,52 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-18-compaction-capability-seam.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.md -2026-06-18-compaction-capability-seam.md: 7d8b4f5011385f306aec4c6374d3402427fb3cc4 -2026-06-18-compaction-capability-seam.zh.md: 6a255bb05e0b3c90077af051bd24744305f3833e +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend: + en: 6808ccbe73762daa + zh: 11f3669e6ae4512c +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/problem: + en: ed3fddc1dce0f229 + zh: fab2663b344cd851 +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/decision/compaction-is-a-capability-seam-with-separate-service-definition-and-service-provider-roles: + en: 785c69730accbb4d + zh: ee9bd2a8a7dc3b72 +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/decision/the-contract-depends-on-dsh-session-and-dsh-llm-a-deliberate-deviation: + en: 5c07a5a6429f6752 + zh: 8bf83da6e0563a66 +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/decision/three-abstract-operations-algorithm-in-the-backend: + en: 62191e0e65c79673 + zh: cbaa5bece0f5b45a +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/decision/automatic-pressure-runs-after-successful-durable-step-work: + en: b246f9837c9c9a6b + zh: c19c51456c8fd8b7 +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/decision/retention-is-turn-agnostic-tool-pairing-balance-is-the-only-structural-guard: + en: 3126c249c48e90b9 + zh: dc82bc9a37d90474 +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/decision/head-anchoring-one-auto-checkpoint-always-at-the-head: + en: 26f187b321217e4c + zh: b324dcdb6da4bf02 +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/decision/approximate-convergence-invariant: + en: 4870032f23833fc4 + zh: b30180c31ba84a5a +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/decision/surface-replacement-compaction-events-are-log-only-one-user-message-carries-the-summary: + en: 6d50dfe66a35f6fb + zh: 6ff9e66553f10ac6 +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/decision/checkpoint-framing-incremental-merge-backend-private: + en: 1c71cf67450e78d5 + zh: fb44b3cf5cee070a +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/decision/blocking-via-a-log-recorded-lock-plus-a-crash-recoverable-failure-taxonomy: + en: 5aed57a49e031b1e + zh: 1424f332197ef541 +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/alternatives-considered: + en: 24a7bb1949445136 + zh: 7914ea99f498ed67 +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/consequences: + en: 400bf1cadb974d04 + zh: 7612a4634ae98b32 +/agent-note-compaction-as-a-capability-seam-abstract-contract-basic-backend/testing: + en: 843476bd607fe832 + zh: 50be0b06553a54d0 diff --git a/.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.i18n.yaml b/.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.i18n.yaml index 1445f54bbb..2362f9cac7 100644 --- a/.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.i18n.yaml @@ -1,6 +1,46 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-21-subagent-capability-seam.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.md -2026-06-21-subagent-capability-seam.md: 6eedb3a4b03cd919aa8888853fac5fdaf3f74fe0 -2026-06-21-subagent-capability-seam.zh.md: 7e73fdc58f4b537ca2f6be481e359b267af31d96 +/agent-note-subagent-capability-seam: + en: 3c051f92759dd9c4 + zh: fceee1b8289f2779 +/agent-note-subagent-capability-seam/problem: + en: 5c81597e6dc16c39 + zh: c30c6b5dce12bfae +/agent-note-subagent-capability-seam/alternatives-considered: + en: 6119e2aff3b6be5a + zh: 76136ef5249c23eb +/agent-note-subagent-capability-seam/alternatives-considered/why-not-the-bash-seam-shape: + en: 3a01c98c45de8585 + zh: 7f87d8bd6d348dae +/agent-note-subagent-capability-seam/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-subagent-capability-seam/decision/the-three-package-boundary: + en: c470cd9518cebc8b + zh: 228b559f73c58f2b +/agent-note-subagent-capability-seam/decision/the-primitive-async-start-subagentrun: + en: 08250dc4d5faf918 + zh: 1b413cb438af6796 +/agent-note-subagent-capability-seam/decision/two-kinds-of-optional-capability-discovered-two-ways: + en: d2a27fcacc46ca76 + zh: 4e8cca931fcaec2c +/agent-note-subagent-capability-seam/decision/fork-vs-fresh-are-separate-backends-not-a-flag: + en: a8e071639738ea79 + zh: 3fd7cc7427843efe +/agent-note-subagent-capability-seam/decision/child-isolation-and-the-parent-log: + en: e970f97f27d11f4a + zh: 34ece0dfe5ec6185 +/agent-note-subagent-capability-seam/decision/synchronous-collect-first-cut: + en: a14200a7abfa532f + zh: ee4f8c08deb0ee99 +/agent-note-subagent-capability-seam/decision/transport-provider-selection-is-config-not-model-facing: + en: 3dab95ec93f918df + zh: 4c3c7d4e8357bf63 +/agent-note-subagent-capability-seam/testing: + en: 324951447c43d01a + zh: b04388c4665302d2 +/agent-note-subagent-capability-seam/consequences: + en: c60d3fb1012f52b4 + zh: f46ab4b214941622 diff --git a/.agents/notes/implemented/feature/2026-06-30-interception-extension-points.i18n.yaml b/.agents/notes/implemented/feature/2026-06-30-interception-extension-points.i18n.yaml index 8ed643d29b..b5de0ccbcd 100644 --- a/.agents/notes/implemented/feature/2026-06-30-interception-extension-points.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-06-30-interception-extension-points.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-30-interception-extension-points.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-06-30-interception-extension-points.md -2026-06-30-interception-extension-points.md: 5adffd1679c97cc69cf18991913113b84d88ba3c -2026-06-30-interception-extension-points.zh.md: c3aa374a22d58c5185a3bd8e79b4040a04bd43e3 +/agent-note-interception-extension-points-the-typed-decision-surface-a-hook-programs-against: + en: 623ca9ecb3ed4c8e + zh: 5d5639dea9a6a541 +/agent-note-interception-extension-points-the-typed-decision-surface-a-hook-programs-against/problem: + en: 7ce5525628f7fc7d + zh: 53f27e5423da86f8 +/agent-note-interception-extension-points-the-typed-decision-surface-a-hook-programs-against/decision: + en: dc7daa9100978a8b + zh: c87aa08a4e085b7b +/agent-note-interception-extension-points-the-typed-decision-surface-a-hook-programs-against/decision/the-tool-pipeline-gives-each-phase-one-kind-of-authority: + en: 65553dedec611132 + zh: 5b002349db90b83f +/agent-note-interception-extension-points-the-typed-decision-surface-a-hook-programs-against/decision/three-load-bearing-loop-decisions: + en: d91bda956aa8bad9 + zh: 12bc8f819bf62ed2 +/agent-note-interception-extension-points-the-typed-decision-surface-a-hook-programs-against/decision/pre-tool-input-rewrite-is-a-separate-consistency-decision: + en: bea1cab63d0470f1 + zh: b3a1dba46e346109 +/agent-note-interception-extension-points-the-typed-decision-surface-a-hook-programs-against/decision/boundaries: + en: 30c23a1087faca81 + zh: 03d58723ee6b1a37 +/agent-note-interception-extension-points-the-typed-decision-surface-a-hook-programs-against/alternatives-considered: + en: d05468299caa114d + zh: d0b0eecf36456130 +/agent-note-interception-extension-points-the-typed-decision-surface-a-hook-programs-against/consequences: + en: 830c7bab979652be + zh: 7266e2d0780e9d67 diff --git a/.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.i18n.yaml b/.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.i18n.yaml index 8fe72e240d..b70097f9c9 100644 --- a/.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-05-dynamic-workflows.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-05-dynamic-workflows.md -2026-07-05-dynamic-workflows.md: c7245704b0734c1508fe7f001e6429f594ebdd1d -2026-07-05-dynamic-workflows.zh.md: a4502d7d6b3acf1aebc4a5b36caccf50859bab01 +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam: + en: 472dec484bf937c1 + zh: 1d6c38c699d43828 +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam/problem: + en: e890f8ac24054d94 + zh: 45ec14140f62e1c9 +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam/decision: + en: 16af14c0c9fc54ee + zh: 463dd56b53d05ea7 +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam/decision/the-script-contract-claude-code-compatible: + en: 889beb90c3650f25 + zh: b1ba5dac3c77f8d2 +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam/decision/the-seam-dsh-workflow: + en: d37f01afb4d9cd6a + zh: 5648b981b61e6624 +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam/decision/the-engine-dsh-workflow-ptc-shared-node-process-execution: + en: 7567d5fcf218e4b5 + zh: 2ba33b1237df9e4a +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam/decision/the-consumer-dsh-tool-workflow: + en: 00b015ee9db948fb + zh: 6dac8d8aaf0b32d2 +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam/decision/the-foundation-structured-output-on-the-subagent-seam: + en: 40ad0d1f23ffa7db + zh: 23a81a277fb24cd9 +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam/testing: + en: a1607694b584dcbc + zh: 29c9c7560f0fcf56 +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam/deferred-documented-non-goals: + en: 2bff807d808bfa13 + zh: add602509c0a826c +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam/alternatives-considered: + en: 44a36cb0a91546cc + zh: f4ed8c49f3764d7a +/agent-note-dynamic-workflows-a-script-driven-multi-agent-orchestration-seam/consequences: + en: bfd2d827ffb20587 + zh: 310c4fe77f48aa4e diff --git a/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml b/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml index f3eb596443..07e39db02d 100644 --- a/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml @@ -1,6 +1,55 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-06-approval-seam.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-06-approval-seam.md -2026-07-06-approval-seam.md: 03a4269dd7712f88d73e0439f944e6bf5bce14b5 -2026-07-06-approval-seam.zh.md: f11e0956c90cd60c9e34c7ccdee62111b5653545 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers: + en: 5a500ddf8910f3b2 + zh: 0461f97e3c905d72 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/problem: + en: 0903931cf3fd2d9b + zh: ae39e774ffa66c36 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/decision: + en: 058d4bd95d3c55d3 + zh: a861c6a59340b121 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/decision/how-a-deployment-uses-it: + en: d0bcdfb988eaeadc + zh: 5ce6fd8f89b503fc +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/decision/design-detail: + en: a6d7884e4359af3a + zh: e72588705942000a +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/decision/design-detail/the-seam-mechanism-and-policy-split: + en: 53da7800d8744d9e + zh: 316fef884853ca5d +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/decision/design-detail/ask-routing-in-dsh-tools: + en: 1d4478059f608fd2 + zh: 4a1d12e4ccb766b5 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/decision/design-detail/the-per-session-policy-tier: + en: 4eaf3ae10290dc6a + zh: 0cb65c79a5e9effc +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/decision/design-detail/the-acp-answerer: + en: bbfb8c3f1cb34b12 + zh: 4f8f51a027a09a03 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/decision/design-detail/audit-and-what-the-model-sees: + en: d9f129e893e76bec + zh: 92929dbc54c65a5b +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/decision/design-detail/entities-and-dependencies: + en: 08abe894f74bcb00 + zh: a94052662c8536c7 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/decision/testing: + en: 01356985c175fcda + zh: b1bb3b68f619e698 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/deferred: + en: 3a9a1ddf86364f14 + zh: ec8413e23f171bd2 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/alternatives-considered: + en: ae974b0f43a29b4e + zh: bbc4662c0c63b6c1 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/consequences: + en: 9d2097d7b796dd63 + zh: 4f1a0493dc109b12 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/faq: + en: 85f3a8270d96497d + zh: b97bedebc08f23f0 +/agent-note-the-approval-seam-one-shot-permission-decisions-over-a-waterfall-of-answerers/prior-art: + en: 964a5c6afd4724d6 + zh: 1a386e1376860105 diff --git a/.agents/notes/implemented/feature/2026-07-06-approval-seam.md b/.agents/notes/implemented/feature/2026-07-06-approval-seam.md index 03a4269dd7..bb44957b6d 100644 --- a/.agents/notes/implemented/feature/2026-07-06-approval-seam.md +++ b/.agents/notes/implemented/feature/2026-07-06-approval-seam.md @@ -55,7 +55,7 @@ After validation and a successful `approval/asked` append, the service resolves Answerers are `approval/request` waterfall listeners. Zero listeners fall through to `unavailable`; a recognizing listener occupies the first-wins decision slot, while an unrecognized agent must delegate with `next()`. Listeners dispose with their fibers, so an unloaded channel fails closed. Because sibling registration order is not deterministic, a deployment composes one terminal answerer and reserves `prepend` for decide-or-delegate gates. -`ApprovalRequest` carries the asking `agent`, `toolName`, optional exact `callId`, human-readable `reason`, and optional `signal`. It uses the `ToolCallId` brand without importing `dsh-tools`, which depends on this seam. Channel adapters correlate any richer call state by `callId`; the approval request does not duplicate tool arguments. +`ApprovalRequest` carries the asking `agent`, `toolName`, optional exact `callId`, human-readable `reason`, optional localized `displayReason`, and optional `signal`. It uses the `ToolCallId` brand without importing `dsh-tools`, which depends on this seam. Channel adapters correlate any richer call state by `callId`; the approval request does not duplicate tool arguments. #### Ask routing in dsh-tools diff --git a/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md b/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md index f11e0956c9..b7e07a376c 100644 --- a/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md +++ b/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md @@ -55,7 +55,7 @@ tool/result "escalated" — this one call ran under the wider mode; the gra 应答者是 `approval/request` waterfall 监听器。零监听器会直接落到 `unavailable`;识别该 agent 的监听器占用先到先得的决策槽,而不识别的监听器必须调用 `next()` 委派。监听器会随其 fiber 一同 dispose(资源释放),因此卸载通道后,请求会在故障时默认被拒绝。由于兄弟插件的注册顺序不确定,部署应组合一个终端应答者,并保留 `prepend` 给「决策或委派」门禁。 -`ApprovalRequest` 携带发起请求的 `agent`、`toolName`、可选的精确 `callId`、人类可读的 `reason` 和可选的 `signal`。它使用 `ToolCallId` brand 而不导入依赖本 seam 的 `dsh-tools`。通道适配器可按 `callId` 关联任何更丰富的调用状态;审批请求本身不重复携带工具参数。 +`ApprovalRequest` 携带发起请求的 `agent`、`toolName`、可选的精确 `callId`、人类可读的 `reason`、可选的本地化 `displayReason` 和可选的 `signal`。它使用 `ToolCallId` brand 而不导入依赖本 seam 的 `dsh-tools`。通道适配器可按 `callId` 关联任何更丰富的调用状态;审批请求本身不重复携带工具参数。 #### dsh-tools 中的 Ask 路由 diff --git a/.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml b/.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml index 0c0d28aa76..e29631633c 100644 --- a/.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml @@ -1,6 +1,61 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-06-sandbox.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-06-sandbox.md -2026-07-06-sandbox.md: f2c703ba67bc16529605250d35ed181412f05494 -2026-07-06-sandbox.zh.md: ff4d4ed592dc4235903555528a029b4b295d972e +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes: + en: b36f59d0746e94f1 + zh: 0d0f8e19917a9eae +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/problem: + en: 045e61bb682755dc + zh: ac95eb64ce892f8d +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision: + en: f4748553d52935ff + zh: 1802a543c6d989ef +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision/how-a-deployment-uses-it: + en: 956a2c069b1ac0b1 + zh: ebf91494b8107ced +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision/design-detail: + en: a6d7884e4359af3a + zh: e72588705942000a +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision/design-detail/scope-grounding: + en: 0c09534b59e2063e + zh: 5225d6750d13b9d7 +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision/design-detail/the-seam-ctx-sandbox: + en: 2c98e8c0bd8a9ff1 + zh: 661b58f81f6e05c6 +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision/design-detail/local-backends-and-the-shipped-launcher: + en: 5c6bf38f958b07d0 + zh: 22bf9fac71eb643d +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision/design-detail/asynchronous-preparation: + en: 7bc0fab85c7c91d0 + zh: 3eafcde6b1e3249c +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision/design-detail/the-bash-consumer: + en: f7f359c89a0e8fd6 + zh: 07d0d551a35716e0 +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision/design-detail/escalation-one-approved-wider-retry-after-a-denial: + en: 035640e276225e97 + zh: 09fd95921529369b +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision/design-detail/per-session-modes-the-session-log-as-the-store: + en: 6805c807f584961c + zh: 687fd4ad687e4dee +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision/design-detail/in-process-tools: + en: 73cd47df9f2acbd0 + zh: 877db86c2a36a9ab +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/decision/testing: + en: c0189d491354eb48 + zh: ac68b07188402f9c +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/deferred-phases: + en: f28b530000b8495e + zh: f256b8b32c4ce4ef +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/alternatives-considered: + en: eabe577b837f3de2 + zh: 4ef0167c895766a6 +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/consequences: + en: c0d8279a677a0ef1 + zh: 3518fc05f8700c0b +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/faq: + en: de45c2a398b8abe6 + zh: 93be112960b40736 +/agent-note-the-subprocess-sandbox-confinement-seam-native-runners-escalation-and-per-session-modes/prior-art: + en: a51744b1cafca339 + zh: 1d27f49f1aa550af diff --git a/.agents/notes/implemented/feature/2026-07-06-sandbox.md b/.agents/notes/implemented/feature/2026-07-06-sandbox.md index f2c703ba67..1f8ca60c83 100644 --- a/.agents/notes/implemented/feature/2026-07-06-sandbox.md +++ b/.agents/notes/implemented/feature/2026-07-06-sandbox.md @@ -78,7 +78,7 @@ Provider-owned I/O requires asynchronous confinement. `confine(argv, policy, sig `dsh-bash-sandbox` extends `LocalBashExecutor`, awaits `ctx.sandbox` for the exact `['bash', '-c', command]` argv with the execution signal, rechecks cancellation, and directly spawns the provider result. This leaves shell semantics and `BASH_ENV` on the inner Bash after the shipped native runner establishes confinement. A provider error propagates unchanged. An asynchronous rejection counts as a runner failure only when the caller-owned workdir is independently usable and Node reports `ENOENT` or `EACCES` with either an `error.path` equal to provider argv[0] or, when `error.path` is absent, an exact `syscall: 'spawn '`; a present path also requires `syscall: 'spawn'` or the exact `spawn `. Other codes, invalid workdirs, resource failures, unrelated syscalls, and unstructured rejections retain stage-neutral provider-failure semantics. Foreground execution converts attributable runner failures to `SANDBOX_UNAVAILABLE` with the original detail; an attributable asynchronous background rejection stamps `runnerFailed: true`, `denied: false`. A `SubprocessRuntime` that synchronously throws the same runner-identifying shape makes background start reject with `SANDBOX_UNAVAILABLE` before handle publication, while other synchronous errors propagate unchanged. After a direct outcome exists, foreground and background use one runner-failure classifier that requires the rule's exit-code check and a remaining fatal line after informational exclusions. A match takes priority over denial: foreground execution throws `SANDBOX_UNAVAILABLE` with that fatal line as detail; a settled `ShellProcess` stamps `sandbox.runnerFailed`, and the bash producer renders it through generic `job_output`. -The model sees the current effective file policy in the owner-derived `sandbox:policy` context, while the static tool description explains the denial marker (`[sandbox: file access denied under mode]`), encourages attempting commands that may be denied, and forbids retrying around a denial; when the escalation fields are advertised, a denied result additionally carries the escalation hint itself, so the sanctioned same-turn retry is prompted at the decision point rather than depending on the model recalling the description (§ Escalation). [The current-policy decision](../../archived/feature/2026-07-30-current-sandbox-policy-context.md) owns the context's rationale and boundaries. +The model sees the current effective file policy in the owner-derived `sandbox:policy` context, while the static tool description explains the denial marker (`[sandbox: file access denied under mode]`) and forbids retrying around a denial, and the `sandbox:policy` context tells the model to try an available tool normally; a rejected escalation's error text says the action stays denied; when the escalation fields are advertised, a denied result additionally carries the escalation hint itself, so the sanctioned same-turn retry is prompted at the decision point rather than depending on the model recalling the description (§ Escalation). [The current-policy decision](../../archived/feature/2026-07-30-current-sandbox-policy-context.md) owns the context's rationale and boundaries. #### Escalation: one approved wider retry after a denial diff --git a/.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md b/.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md index ff4d4ed592..707a576e97 100644 --- a/.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md +++ b/.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md @@ -78,7 +78,7 @@ Landlock launcher 源码和包家族位于 `native/system`,与 harness 消费 `dsh-bash-sandbox` 扩展 `LocalBashExecutor`,携带执行信号等待 `ctx.sandbox` 为精确的 `['bash', '-c', command]` argv 完成限制准备,重新检查取消后直接 spawn 提供方返回的 argv。这样,随附的原生 runner 建立约束后,shell 语义与 `BASH_ENV` 仍由内层 Bash 处理。提供方错误原样传播。异步 rejection 只有在调用方拥有的 workdir 经独立验证可用,Node 报告 `ENOENT` 或 `EACCES`,并且错误符合以下一种形态时,才判定为 runner 失败:`error.path` 等于提供方返回的 `argv[0]`,同时 `syscall` 为 `'spawn'` 或精确的 `'spawn '`;或者 `error.path` 不存在,同时 `syscall` 为精确的 `'spawn '`。其他错误码、无效 workdir、资源失败、无关 syscall 与无结构 rejection 保留不声明阶段的 provider-failure 语义。前台执行会将可归因的 runner failure 转为 `SANDBOX_UNAVAILABLE` 并附上原始详情;可归因的异步后台 rejection 则盖章 `runnerFailed: true`、`denied: false`。如果 `SubprocessRuntime` 同步抛出同样能指明 runner 的形态,后台启动会在发布句柄前以 `SANDBOX_UNAVAILABLE` 拒绝;其他同步错误原样传播。direct outcome 已存在后,前台与后台共用一个 runner failure 分类器:先排除信息性行,再要求规则的退出码检查与余下的一行致命诊断同时匹配。匹配结果优先于拒绝:前台执行抛出 `SANDBOX_UNAVAILABLE`,并以该致命行作为详情;结算后的 `ShellProcess` 会盖章 `sandbox.runnerFailed`,bash 生产者再通过通用 `job_output` 渲染它。 -模型会在归属方派生的 `sandbox:policy` 上下文中看到当前有效的文件策略;静态工具描述则解释拒绝标记(`[sandbox: file access denied under mode]`),鼓励尝试可能被拒绝的命令,并禁止绕过拒绝重试。当升级字段被公布时,被拒绝的结果还会携带升级提示本身,使被认可的同轮次重试在决策点获得提示,而非依赖模型回忆描述(§ 升级机制)。[当前策略决策](../../archived/feature/2026-07-30-current-sandbox-policy-context.md)负责该上下文的理由与边界。 +模型会在归属方派生的 `sandbox:policy` 上下文中看到当前有效的文件策略;静态工具描述则解释拒绝标记(`[sandbox: file access denied under mode]`)并禁止绕过拒绝重试,`sandbox:policy` 上下文要求模型正常尝试可用工具;被拒绝的升级请求的错误文本说明该操作仍被拒绝。当升级字段被公布时,被拒绝的结果还会携带升级提示本身,使被认可的同轮次重试在决策点获得提示,而非依赖模型回忆描述(§ 升级机制)。[当前策略决策](../../archived/feature/2026-07-30-current-sandbox-policy-context.md)负责该上下文的理由与边界。 #### 升级机制:拒绝后一次经批准的更宽重试 diff --git a/.agents/notes/implemented/feature/2026-07-07-mcp-client-plugin.i18n.yaml b/.agents/notes/implemented/feature/2026-07-07-mcp-client-plugin.i18n.yaml index 2d9a9b05e4..751b41f4c6 100644 --- a/.agents/notes/implemented/feature/2026-07-07-mcp-client-plugin.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-07-mcp-client-plugin.i18n.yaml @@ -1,6 +1,94 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-07-mcp-client-plugin.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-07-mcp-client-plugin.md -2026-07-07-mcp-client-plugin.md: dd793b67bf2043fa88377d50837df40faadf3fbf -2026-07-07-mcp-client-plugin.zh.md: 5056118df0185f1e7ec2b1ea06818ed920d2af26 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools: + en: 7d41e632fd40efe0 + zh: 4c7f6410b74a5bd3 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/problem: + en: 7cef5ed5bc88fba5 + zh: 795917e3321148ab +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/package: + en: 90a6e5a22fa99a36 + zh: 4280a5feecd3e6c1 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/sdk: + en: f69bbd1cfca85fa0 + zh: 9b21abc7e3eeb2fd +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/scope: + en: 32cd57e8d3ea1ac1 + zh: 7c14401492f22c32 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/plugin-shape: + en: 3d6e4726e5c890a6 + zh: 888123ed412544a7 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/configuration: + en: a244e4d7a8294424 + zh: 4be5ed51345a660e +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/lifecycle: + en: b428a4e72dec4ba0 + zh: c070db6fdd2d3c7f +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/tool-discovery-and-registration: + en: 75da266ca8141a90 + zh: 078e3a969273ed9b +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/public-name-normalization: + en: eb0511bd6173c99c + zh: c5fc98231a733699 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/name-conflict-handling: + en: 88210585c857f934 + zh: fc0d90d572d6ba45 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/naming-invariants: + en: 1e2ce84605977339 + zh: 3b3c9d120c0262a7 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/tool-execution: + en: c82db842e7a6f3db + zh: ace9e266cd6c4203 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/subprocess-environment-stdio-transport: + en: d599a7db35e1f96d + zh: a2655e0410565c93 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/decision/disconnection-crash: + en: e8207a70c6511778 + zh: aa281be51d85be13 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered: + en: 6119e2aff3b6be5a + zh: 76136ef5249c23eb +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered/mcp-server-side-expose-harness-tools-to-external-mcp-clients: + en: 831148b7e748eaa3 + zh: 845172ccc64d7a65 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered/capability-seam-three-package-split-interface-impl-consumer: + en: caefc1146f9b2b16 + zh: 9c4a5d55019d8002 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered/auto-reconnect-with-exponential-backoff: + en: e92d18530feb1ee3 + zh: 2fecc50b4b6a96d9 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered/bridge-resources-and-prompts: + en: 606ee33502fa60cc + zh: 0c21afec01caf4c2 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered/raw-model-facing-tool-names-with-an-optional-toolprefix: + en: ef886d275ac5734c + zh: 304c578e674f50a2 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered/server-only-namespace-github-create-issue-no-mcp-marker: + en: d18be656bd334d18 + zh: b7cdc2d580e9f2ab +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered/deriving-the-namespace-from-the-server-announced-serverinfo-name: + en: 17bc5d831e3d06a7 + zh: 6b9e2f5cd76d12f8 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered/preserve-multiple-textblocks-in-tool-result: + en: 184f6d75be815400 + zh: a284afac1e2b80e2 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered/replace-the-canonical-mcp-result-with-core-contentblock: + en: d5d253f8e466bab9 + zh: 7d93b7fa1c2219ed +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered/add-a-generic-richcontent-service-or-perform-i-o-in-output-render: + en: 687c220df3767635 + zh: c87dd8700edc9291 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/alternatives-considered/let-each-image-returning-tool-special-case-ptc-mode-parents: + en: a5fc7b17970699ce + zh: 2d7bd23621f62597 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/testing: + en: 4bb5be21c1097a57 + zh: d12bf01bb70e1bc3 +/agent-note-mcp-client-plugin-connect-to-external-mcp-servers-and-bridge-their-tools/consequences: + en: ef35ec18568b38e5 + zh: ca85076585c2b787 diff --git a/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.i18n.yaml b/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.i18n.yaml index 2b37bdad0a..67063fa1b4 100644 --- a/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-08-self-referential-cordis-toolset.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md -2026-07-08-self-referential-cordis-toolset.md: 278c71051de1fb897c8735b39dff0b66c43a5626 -2026-07-08-self-referential-cordis-toolset.zh.md: 8a8e197e197fb6b53b52426d5ad9a33fd09e78c9 +/agent-note-cordis-runtime-inspection-and-runner-isolation: + en: d96c123d1989b22b + zh: 4a53cdd763955f19 +/agent-note-cordis-runtime-inspection-and-runner-isolation/problem: + en: 29d1465c348331e9 + zh: 25dbc885f5d7ee7d +/agent-note-cordis-runtime-inspection-and-runner-isolation/decision: + en: 8a4cbb660f2409d7 + zh: 2219e39468e6baee +/agent-note-cordis-runtime-inspection-and-runner-isolation/alternatives-considered: + en: 637137a3b035c211 + zh: 5a667bfe2446a5f8 +/agent-note-cordis-runtime-inspection-and-runner-isolation/consequences: + en: a21f854954e01db6 + zh: c16bbe7c3580b394 diff --git a/.agents/notes/implemented/feature/2026-07-10-parallel-tool-call-execution.i18n.yaml b/.agents/notes/implemented/feature/2026-07-10-parallel-tool-call-execution.i18n.yaml index f317a3d223..4b82a34a31 100644 --- a/.agents/notes/implemented/feature/2026-07-10-parallel-tool-call-execution.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-10-parallel-tool-call-execution.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-10-parallel-tool-call-execution.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-10-parallel-tool-call-execution.md -2026-07-10-parallel-tool-call-execution.md: d5d26e03a2081569a8dba4de966201abc312d420 -2026-07-10-parallel-tool-call-execution.zh.md: 707428985c872dcbbc82f59124f0d60aef7f1090 +/agent-note-parallel-tool-call-execution-by-per-call-safety: + en: bbc8567dc50716d1 + zh: 4ddef348cc74b39c +/agent-note-parallel-tool-call-execution-by-per-call-safety/problem: + en: 41ffece5e72e022f + zh: e813a3efb9c12646 +/agent-note-parallel-tool-call-execution-by-per-call-safety/decision: + en: 532bb7268d9b93ce + zh: ad47162233222ab0 +/agent-note-parallel-tool-call-execution-by-per-call-safety/scheduling-and-ordering: + en: f0906d03fef98e7b + zh: f9e43c4c832c9a05 +/agent-note-parallel-tool-call-execution-by-per-call-safety/safety-contract: + en: 16c4ee08b65ead23 + zh: df80d6e49982615b +/agent-note-parallel-tool-call-execution-by-per-call-safety/configuration-and-declarations: + en: e112957ed8a48039 + zh: 37d63f9ea4968fb2 +/agent-note-parallel-tool-call-execution-by-per-call-safety/verification: + en: eb5a6aa84980f0ab + zh: eed2680a160e8ed2 +/agent-note-parallel-tool-call-execution-by-per-call-safety/alternatives-considered: + en: 44f8fb5851ba4e39 + zh: 4d75c937ac5277f7 +/agent-note-parallel-tool-call-execution-by-per-call-safety/consequences: + en: 5e5b2a1c7d850f83 + zh: b63311f28eb69366 diff --git a/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.i18n.yaml b/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.i18n.yaml index 13820af392..431d5f60ec 100644 --- a/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-12-subagent-persona-tool-filter-and-depth.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md -2026-07-12-subagent-persona-tool-filter-and-depth.md: f848b92a7a5647995330e2bf26796dde1b43a3f8 -2026-07-12-subagent-persona-tool-filter-and-depth.zh.md: 3360b27c9feb5950cc3f338c89e48a4c902e2ac8 +/agent-note-configure-subagent-persona-tool-visibility-and-depth: + en: ea51f1e98afc88b7 + zh: 6aa0101b8de5097f +/agent-note-configure-subagent-persona-tool-visibility-and-depth/problem: + en: 311bc04b9c36ab53 + zh: 0c52e6493e9350a5 +/agent-note-configure-subagent-persona-tool-visibility-and-depth/decision: + en: 79b3fcfaaaaccf9e + zh: 0287bfb41c7b9707 +/agent-note-configure-subagent-persona-tool-visibility-and-depth/decision/persona-is-a-scoped-shadow: + en: 8b299c99d26aa5c3 + zh: 6956efbd236cef8e +/agent-note-configure-subagent-persona-tool-visibility-and-depth/decision/tool-filtering-is-one-live-global-view-rule: + en: a9fe46283ea28722 + zh: 7b7d1be7c070b893 +/agent-note-configure-subagent-persona-tool-visibility-and-depth/decision/depth-is-an-absolute-tree-cap: + en: 9145bec4e3f7eb5b + zh: 986276925cb064d9 +/agent-note-configure-subagent-persona-tool-visibility-and-depth/decision/capability-gating-keeps-providers-honest: + en: 5334afafefdb0f59 + zh: 7e96c9a08bbc3d1a +/agent-note-configure-subagent-persona-tool-visibility-and-depth/decision/unpublished-setup-makes-the-first-request-correct: + en: 3c988dfff07c8da3 + zh: 8ce2fbcc438e7dd8 +/agent-note-configure-subagent-persona-tool-visibility-and-depth/visibility-is-not-authority: + en: d0db5310a87ff8e4 + zh: 4b9f502238cd4bae +/agent-note-configure-subagent-persona-tool-visibility-and-depth/alternatives-considered: + en: 78ae41331d8fcc3e + zh: a93ee10b3e30c267 +/agent-note-configure-subagent-persona-tool-visibility-and-depth/consequences: + en: d5f05d63b7a01dd8 + zh: f0be1e88b06d8cc9 diff --git a/.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.i18n.yaml b/.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.i18n.yaml index 021837de21..938869414c 100644 --- a/.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-14-cross-family-fs-sandbox.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.md -2026-07-14-cross-family-fs-sandbox.md: 0fe1d4078797eceb9f3f0f9c319bba62acd6b08c -2026-07-14-cross-family-fs-sandbox.zh.md: 021923c7e3c4653991377cd9b5bccf18c9a4bf65 +/agent-note-cross-family-file-sandbox-one-policy-home-a-sandboxed-fs-provider-and-fs-escalation-parity: + en: d971839c319030fa + zh: 29d8cc0ec85337af +/agent-note-cross-family-file-sandbox-one-policy-home-a-sandboxed-fs-provider-and-fs-escalation-parity/problem: + en: 2ce70b520caa28b5 + zh: 6f023332dd48bf83 +/agent-note-cross-family-file-sandbox-one-policy-home-a-sandboxed-fs-provider-and-fs-escalation-parity/decision: + en: dd825d09d6d850ed + zh: 0c355b56ff17d099 +/agent-note-cross-family-file-sandbox-one-policy-home-a-sandboxed-fs-provider-and-fs-escalation-parity/decision/ctx-sandboxpolicy-one-home-for-mode-and-workspace-root: + en: e8ef62a480614c1a + zh: 90c29f6845e2f437 +/agent-note-cross-family-file-sandbox-one-policy-home-a-sandboxed-fs-provider-and-fs-escalation-parity/decision/dsh-fs-sandbox-enforcement-inside-the-provider: + en: 077a767b86dd7860 + zh: e8797afed2f65fa6 +/agent-note-cross-family-file-sandbox-one-policy-home-a-sandboxed-fs-provider-and-fs-escalation-parity/decision/tool-parity-one-denial-marker-one-escalation-flow: + en: f1fed3aaf3a1482c + zh: d4bc7989477b3a0b +/agent-note-cross-family-file-sandbox-one-policy-home-a-sandboxed-fs-provider-and-fs-escalation-parity/decision/the-enforcement-point-provider-not-intent-gate: + en: 98549276110ac457 + zh: d680c26086c68a8c +/agent-note-cross-family-file-sandbox-one-policy-home-a-sandboxed-fs-provider-and-fs-escalation-parity/decision/out-of-scope: + en: 9157891a477f17bd + zh: 58d926d0b86bc4fd +/agent-note-cross-family-file-sandbox-one-policy-home-a-sandboxed-fs-provider-and-fs-escalation-parity/alternatives-considered: + en: 669431ca494a7783 + zh: e875a63c553135e1 +/agent-note-cross-family-file-sandbox-one-policy-home-a-sandboxed-fs-provider-and-fs-escalation-parity/consequences: + en: 3848066c5a8c56ef + zh: 048cdf6cb8dbde4d +/agent-note-cross-family-file-sandbox-one-policy-home-a-sandboxed-fs-provider-and-fs-escalation-parity/testing: + en: dc226f5a587ff7d4 + zh: 55f5d937d6bc86e9 diff --git a/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.i18n.yaml b/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.i18n.yaml index 550d23413e..624d9c4025 100644 --- a/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.i18n.yaml @@ -1,6 +1,46 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-16-harness-level-loop.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-16-harness-level-loop.md -2026-07-16-harness-level-loop.md: 54adc1aad63e8968c9e0d276a075cd42abf021fd -2026-07-16-harness-level-loop.zh.md: 9e1a7e73fbf1fab1807b59b3b7816cdfcc6f45df +/agent-note-harness-level-goal-based-execution: + en: 20d103f4160b124d + zh: 36e888ebeec1d366 +/agent-note-harness-level-goal-based-execution/problem: + en: b0294f40b8915f39 + zh: 786bcecd8e0df343 +/agent-note-harness-level-goal-based-execution/decision: + en: f9d2e5774bca2d5b + zh: 375683705a21f16c +/agent-note-harness-level-goal-based-execution/decision/vocabulary-and-policy-boundary: + en: 213a55ec1ef4dd58 + zh: 56076b8524188153 +/agent-note-harness-level-goal-based-execution/decision/package-topology-and-owning-verbs: + en: fb8e9df7705a2293 + zh: ffe7040bdad4fa64 +/agent-note-harness-level-goal-based-execution/decision/durable-goal-state-and-live-authority: + en: ef386ad58ff3bcaf + zh: 9517886000faf515 +/agent-note-harness-level-goal-based-execution/decision/same-session-continuation: + en: 669447319e89b06a + zh: 2a08e6a8622aabd1 +/agent-note-harness-level-goal-based-execution/decision/human-and-model-interactions: + en: 8923f16b40a2f331 + zh: 697417b21f475c1e +/agent-note-harness-level-goal-based-execution/decision/fresh-agent-ralph-execution: + en: 3cc9d8fee8dfbd41 + zh: 2c4bf8aab739b0e8 +/agent-note-harness-level-goal-based-execution/decision/external-design-lineage: + en: 4a7b290a2649720c + zh: 1a2f32667061e7b4 +/agent-note-harness-level-goal-based-execution/decision/verification: + en: cb538a23eb170008 + zh: fdd00c5ca70918a1 +/agent-note-harness-level-goal-based-execution/alternatives-considered: + en: 5f4c2ba58601587c + zh: a7e2028dd8bc23c1 +/agent-note-harness-level-goal-based-execution/consequences: + en: 31d109628ee650f4 + zh: 2278dd884e6a088a +/agent-note-harness-level-goal-based-execution/known-limitations-and-deferred-work: + en: 2bc0e7709c516ed0 + zh: 614b4ddf8ca6ebc6 diff --git a/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.i18n.yaml b/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.i18n.yaml index b1b7365597..ac9be41f4d 100644 --- a/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.i18n.yaml @@ -1,6 +1,49 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-16-persistent-pty-sessions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md -2026-07-16-persistent-pty-sessions.md: d62587ced78be75de121fe907ca258d07a2830a1 -2026-07-16-persistent-pty-sessions.zh.md: a26c3ed852b3a18842585e19ecb2a6994f8d9117 +/agent-note-persistent-pty-sessions: + en: c7796dc579fe7fb3 + zh: 2126be0b08124ca5 +/agent-note-persistent-pty-sessions/problem: + en: cd408e9b6e9705e8 + zh: 7811f9216b6961fa +/agent-note-persistent-pty-sessions/decision: + en: 5656c117648160c8 + zh: 7f7c3de8e2ea6d9a +/agent-note-persistent-pty-sessions/decision/package-topology: + en: 0187ac573d06a360 + zh: 13e08f4f22bacfff +/agent-note-persistent-pty-sessions/decision/agent-ownership-and-identity: + en: 9bf79081f102eb51 + zh: 34855888f0614b47 +/agent-note-persistent-pty-sessions/decision/security-and-process-boundary: + en: 10d84442483e1d40 + zh: c970ae058e2e0f6d +/agent-note-persistent-pty-sessions/decision/six-model-facing-tools: + en: b92715f36550c728 + zh: e18d7e0e2363347a +/agent-note-persistent-pty-sessions/decision/local-readiness-detection: + en: cd8b4032a624c277 + zh: 47f0d8c15f1c9cad +/agent-note-persistent-pty-sessions/decision/model-visible-output-and-durability: + en: 1b504ab41b47216d + zh: 8fb3d360b3a4e6a1 +/agent-note-persistent-pty-sessions/decision/process-tree-teardown: + en: e96a972845bc3513 + zh: d76d7dfb80985e9d +/agent-note-persistent-pty-sessions/decision/composition-and-rollout: + en: db49b6dff73d8772 + zh: 1f2182fd2c7dc3af +/agent-note-persistent-pty-sessions/decision/deferred-work: + en: c0ae6d86dd5c0635 + zh: 737bd3fda903d5e3 +/agent-note-persistent-pty-sessions/alternatives-considered: + en: cda0998b2bb05b7d + zh: 7cc5683a6dfd64be +/agent-note-persistent-pty-sessions/verification: + en: 08cd5f0369ee69e9 + zh: 3e9b13ba1f8b6bff +/agent-note-persistent-pty-sessions/consequences: + en: f8784b2ca03fc80a + zh: e20e38014292f86a diff --git a/.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.i18n.yaml b/.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.i18n.yaml index 3a30f6624d..c67f4a0d57 100644 --- a/.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-model-facing-goal-tools.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.md -2026-07-19-model-facing-goal-tools.md: 2c05c8aa0ee2caecb0264fa87984085b3df5d785 -2026-07-19-model-facing-goal-tools.zh.md: f16055e52e4a3d6a4db423699a36929f6f8c4cd2 +/agent-note-model-facing-same-session-goal-tools: + en: 4d9b039620654dd6 + zh: e8703b6a1723f910 +/agent-note-model-facing-same-session-goal-tools/problem: + en: f8e860155bfc0b43 + zh: 3279c90b622e8c08 +/agent-note-model-facing-same-session-goal-tools/decision: + en: 0ab1e1c40cb2dac9 + zh: b4180b6681c130b2 +/agent-note-model-facing-same-session-goal-tools/decision/tools-and-model-contract: + en: 288a819f644611c9 + zh: d6bd7986ba091519 +/agent-note-model-facing-same-session-goal-tools/decision/execution-authority: + en: 63a9e7e85303b9f1 + zh: d3f1d0c225103cfe +/agent-note-model-facing-same-session-goal-tools/decision/blocking-threshold: + en: 398de9518db40d11 + zh: b7f36c4061ca7e78 +/agent-note-model-facing-same-session-goal-tools/testing: + en: 92650dd6648ca455 + zh: 5b57276a6a983fea +/agent-note-model-facing-same-session-goal-tools/alternatives-considered: + en: e84b9fc4823bcc1e + zh: a125628e4746bf50 +/agent-note-model-facing-same-session-goal-tools/consequences: + en: e254571a176b37e5 + zh: 01f76aff35e3618d +/agent-note-model-facing-same-session-goal-tools/known-limitations-and-deferred-work: + en: 5b043a930afd4a13 + zh: d91e8a61de2590a4 diff --git a/.agents/notes/implemented/feature/2026-07-19-persisted-same-session-goal-domain.i18n.yaml b/.agents/notes/implemented/feature/2026-07-19-persisted-same-session-goal-domain.i18n.yaml index 62b98a691a..722d00ad1a 100644 --- a/.agents/notes/implemented/feature/2026-07-19-persisted-same-session-goal-domain.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-19-persisted-same-session-goal-domain.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-persisted-same-session-goal-domain.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-19-persisted-same-session-goal-domain.md -2026-07-19-persisted-same-session-goal-domain.md: 4ddc02c3bd3b7bbf04b3c6867a76673431309460 -2026-07-19-persisted-same-session-goal-domain.zh.md: 2bb937b0f637e54ab6d9a6e10ebe237849e08171 +/agent-note-persisted-same-session-goal-domain: + en: 05f6641270399579 + zh: 962259d5bd3b3e16 +/agent-note-persisted-same-session-goal-domain/problem: + en: 45e351264fabe761 + zh: 6513999a7d83a528 +/agent-note-persisted-same-session-goal-domain/decision: + en: 7efc52c6215aa755 + zh: e570a4f82e69300b +/agent-note-persisted-same-session-goal-domain/decision/durable-record-and-replay: + en: d4520ec456f4023a + zh: 2ffcb155955539e5 +/agent-note-persisted-same-session-goal-domain/decision/lifecycle-and-live-activation: + en: d68c058ff7a49fee + zh: cbcdbce1aade7758 +/agent-note-persisted-same-session-goal-domain/decision/service-boundary: + en: 0bff035a2664e7c0 + zh: ba303bd3ec64151b +/agent-note-persisted-same-session-goal-domain/testing: + en: 9fb97674d1dd45ac + zh: c56df41a9aa6767a +/agent-note-persisted-same-session-goal-domain/alternatives-considered: + en: b8bae793bb1c922d + zh: 4abb28a01b1fc7f3 +/agent-note-persisted-same-session-goal-domain/consequences: + en: fa46d172b9d01b52 + zh: 54c40631d1719624 +/agent-note-persisted-same-session-goal-domain/known-limitations-and-deferred-work: + en: 21f5c50b4eafa028 + zh: 4cad975fb10501bd diff --git a/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.i18n.yaml b/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.i18n.yaml index 8a975fd9bd..a8a8205207 100644 --- a/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-plugin-command-registration.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md -2026-07-19-plugin-command-registration.md: f5033c6ac52dd09371d67ba5b54f0aa2cdba8024 -2026-07-19-plugin-command-registration.zh.md: 55f3a58f0e1f4c1ee6dfd7105e968a1a466f7806 +/agent-note-plugin-owned-human-command-registration: + en: f1509f79bd9e2445 + zh: 30f62b9b4f611f9d +/agent-note-plugin-owned-human-command-registration/problem: + en: 628dcc0bda181677 + zh: 71b110588f89c2b4 +/agent-note-plugin-owned-human-command-registration/decision: + en: acf2742722ab7c85 + zh: e0bdbd6fd0bf51b1 +/agent-note-plugin-owned-human-command-registration/decision/registry-contract: + en: 1b3daffaa9a8b56e + zh: fa99bb6bc553cafb +/agent-note-plugin-owned-human-command-registration/decision/scope-and-lifecycle: + en: 6d55a0d4b1b9606a + zh: 34bf959ef332630f +/agent-note-plugin-owned-human-command-registration/decision/direct-dispatch-and-cancellation: + en: 074ee61a689493cb + zh: 580035e2a4c82d4f +/agent-note-plugin-owned-human-command-registration/decision/tui-mapping: + en: 00f0f8b697d9e1ff + zh: 9c4ceb0024e50835 +/agent-note-plugin-owned-human-command-registration/testing: + en: 0679c206796636a6 + zh: ca2cc5df6aa3aa2e +/agent-note-plugin-owned-human-command-registration/alternatives-considered: + en: ffb2f060314a17b2 + zh: e7707cf5faf80227 +/agent-note-plugin-owned-human-command-registration/consequences: + en: 6b8525a4ca3213a8 + zh: 286a336a68669f72 +/agent-note-plugin-owned-human-command-registration/known-limitations-and-deferred-work: + en: 5e2417d5b1237526 + zh: dbfeea7c7ac38cf0 diff --git a/.agents/notes/implemented/feature/2026-07-20-ptc-typed-tool-returns.i18n.yaml b/.agents/notes/implemented/feature/2026-07-20-ptc-typed-tool-returns.i18n.yaml index b083ea6a1e..1d59d0072b 100644 --- a/.agents/notes/implemented/feature/2026-07-20-ptc-typed-tool-returns.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-20-ptc-typed-tool-returns.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-20-ptc-typed-tool-returns.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-20-ptc-typed-tool-returns.md -2026-07-20-ptc-typed-tool-returns.md: 08e760b95a40386bccc8c7a2722d289da10e3dff -2026-07-20-ptc-typed-tool-returns.zh.md: c2883740e1eeadbf6fb2413496104ff08a9bd1f7 +/agent-note-typed-tool-returns-in-ptc-mode: + en: 4b7c45b382db3a40 + zh: 96e9210446ec35ed +/agent-note-typed-tool-returns-in-ptc-mode/problem: + en: cf7610bb16ff04af + zh: 73b00b539dbaecd9 +/agent-note-typed-tool-returns-in-ptc-mode/decision: + en: 55bb889404c89f4a + zh: f9a9091569fbf7b4 +/agent-note-typed-tool-returns-in-ptc-mode/decision/generated-sdk: + en: 30583e9ac6715952 + zh: 3a85c9482abf574c +/agent-note-typed-tool-returns-in-ptc-mode/decision/binding-values-and-failures: + en: ecb95cafa2dc1297 + zh: ccdf300ca936ca12 +/agent-note-typed-tool-returns-in-ptc-mode/decision/outer-result-and-output-ledger: + en: d907d0a8205157e1 + zh: 1ed99168266a7ca4 +/agent-note-typed-tool-returns-in-ptc-mode/decision/typed-handles-and-lifetime: + en: c5d9997ae7c7362d + zh: 1da8883d17d2748e +/agent-note-typed-tool-returns-in-ptc-mode/decision/persistence-metadata-and-spill: + en: 4d1e5f83f15f99cc + zh: b7f41a084cb23745 +/agent-note-typed-tool-returns-in-ptc-mode/testing: + en: 728513c779f031f8 + zh: f6d869f18add7242 +/agent-note-typed-tool-returns-in-ptc-mode/alternatives-considered: + en: dedd87b9b35d8fab + zh: 78db4c7e8c4e5f61 +/agent-note-typed-tool-returns-in-ptc-mode/consequences: + en: 7c2ee65532ab76f8 + zh: 3fb074c69909d390 +/agent-note-typed-tool-returns-in-ptc-mode/known-limitations-and-deferred-work: + en: a42af629ad6872cc + zh: 41e5c0bb3de0ae4d diff --git a/.agents/notes/implemented/feature/2026-07-21-follow-instruction-symlinks.i18n.yaml b/.agents/notes/implemented/feature/2026-07-21-follow-instruction-symlinks.i18n.yaml index 77a58fcc17..b85229745f 100644 --- a/.agents/notes/implemented/feature/2026-07-21-follow-instruction-symlinks.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-21-follow-instruction-symlinks.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-21-follow-instruction-symlinks.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-21-follow-instruction-symlinks.md -2026-07-21-follow-instruction-symlinks.md: a6b4cb5d465d2ebf7088d8e3a04fbb32503e2e15 -2026-07-21-follow-instruction-symlinks.zh.md: a44f89d8ec3c636a875059aabe0683c6bf1da851 +/agent-note-follow-symlinked-instruction-files: + en: aa37067267aa70ff + zh: 75aff9256b49199f +/agent-note-follow-symlinked-instruction-files/problem: + en: 81e1947150ceb054 + zh: 97575f09a9e57db4 +/agent-note-follow-symlinked-instruction-files/decision: + en: 911b5bb48a95afd0 + zh: 1a38e50602b86bc4 +/agent-note-follow-symlinked-instruction-files/decision/trust-boundary-and-residual-risk: + en: 31ea638766861600 + zh: a270db3c868585b0 +/agent-note-follow-symlinked-instruction-files/alternatives-considered: + en: cf5e62b7cae4f0dc + zh: ff7d5821958efeac +/agent-note-follow-symlinked-instruction-files/consequences: + en: b0ee45a9e4d95dd5 + zh: 338d3758f400a651 diff --git a/.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.i18n.yaml b/.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.i18n.yaml index c193f39ddd..8f2fe2b211 100644 --- a/.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-23-session-telemetry-otel-revival.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.md -2026-07-23-session-telemetry-otel-revival.md: dc52ee87ef78107d674e49af3c20c255266f0414 -2026-07-23-session-telemetry-otel-revival.zh.md: f647ea289684eca648fe797011daad858612546f +/agent-note-session-telemetry-seam-with-mandatory-redaction-and-the-otel-backend: + en: 36222884462b86d2 + zh: 2f834557e3fa3baa +/agent-note-session-telemetry-seam-with-mandatory-redaction-and-the-otel-backend/problem: + en: d3383b495424d118 + zh: 4e6ffc8ebfa7f741 +/agent-note-session-telemetry-seam-with-mandatory-redaction-and-the-otel-backend/decision: + en: 85b950a67315023c + zh: cb4c08338c30b226 +/agent-note-session-telemetry-seam-with-mandatory-redaction-and-the-otel-backend/alternatives-considered: + en: 01838eefca2bc117 + zh: fc71f5449d095b27 +/agent-note-session-telemetry-seam-with-mandatory-redaction-and-the-otel-backend/consequences: + en: 487d440abfc7e3a9 + zh: a31d6abc8a0176c6 diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml index 892090c52d..f52f1c14fc 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-25-subagent-policy-inheritance.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md -2026-07-25-subagent-policy-inheritance.md: 8ca63bd511a275acbfda5ddee8cb50af51c348a1 -2026-07-25-subagent-policy-inheritance.zh.md: 630c69274e8e9cba07a6152395149757be3d6560 +/agent-note-in-process-subagent-policy-inheritance-the-child-starts-under-the-parent-s-sandbox-override: + en: 02b7ba888360c75c + zh: 42a6d20927622c9c +/agent-note-in-process-subagent-policy-inheritance-the-child-starts-under-the-parent-s-sandbox-override/problem: + en: 476b4a1b9ada2d8a + zh: 15b8051d22bb1dd0 +/agent-note-in-process-subagent-policy-inheritance-the-child-starts-under-the-parent-s-sandbox-override/decision: + en: 1f99951bc562cce4 + zh: d68ee315b7aea792 +/agent-note-in-process-subagent-policy-inheritance-the-child-starts-under-the-parent-s-sandbox-override/decision/what-a-blocked-child-experiences: + en: 3b6ff196a06c2420 + zh: c04cb8bd81eb1c4b +/agent-note-in-process-subagent-policy-inheritance-the-child-starts-under-the-parent-s-sandbox-override/alternatives-considered: + en: 2f659b5b3b6faa21 + zh: c3712d0b6f8903c9 +/agent-note-in-process-subagent-policy-inheritance-the-child-starts-under-the-parent-s-sandbox-override/consequences: + en: 1b0a242aa33a8005 + zh: 426f83e118771b8e diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md index 8ca63bd511..a7973bcc07 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md @@ -10,7 +10,7 @@ The Auto or Full access preset identity plus sandbox and approval overrides are ## Decision -The delegation boundary calls the shared child-agent helpers (`captureDelegatedPolicyOverrides`/`appendDelegatedPolicyOverrides` in `dsh-subagent`) before its first await; the one-shot driver and the [continuable start](../../../../packages/subagent/subagent/README.md) both use them. The capture copies the current `permission/preset` identity when `permissionPresets.current(parent.session)` is `auto` or `danger-full-access`, snapshots `sandboxPolicy.overrideOf(parent.session)`, and pins the child approval policy to `'never'`. A later parent switch belongs to the parent's future; cancel-and-redelegate takes a new snapshot. The permission-preset and sandbox-policy services are optional: only the Auto/Full-access shared-bundle identity and the explicit sandbox session override are copied, never deployment defaults or one-shot grants. The approval policy is not inherited — the [approvals-pinned decision](2026-08-10-subagent-approval-pinned-never.md) supersedes this note's original approval-override inheritance. +The delegation boundary calls the shared child-agent helpers (`captureDelegatedPolicyOverrides`/`appendDelegatedPolicyOverrides` in `dsh-subagent`) before its first await; the one-shot driver and the [continuable start](../../../../packages/subagent/subagent/README.md) both use them. The capture copies the current `permission/preset` identity when `permissionPresets.current(parent.session)` is `auto` or `danger-full-access`, snapshots `sandboxPolicy.overrideOf(parent.session)`, and pins the child approval policy to `'never'`. A later parent switch belongs to the parent's future; cancel-and-redelegate takes a new snapshot. The permission-preset and sandbox-policy services are optional: only the Auto or Full access identity and the explicit sandbox session override are copied, never deployment defaults or one-shot grants. The approval policy is not inherited — the [approvals-pinned decision](2026-08-10-subagent-approval-pinned-never.md) supersedes this note's original approval-override inheritance. An inherited Auto or Full access identity becomes a `permission/preset` event, while captured sandbox and pinned approval values become source-tagged `sandbox/mode` and `approval/policy` events during the child factory's unpublished setup. The session constructor has already fixed `Session.firstLiveSeq` after the constructor seed, while `Session.inheritedEventCount` keeps the exact fork-prefix length, so the inherited facts follow fork history without changing its lineage cut. Lifecycle-local telemetry starts at `firstLiveSeq`, so it excludes the constructor seed and includes these unpublished-setup events. Existing last-event-wins folds therefore make the delegation snapshot beat stale fork history and let a later child switch beat the snapshot. A grandchild folds its parent's logged state, so the rule composes without another inheritance mechanism. diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md index 630c69274e..0b4a2d4099 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md @@ -10,7 +10,7 @@ Auto 或 Full access 预设身份以及沙箱与审批覆盖项都是按会话 ## 决策 -委派边界会在第一次 await 之前调用共享的子 agent 辅助函数(`dsh-subagent` 中的 `captureDelegatedPolicyOverrides`/`appendDelegatedPolicyOverrides`);一次性驱动器与[可继续启动](../../../../packages/subagent/subagent/README.zh.md)都会使用它们。当 `permissionPresets.current(parent.session)` 为 `auto` 或 `danger-full-access` 时,捕获会复制当前 `permission/preset` 身份,同时对 `sandboxPolicy.overrideOf(parent.session)` 获取快照,并把子 agent 的审批策略钉定为 `'never'`。父级后续的切换属于父级的未来;取消后重新委派会取得新快照。权限预设与沙箱策略服务都是可选的:只复制 Auto/Full access 共用旋钮组合的身份与显式沙箱会话覆盖项,绝不复制部署默认值或一次性授权。审批策略不继承——[审批钉定决策](2026-08-10-subagent-approval-pinned-never.zh.md)取代了本 note 原先的审批覆盖项继承。 +委派边界会在第一次 await 之前调用共享的子 agent 辅助函数(`dsh-subagent` 中的 `captureDelegatedPolicyOverrides`/`appendDelegatedPolicyOverrides`);一次性驱动器与[可继续启动](../../../../packages/subagent/subagent/README.zh.md)都会使用它们。当 `permissionPresets.current(parent.session)` 为 `auto` 或 `danger-full-access` 时,捕获会复制当前 `permission/preset` 身份,同时对 `sandboxPolicy.overrideOf(parent.session)` 获取快照,并把子 agent 的审批策略钉定为 `'never'`。父级后续的切换属于父级的未来;取消后重新委派会取得新快照。权限预设与沙箱策略服务都是可选的:只复制 Auto 或 Full access 身份与显式沙箱会话覆盖项,绝不复制部署默认值或一次性授权。审批策略不继承——[审批钉定决策](2026-08-10-subagent-approval-pinned-never.zh.md)取代了本 note 原先的审批覆盖项继承。 继承的 Auto 或 Full access 身份会成为一条 `permission/preset` 事件,捕获的沙箱值与钉定的审批值则会在子 agent 工厂的未发布设置阶段成为带来源标记的 `sandbox/mode` 与 `approval/policy` 事件。会话构造函数已把 `Session.firstLiveSeq` 固定在 constructor seed 之后,而 `Session.inheritedEventCount` 保留精确的 fork 前缀长度,因此继承事实会排在 fork 历史之后,却不改变其谱系 cut。生命周期本地遥测从 `firstLiveSeq` 开始,因此排除 constructor seed,并包含这些未发布设置事件。因此,既有的末事件胜出折叠会让委派快照压过陈旧的 fork 历史,并让子 agent 后续的切换压过该快照。孙代 agent 会折叠其父级已记录的状态,因此无需另一套继承机制即可组合此规则。 diff --git a/.agents/notes/implemented/feature/2026-07-26-ptc-live-parallel-dispatch.i18n.yaml b/.agents/notes/implemented/feature/2026-07-26-ptc-live-parallel-dispatch.i18n.yaml index ae720a62ac..07e8978506 100644 --- a/.agents/notes/implemented/feature/2026-07-26-ptc-live-parallel-dispatch.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-26-ptc-live-parallel-dispatch.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-26-ptc-live-parallel-dispatch.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-26-ptc-live-parallel-dispatch.md -2026-07-26-ptc-live-parallel-dispatch.md: f064314098af9c074f7cd06dc9ceea3df4c91c76 -2026-07-26-ptc-live-parallel-dispatch.zh.md: 70cbebcdc30c5771a2c29f36b588232822e19269 +/agent-note-ptc-mode-live-dispatch-lifecycle-and-native-contract-parallelism: + en: f546683c54ae7d6b + zh: 1c0760c5f49f0188 +/agent-note-ptc-mode-live-dispatch-lifecycle-and-native-contract-parallelism/problem: + en: ce16b44b1db07ec0 + zh: 30681dab84948cd8 +/agent-note-ptc-mode-live-dispatch-lifecycle-and-native-contract-parallelism/decision: + en: 7ac907f773ff9d50 + zh: 86982428baf83cde +/agent-note-ptc-mode-live-dispatch-lifecycle-and-native-contract-parallelism/alternatives-considered: + en: b015fa95b46e5fd5 + zh: b4fe283a1ab598c1 +/agent-note-ptc-mode-live-dispatch-lifecycle-and-native-contract-parallelism/consequences: + en: d16ba3a88fa7d528 + zh: 8c374a14a4f34cfe diff --git a/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.i18n.yaml b/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.i18n.yaml index 21f75ab4b4..770368862d 100644 --- a/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-27-web-subagent-conversations.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.md -2026-07-27-web-subagent-conversations.md: 3798a5a2e5deb8b3801298def31c3a1890877796 -2026-07-27-web-subagent-conversations.zh.md: 4531528dd2a58baff3aaeaf53f20e037fce6cec4 +/agent-note-web-subagent-catalog-and-human-continuation: + en: c6373db2300cb803 + zh: 4d0589f21ec284ff +/agent-note-web-subagent-catalog-and-human-continuation/problem: + en: dfdbe64d34f9e05b + zh: 4cb7a92a6d3dc3e3 +/agent-note-web-subagent-catalog-and-human-continuation/decision: + en: 8892eea7f62d45ed + zh: 18f64966ff53e38b +/agent-note-web-subagent-catalog-and-human-continuation/design-context: + en: 3c44fc5af90bc807 + zh: 478538d028a52858 +/agent-note-web-subagent-catalog-and-human-continuation/product-contract: + en: 2060d607d1cd1ef3 + zh: e7100887358625c4 +/agent-note-web-subagent-catalog-and-human-continuation/host-adapter-and-wire-contract: + en: e0e82599b0a8d3bf + zh: e671e1f0f98795b4 +/agent-note-web-subagent-catalog-and-human-continuation/client-object-layer-and-presentation: + en: c0c891d86b1f7e1e + zh: c7b8da2bee81755d +/agent-note-web-subagent-catalog-and-human-continuation/default-web-assembly: + en: 6d4d8db99535aa18 + zh: 803554b55a67acb1 +/agent-note-web-subagent-catalog-and-human-continuation/alternatives-considered: + en: 427f0a8ace8ad692 + zh: 876771621858f77d +/agent-note-web-subagent-catalog-and-human-continuation/testing: + en: 0c2f7f5cc473ecff + zh: 00b2c22e109b3429 +/agent-note-web-subagent-catalog-and-human-continuation/consequences: + en: 143fc76c6d09e8fb + zh: 01a042fb32b0d6e0 diff --git a/.agents/notes/implemented/feature/2026-07-27-workspace-registration-deletion.i18n.yaml b/.agents/notes/implemented/feature/2026-07-27-workspace-registration-deletion.i18n.yaml index ff57ba5953..ff719e7b97 100644 --- a/.agents/notes/implemented/feature/2026-07-27-workspace-registration-deletion.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-27-workspace-registration-deletion.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-27-workspace-registration-deletion.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-27-workspace-registration-deletion.md -2026-07-27-workspace-registration-deletion.md: 1d9804cfc4e2d44ea6c44f69b69dd6b10578f08a -2026-07-27-workspace-registration-deletion.zh.md: 54e10b67a7607e32b08609fe00191da87d75f7e8 +/agent-note-workspace-registration-deletion: + en: 68262d0cd61db2ae + zh: bb2f78757972aae6 +/agent-note-workspace-registration-deletion/problem: + en: a51dbe0190d4dff0 + zh: 25b6c3083ee60627 +/agent-note-workspace-registration-deletion/decision: + en: 70182cd2979bdfd6 + zh: a6580a23cfbe6c07 +/agent-note-workspace-registration-deletion/durable-commit-and-publication: + en: f97d526274c3608b + zh: b0ae161f4e9febb8 +/agent-note-workspace-registration-deletion/client-convergence: + en: 84e56775e22ecf23 + zh: ab146e3179868efb +/agent-note-workspace-registration-deletion/confirmation-interaction: + en: 95178832030a9697 + zh: 3a2bd50680ed0c97 +/agent-note-workspace-registration-deletion/alternatives-considered: + en: d7b866f763db5364 + zh: 5e0865d42522d189 +/agent-note-workspace-registration-deletion/verification: + en: a7e98d39e3ffdba7 + zh: 9c4f8168e3fff83e +/agent-note-workspace-registration-deletion/consequences: + en: 3a50bfb5d93f6ef7 + zh: 80b8dd19b2d50b16 diff --git a/.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.i18n.yaml b/.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.i18n.yaml index 1369b927e3..e3f1e8bb08 100644 --- a/.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.i18n.yaml @@ -1,6 +1,52 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-28-continuable-subagent-conversations.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.md -2026-07-28-continuable-subagent-conversations.md: a30966c4d614fda837bc2bac95f6b6e411de9791 -2026-07-28-continuable-subagent-conversations.zh.md: 59a02a211e0ca861f819a7524e4d69ad09acdbbc +/agent-note-continuable-subagents: + en: 14c7d31032237174 + zh: ac2666670a0ca5ab +/agent-note-continuable-subagents/problem: + en: a72071eeedb77402 + zh: 818d16ce429fd610 +/agent-note-continuable-subagents/decision: + en: 445a8c9783aad214 + zh: 9b5c576bb76100a4 +/agent-note-continuable-subagents/decision/materialization-and-public-operations: + en: c7c55e5738a7c0d8 + zh: 54849d8938f7c77f +/agent-note-continuable-subagents/decision/durable-session-and-live-activation: + en: 92fd7302d4c8f2e5 + zh: e821764c07070ebc +/agent-note-continuable-subagents/decision/activation-lifecycle: + en: 68215c0ae5628608 + zh: fdf038decac8f07a +/agent-note-continuable-subagents/decision/one-inbox-and-follow-up-delivery: + en: 065399ce5b1de59e + zh: b60af3c37851323e +/agent-note-continuable-subagents/decision/child-ownership: + en: 503fb4311cd94674 + zh: 376fa98ec4d22b20 +/agent-note-continuable-subagents/decision/adjacent-agent-messaging: + en: a6899f5a82d5dceb + zh: 0671b89b2dca9c4e +/agent-note-continuable-subagents/decision/agent-and-human-scheduling: + en: 8c861f3846fef1b5 + zh: 8cc3d668d73c7748 +/agent-note-continuable-subagents/decision/authority-and-recorded-sender-identity: + en: f5ba7e9c5339ceef + zh: 31ae1b2f57e44463 +/agent-note-continuable-subagents/decision/durability-disposal-and-recovery: + en: 276626f3b6d4a080 + zh: 806f9c4786bc4004 +/agent-note-continuable-subagents/decision/scope: + en: a47eed90de23351c + zh: 2351e4acbfe4c8e1 +/agent-note-continuable-subagents/alternatives-considered: + en: 485aef32231dac62 + zh: 5e2c103afb3e2d6f +/agent-note-continuable-subagents/consequences: + en: fa5a6b4bf262b8dd + zh: 4bffd7b8cc2efae5 +/agent-note-continuable-subagents/consequences/accepted-costs: + en: 4d4330ee4d7c3f31 + zh: 8fd11ba0625fb76d diff --git a/.agents/notes/implemented/feature/2026-07-28-skill-invocation-policy.i18n.yaml b/.agents/notes/implemented/feature/2026-07-28-skill-invocation-policy.i18n.yaml index 4e16712b96..55f7304827 100644 --- a/.agents/notes/implemented/feature/2026-07-28-skill-invocation-policy.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-28-skill-invocation-policy.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-28-skill-invocation-policy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-28-skill-invocation-policy.md -2026-07-28-skill-invocation-policy.md: 614a0058e3887c6977cf92b4bcf7d15557215996 -2026-07-28-skill-invocation-policy.zh.md: a49cb96ea63af72d5abc41406097fcfb1b06739a +/agent-note-independent-model-and-user-skill-invocation-policy: + en: d5f87e846ef041b1 + zh: 273e87043d19a709 +/agent-note-independent-model-and-user-skill-invocation-policy/problem: + en: 9fc564115fca4b22 + zh: 3a414ee5c1f7f842 +/agent-note-independent-model-and-user-skill-invocation-policy/decision: + en: dbd7aabf9fdd7c37 + zh: d71a2fd355e30fd1 +/agent-note-independent-model-and-user-skill-invocation-policy/alternatives-considered: + en: fdffcd101a494c4a + zh: db802bf9bc04ae74 +/agent-note-independent-model-and-user-skill-invocation-policy/consequences: + en: 94071073367396eb + zh: 5afca22d8140b5c0 diff --git a/.agents/notes/implemented/feature/2026-07-30-queued-manual-compaction.i18n.yaml b/.agents/notes/implemented/feature/2026-07-30-queued-manual-compaction.i18n.yaml index 73f3dd021b..9da56d634b 100644 --- a/.agents/notes/implemented/feature/2026-07-30-queued-manual-compaction.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-30-queued-manual-compaction.i18n.yaml @@ -1,6 +1,43 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-30-queued-manual-compaction.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-30-queued-manual-compaction.md -2026-07-30-queued-manual-compaction.md: 3efd1a490148b34b0ee76800ed795dfaab280743 -2026-07-30-queued-manual-compaction.zh.md: 2da3f494afcdb0e0db47a0adb2e2a6101f7ef2e6 +/agent-note-queued-manual-compaction-with-one-durable-lock: + en: 45504a64618db51a + zh: f8dfebaf42ee4ddf +/agent-note-queued-manual-compaction-with-one-durable-lock/problem: + en: ffd033e0cea4b612 + zh: 63fa18871f038eb7 +/agent-note-queued-manual-compaction-with-one-durable-lock/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-queued-manual-compaction-with-one-durable-lock/decision/compact-is-a-command-over-a-backend-independent-seam: + en: a8631732e038e08d + zh: 68cb705f38ddfa57 +/agent-note-queued-manual-compaction-with-one-durable-lock/decision/idle-maintenance-is-synchronously-claimed: + en: a11c700f32838561 + zh: c20636c5f7efabaf +/agent-note-queued-manual-compaction-with-one-durable-lock/decision/one-parameterized-transaction-owns-every-bracket: + en: 7b75672fafc370c9 + zh: 4fb473856c9c7265 +/agent-note-queued-manual-compaction-with-one-durable-lock/decision/bracket-first-deliberately-differs-from-the-surveyed-implementations: + en: 309671a79b437033 + zh: 86e0f366aed73c35 +/agent-note-queued-manual-compaction-with-one-durable-lock/decision/markers-are-time-points-not-an-event-container: + en: e9d8043178dc946f + zh: 56808150ba2ab275 +/agent-note-queued-manual-compaction-with-one-durable-lock/decision/end-seed-distinguishes-live-and-stale-orphans: + en: cc767e216225e117 + zh: 4ec7dbc179f96c37 +/agent-note-queued-manual-compaction-with-one-durable-lock/decision/reference-implementation-boundaries: + en: 97b121c53b8f3b68 + zh: 13d86db92c30bef1 +/agent-note-queued-manual-compaction-with-one-durable-lock/alternatives-considered: + en: f1c5bae090425598 + zh: 60a30f851d85dfb0 +/agent-note-queued-manual-compaction-with-one-durable-lock/verification: + en: 37587419460fcf36 + zh: e45c752f93d5a87e +/agent-note-queued-manual-compaction-with-one-durable-lock/consequences: + en: b8c71ea1d1db7b8e + zh: 0d276bb8317ada91 diff --git a/.agents/notes/implemented/feature/2026-07-30-web-remote-markdown-images.i18n.yaml b/.agents/notes/implemented/feature/2026-07-30-web-remote-markdown-images.i18n.yaml index afe776d402..aea31db0d2 100644 --- a/.agents/notes/implemented/feature/2026-07-30-web-remote-markdown-images.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-30-web-remote-markdown-images.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-30-web-remote-markdown-images.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-30-web-remote-markdown-images.md -2026-07-30-web-remote-markdown-images.md: 23dc699aab87597b7b5bfee83d0d745d4798303e -2026-07-30-web-remote-markdown-images.zh.md: 54db9b25e9f558d77c84bb67c05fadea2c9086ac +/agent-note-remote-web-markdown-images: + en: a11eadff0703761d + zh: 59841eaf2993b7c4 +/agent-note-remote-web-markdown-images/problem: + en: 97447c93b654eda7 + zh: 456a3ceed4967d0a +/agent-note-remote-web-markdown-images/decision: + en: 8dfbdb81dff9cae3 + zh: 217042998b65c158 +/agent-note-remote-web-markdown-images/alternatives-considered: + en: 32a4116e8ffc4b16 + zh: 59dd991fede9ac71 +/agent-note-remote-web-markdown-images/consequences: + en: 12b97c75c5d19308 + zh: ee8102b7d01e579b diff --git a/.agents/notes/implemented/feature/2026-07-31-even-out-shipped-tool-rosters.i18n.yaml b/.agents/notes/implemented/feature/2026-07-31-even-out-shipped-tool-rosters.i18n.yaml index 1f490bce21..2a3d4bae8d 100644 --- a/.agents/notes/implemented/feature/2026-07-31-even-out-shipped-tool-rosters.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-31-even-out-shipped-tool-rosters.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-31-even-out-shipped-tool-rosters.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-31-even-out-shipped-tool-rosters.md -2026-07-31-even-out-shipped-tool-rosters.md: 90efaeb4734c806bc1bdc63d883c4e3158792a13 -2026-07-31-even-out-shipped-tool-rosters.zh.md: 4379ffbcd23ea80acd6801ea260fb686cd955fa5 +/agent-note-even-out-the-shipped-tool-rosters: + en: aa8ec8438dc609aa + zh: 28172207b09ea3ad +/agent-note-even-out-the-shipped-tool-rosters/problem: + en: 69e127b53366cf66 + zh: 63f783ac453d4cbe +/agent-note-even-out-the-shipped-tool-rosters/decision: + en: 45662b711bd9a201 + zh: 845cd2a9193cbe0f +/agent-note-even-out-the-shipped-tool-rosters/decision/what-stays-unmounted-and-why: + en: 7a74b42b428b9cf9 + zh: 4f534ccd26b9ecc4 +/agent-note-even-out-the-shipped-tool-rosters/decision/mcp-is-a-dependency-not-a-row: + en: 45358314e6adae26 + zh: 85ca6a6ce7bbf947 +/agent-note-even-out-the-shipped-tool-rosters/testing: + en: 07e46125d49a2068 + zh: 83a1b2737768651b +/agent-note-even-out-the-shipped-tool-rosters/alternatives-considered: + en: cf41f0bf700af59c + zh: 1dcaafe6bb944d92 +/agent-note-even-out-the-shipped-tool-rosters/consequences: + en: cf1821c985507b13 + zh: 0f7396a06d1b19fb diff --git a/.agents/notes/implemented/feature/2026-07-31-web-default-search.i18n.yaml b/.agents/notes/implemented/feature/2026-07-31-web-default-search.i18n.yaml index ce197d5093..f398e72a4e 100644 --- a/.agents/notes/implemented/feature/2026-07-31-web-default-search.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-31-web-default-search.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-31-web-default-search.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-31-web-default-search.md -2026-07-31-web-default-search.md: fed162cf2552e0209599634a7f215c48c1943339 -2026-07-31-web-default-search.zh.md: 3f39ef7d9f3adbc1c43a327faac78b21a08654de +/agent-note-default-web-search-in-shipped-compositions: + en: 030dc2ef246ba33d + zh: 94cc720adfd3d4ef +/agent-note-default-web-search-in-shipped-compositions/problem: + en: cd5af0c73d578874 + zh: 29e14c7ff1c77391 +/agent-note-default-web-search-in-shipped-compositions/decision: + en: 7062647c8e227743 + zh: 26bdd8dc4b0cd7ad +/agent-note-default-web-search-in-shipped-compositions/alternatives-considered: + en: f28e0f1183e755ce + zh: 2cbf256a33d99686 +/agent-note-default-web-search-in-shipped-compositions/consequences: + en: d69965f3be327186 + zh: 4e2b10bb0a227f0a diff --git a/.agents/notes/implemented/feature/2026-07-31-web-workspace-file-links.i18n.yaml b/.agents/notes/implemented/feature/2026-07-31-web-workspace-file-links.i18n.yaml index a8899fea13..25355eb4d5 100644 --- a/.agents/notes/implemented/feature/2026-07-31-web-workspace-file-links.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-31-web-workspace-file-links.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-31-web-workspace-file-links.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-31-web-workspace-file-links.md -2026-07-31-web-workspace-file-links.md: 1fd58deafa99f6c84371d2a2c3975eae86522ac2 -2026-07-31-web-workspace-file-links.zh.md: 8cb1d06562398a832fed0743a7c06894d0a4212b +/agent-note-opening-a-produced-file-from-the-web-ui: + en: bdfcd62110aaefa2 + zh: 92981f1fe8ca52c9 +/agent-note-opening-a-produced-file-from-the-web-ui/problem: + en: 06ba78ace240645c + zh: 07a46477d41ddcee +/agent-note-opening-a-produced-file-from-the-web-ui/decision: + en: a3d6e9aa14dc6fb8 + zh: d9696d46eb4a348d +/agent-note-opening-a-produced-file-from-the-web-ui/alternatives-considered: + en: ba9603055aea84aa + zh: 3ab217f1b1ccb3b6 +/agent-note-opening-a-produced-file-from-the-web-ui/consequences: + en: aa460548654a89a5 + zh: ebb8e51f5cd18f0b diff --git a/.agents/notes/implemented/feature/2026-08-02-pwsh-tool-bash-parity.i18n.yaml b/.agents/notes/implemented/feature/2026-08-02-pwsh-tool-bash-parity.i18n.yaml index 66983526a5..4ac0e96629 100644 --- a/.agents/notes/implemented/feature/2026-08-02-pwsh-tool-bash-parity.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-02-pwsh-tool-bash-parity.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-02-pwsh-tool-bash-parity.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-02-pwsh-tool-bash-parity.md -2026-08-02-pwsh-tool-bash-parity.md: cc2e7797c07ee8fd8c876cb30f9154a8ee2903c3 -2026-08-02-pwsh-tool-bash-parity.zh.md: b7949f1a5145fb6dac06bc47eeee488497b169d6 +/agent-note-pwsh-tool-bash-parity: + en: 76e33af7ff962cd2 + zh: 392f3d5f7100c564 +/agent-note-pwsh-tool-bash-parity/problem: + en: de5bfad14ef58243 + zh: fe8168a215719127 +/agent-note-pwsh-tool-bash-parity/decision: + en: 169a42b6c2dc965d + zh: 4172091b0299c748 +/agent-note-pwsh-tool-bash-parity/alternatives-considered: + en: 7dc381c52b191bc9 + zh: 6c07393519d3bb21 +/agent-note-pwsh-tool-bash-parity/consequences: + en: ea302108933e8a69 + zh: 563db786f22d07fa diff --git a/.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.i18n.yaml b/.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.i18n.yaml index d95f30747e..dc33cc6355 100644 --- a/.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-04-claude-code-and-codex-subagent-backends.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.md -2026-08-04-claude-code-and-codex-subagent-backends.md: d11b200e95cbb0769ad30ae88cb976c7921c80f8 -2026-08-04-claude-code-and-codex-subagent-backends.zh.md: 5899a27bb8ad592d9b83b7d19e681bef375525fb +/agent-note-claude-code-and-codex-subagent-backends: + en: 0f3599cefa53ad5b + zh: 988c28cdd9ee4e61 +/agent-note-claude-code-and-codex-subagent-backends/problem: + en: dbd5758c1c46b303 + zh: ca5b8479f4358c9b +/agent-note-claude-code-and-codex-subagent-backends/decision: + en: caf8c74c3466b27a + zh: 5b1daf0a738221cd +/agent-note-claude-code-and-codex-subagent-backends/decision/ownership-and-lifecycle: + en: 1c106b8b0063fee2 + zh: 0a38a1ffbe93086d +/agent-note-claude-code-and-codex-subagent-backends/codex-provider: + en: 5835894b4ac2e182 + zh: c1fcbd2b2b7e0ea0 +/agent-note-claude-code-and-codex-subagent-backends/claude-code-provider: + en: 81a92541d399b155 + zh: d73a1f20c34982bb +/agent-note-claude-code-and-codex-subagent-backends/distribution-and-evidence: + en: ff6d6216e5ce11dd + zh: 6198c006ba8c61e7 +/agent-note-claude-code-and-codex-subagent-backends/alternatives-considered: + en: 10b5b282fac03988 + zh: bf9fb4899f2c8e16 +/agent-note-claude-code-and-codex-subagent-backends/consequences: + en: 4154bcdc7ad9ff7c + zh: e2bc1f2010bb48a9 diff --git a/.agents/notes/implemented/feature/2026-08-05-agent-teams.i18n.yaml b/.agents/notes/implemented/feature/2026-08-05-agent-teams.i18n.yaml index 4eb9df8cb0..1f9b21f587 100644 --- a/.agents/notes/implemented/feature/2026-08-05-agent-teams.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-05-agent-teams.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-05-agent-teams.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-05-agent-teams.md -2026-08-05-agent-teams.md: 6333e511ba1e71823cfa55c27ba46b2665d1ef15 -2026-08-05-agent-teams.zh.md: 3fed1302146406f71d63c7ff2df8f031a91c9804 +/agent-note-durable-agent-teams-over-continuable-children: + en: c914d8148bfc4bf9 + zh: a8115f87c0ac6cae +/agent-note-durable-agent-teams-over-continuable-children/problem: + en: bab62798c2dc07b4 + zh: fe42c5abf9127d37 +/agent-note-durable-agent-teams-over-continuable-children/decision: + en: 58568b3a9b5f60d5 + zh: 02d67b6cb0736c0a +/agent-note-durable-agent-teams-over-continuable-children/profile-delegation: + en: 3a66308576f74247 + zh: 3453f0bcce88033d +/agent-note-durable-agent-teams-over-continuable-children/team-identity: + en: 83e446c928a20c47 + zh: b0a2bd24419dd815 +/agent-note-durable-agent-teams-over-continuable-children/provisioning-and-recovery: + en: 085846d0078c0898 + zh: 40b2ca3ae6864451 +/agent-note-durable-agent-teams-over-continuable-children/mailbox-and-task-transactions: + en: ab2ad55021eb34e0 + zh: 2d1996df7a69201d +/agent-note-durable-agent-teams-over-continuable-children/shared-checkout-boundary: + en: 3969de3b44e412c8 + zh: 12be5854816cb808 +/agent-note-durable-agent-teams-over-continuable-children/web-projection: + en: e6348054f024725b + zh: 8740636e99940308 +/agent-note-durable-agent-teams-over-continuable-children/alternatives-considered: + en: bb266fe7a97f0828 + zh: 7c86c2d6d11ba02a +/agent-note-durable-agent-teams-over-continuable-children/testing: + en: 151b462649212acf + zh: 983c4bee7b71c1e3 +/agent-note-durable-agent-teams-over-continuable-children/consequences: + en: c3740ae56809e537 + zh: 76a1e77d14cb6f26 diff --git a/.agents/notes/implemented/feature/2026-08-05-context-form-vocabulary.i18n.yaml b/.agents/notes/implemented/feature/2026-08-05-context-form-vocabulary.i18n.yaml index bcd3dfd359..19c93bd64d 100644 --- a/.agents/notes/implemented/feature/2026-08-05-context-form-vocabulary.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-05-context-form-vocabulary.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-05-context-form-vocabulary.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-05-context-form-vocabulary.md -2026-08-05-context-form-vocabulary.md: e1c909b761fee60ebacb306ef204a4212a03baa4 -2026-08-05-context-form-vocabulary.zh.md: 4d595bf52fba2f7323643ddc47bd365ce6508c9e +/agent-note-producer-declared-context-forms: + en: a88151ac41197659 + zh: 4aaffb71b4ae04ea +/agent-note-producer-declared-context-forms/problem: + en: 74c06aa0b3e5337e + zh: c13364dbaebabba1 +/agent-note-producer-declared-context-forms/decision: + en: e97830627fd8245f + zh: 0b035c15ed09902d +/agent-note-producer-declared-context-forms/why-not-a-presenter-registry: + en: feb1b16eeb312e0c + zh: 9eb3c5af2d510235 +/agent-note-producer-declared-context-forms/alternatives-considered: + en: 86f7f90f4c573316 + zh: d8008512145a89b4 +/agent-note-producer-declared-context-forms/testing: + en: 5910183c18c3341e + zh: 7c5d4e538a66533f +/agent-note-producer-declared-context-forms/consequences: + en: 15d3d98980ea3919 + zh: 4e14b65420de0df3 diff --git a/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.i18n.yaml b/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.i18n.yaml index a2330d603f..74f90930fc 100644 --- a/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-05-durable-web-schedule.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-05-durable-web-schedule.md -2026-08-05-durable-web-schedule.md: b09ab752c9db0587b49dbe50a152144b9ff19515 -2026-08-05-durable-web-schedule.zh.md: 8d84be3e3589969245fa41f433166eabacdf3951 +/agent-note-durable-scheduled-reminders: + en: 7d312bc635f68bef + zh: f675a214bfe26dac +/agent-note-durable-scheduled-reminders/problem: + en: 85e09d88c1383aeb + zh: 2d90fcbf2fe5ad3c +/agent-note-durable-scheduled-reminders/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-durable-scheduled-reminders/decision/explicit-absolute-time-boundary: + en: 16cc539a319f99b4 + zh: ae06872529f2227d +/agent-note-durable-scheduled-reminders/decision/bounded-fixed-rate-semantics: + en: 4a12a91087629614 + zh: 4f23eee242eeadd3 +/agent-note-durable-scheduled-reminders/decision/queue-admission-is-not-completion: + en: 1d88821105254303 + zh: 08982a1534d8fd18 +/agent-note-durable-scheduled-reminders/alternatives-considered: + en: f6d44a87797410ca + zh: 383ac9e712492c93 +/agent-note-durable-scheduled-reminders/verification: + en: 113a6d381ff1b145 + zh: 59f9693741adbbab +/agent-note-durable-scheduled-reminders/consequences: + en: 2121b1640094e601 + zh: 9420468b80ff1155 diff --git a/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.md b/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.md index b09ab752c9..f918a6f44f 100644 --- a/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.md +++ b/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.md @@ -1,93 +1,49 @@ -# Agent Note: Durable Session-local reminders +# Agent Note: Durable scheduled reminders Status: implemented English | [中文](2026-08-05-durable-web-schedule.zh.md) +The [Host-owned scheduled messages decision](../architecture/2026-09-16-host-schedule-storage.md) owns task storage, timer activation, dispatch, delivery records, and the task catalog. This note owns the two timing decisions that survive it — the explicit absolute-time boundary and bounded fixed-rate arithmetic — and the queue-admission boundary they share. + ## Problem -A reminder created inside a conversation must remain attributable to that exact Session and survive a process restart. A process-local timer or inbox item cannot provide that durability, while a global scheduler or private database introduces a second identity, persistence, and lifecycle system. - -Busy Agents, long waits, wall-clock changes, cold Sessions, forks, persistence failures, absolute calendar input, and teardown make a simple timeout insufficient. The design must distinguish a durable record from its disposable live wait, keep a fork from inheriting its parent's active reminders, and avoid spreading Schedule-specific presentation or time-zone state across unrelated components. +A reminder created inside a conversation must remain attributable to that exact Session and survive a process restart. Busy Agents, long waits, wall-clock changes, cold Sessions, and persistence failures make a simple timeout insufficient. Absolute calendar input and repeated wake-ups raise two timing questions that storage and activation choices do not answer: what an absolute time means when no recurring rule stores a zone, and how a fixed interval catches up after downtime without replaying every missed occurrence. ## Decision -The [Schedule guide](../../../../docs/user/guide/schedule.md) uses an overlay that explicitly loads `@deepseek-ai/dsh-time-context` and `@deepseek-ai/dsh-schedule`, and enables the Web bundle's otherwise-disabled `ui-schedule` row. The default Web startup graph remains inactive for Schedule. Schedule observes only root Agents published after the plugin loads and installs its three tools plus one disposable owner in that Agent scope. Cold history reads, already-published roots, child Agents, and other hosts do not activate the runtime. - -The user-visible boundary is `session-local`: the original Session runs an on-time reminder only while live, does no external notification while cold, and processes an overdue reminder after it becomes live again. Due work waits until the Agent is fully idle, then enters the ordinary next-turn queue through `followup()`; it never steers the current turn and has no independent Web receipt ([conversational delivery](../../archived/simplification/2026-08-09-conversational-schedule-delivery.md)). - -| Scenario | Durable fact | Live behavior | User-visible result | -| --- | --- | --- | --- | -| Create and manage | `schedule/change` create/delete in the original Session | Agent-scoped tools checkpoint before reads and after mutations | Stable id, UTC target, state, and `session-local` disclosure | -| Due while busy | Active create remains in the fold | Owner waits for idle maintenance, queues one follow-up, then appends dispatch | A later ordinary conversation turn | -| Several Every records are overdue | Each active record retains its earliest unaccepted anchor-aligned target | One decision selects each record's latest occurrence and advances it past now | One ordinary follow-up containing one occurrence per record | -| Process stopped or Session cold | Active create remains persisted | No timer or background scan; resume rebuilds the owner | Future target waits; overdue target is attempted | -| Fork | Parent events remain in the inherited prefix | Child fold starts at the exact `inheritedEventCount` | Parent work does not become active in the child | - -### Session-log authority and tools - -The version-1 `schedule/change` stream is the only durable Schedule authority. A create record owns a Session-local, non-reused branded id, the trimmed prompt, its rule discriminator, and UTC target. Delete and one-shot dispatch are terminal transitions. Every dispatch stores its id and decision time so the fold advances that record directly past missed occurrences. The strict decoder and pure fold reject unknown versions, extra fields, reused ids, mismatched dispatch shapes, and transitions against inactive records. A normal Session folds its complete stream; a fork folds only events at or after the `inheritedEventCount` passed into projection initialization. - -When `ctx.sessionProjections` exists, Schedule registers a strict unit that uses the same transition and publishes the complete active `ScheduleRecord[]`; the shared [projection state decision](../../archived/architecture/2026-08-19-session-projection-state-and-client-views.md) owns its initialization and restore contract. Corrupt durable input fails the existing read path rather than yielding a partial array. The browser-safe record vocabulary is exposed through the type-only `@deepseek-ai/dsh-schedule/client` subpath. - -The current rule union accepts a non-empty prompt and exactly one selector. `after_seconds` is a positive safe-integer delay whose record is `{ id, kind: 'after', prompt, afterSeconds, scheduledAt }`. `at` is either strict RFC 3339 with `Z` or a numeric offset, or structured `{ date, time, time_zone }` with an explicit zone; its record is `{ id, kind: 'at', prompt, scheduledAt }`. `every_seconds` is a safe integer of at least 300 whose `{ id, kind: 'every', prompt, everySeconds, scheduledAt }` record stays aligned to its creation-plus-interval sequence. One-shot dispatch stores only the id; Every dispatch stores `id + acceptedAt`. Tool values derive `scheduled` or `overdue` and include `deliveryMode: 'session-local'`. - -An Agent-scoped FIFO serializes management transactions and the live owner's due transaction from preflight through post-append barriers. Every tool read first awaits `ctx.sessions.flush(session)`. Create rejects input-shape failures before the FIFO when possible, preflights, allocates an id, appends, and checkpoints again. Delete validates its id before the FIFO, preflights before deciding whether it is active, and checkpoints again only after append. List and not-found delete never answer from an unconfirmed live suffix. Failed barriers return `persistence_uncertain` rather than guessing whether an eager write committed. - -Every successful management preflight asks the live owner to recompute. A later list can therefore confirm a retained create after a previous post-append rejection and arm it without a private persistence-retry timer. - ### Explicit absolute-time boundary Natural-language interpretation and Schedule parsing are deliberately separate ([time-zone simplification](../simplification/2026-08-09-explicit-schedule-time-zone.md)). Each browser prompt carries its Host-validated IANA zone only on that durable user message. Time-context tells the model to assume that zone for otherwise-unqualified dates and times. Schedule neither imports that plugin nor stores a Session zone: the model must turn its interpretation into an offset-bearing RFC 3339 value or a local object with explicit `time_zone`. -Schedule validates exact calendar shapes, offsets, zone names, and a strictly future four-digit-year instant. A local time inside a daylight-saving gap is rejected; an overlap chooses its first, earlier instant. A successful create stores only canonical UTC `scheduledAt`, not the original offset, local fields, or zone. +Schedule validates exact calendar shapes, offsets, zone names, and a strictly future four-digit-year instant. A structured local time inside a daylight-saving gap is rejected; an overlap chooses its first, earlier instant. A one-time `at` or `after` record stores only the canonical UTC `scheduledAt`, not the input offset, local fields, or zone. A `daily`, `weekly`, or `cron` record instead stores its normalized local rule with an explicit `timeZone` ([timing selectors](../../../../packages/schedule/schedule/README.md)). ### Bounded fixed-rate semantics -Every is a fixed-duration interval, not a calendar rule. The first target is creation time plus the interval. At a due decision, integer division selects the latest sequence point at or before the sampled wall clock and the first sequence point after it. The selected occurrence is presented once and the record advances directly to the future target, so a cold Session never accumulates a replay backlog and delayed model work never shifts the sequence. +Every is a fixed-duration interval, not a calendar rule. Its first target is creation time plus the interval. At a due decision, integer division selects the latest sequence point at or before the sampled wall clock and the first sequence point after it. The selected occurrence is presented once and the record advances directly to the future target, so a cold Session never accumulates a replay backlog and delayed model work never shifts the sequence. Every, Daily, Weekly, and Cron records overdue for one Session share one message, and each record contributes only its latest occurrence ([storage and dispatch](../architecture/2026-09-16-host-schedule-storage.md)). -All distinct overdue Every records participate in one batch, each with one latest occurrence and one shared `acceptedAt`. There is no cross-record cooldown, gate, quota, or retained batch timestamp. A five-minute minimum bounds wake and model-request frequency. If the next sequence point would exceed the four-digit-year storage range, dispatch terminates that record. +A five-minute minimum bounds wake and model-request frequency. There is no cross-record cooldown, gate, quota, or retained batch timestamp. If the next sequence point would exceed the four-digit-year storage range, dispatch terminates that record. -Calendar and Cron expressions are deliberately absent ([bounded recurrence simplification](../../archived/simplification/2026-08-09-bounded-fixed-rate-schedule.md)); supporting them would add a time-zone-sensitive calendar language, evaluator dependency, validation surface, and tzdata replay policy unrelated to fixed-rate reminders. +### Queue admission is not completion -### Live delivery lifecycle - -The Agent-scoped owner derives its earliest target from the durable fold. Long targets use bounded timer segments, and every wake reads the wall clock again, so a rollback cannot fire early and a forward jump becomes overdue. Due one-shots have priority and are admitted one at a time; otherwise every overdue Every record enters one batch in target and creation order. If a turn or maintenance task owns the Agent, `runMaintenance()` rejects the claim; the records stay active and one `whenIdle()` wait triggers another attempt. A rejected preflight or contained framing/enqueue failure also leaves them active without starting a private retry timer. - -The accepted path clears pending persistence and claims the true idle phase. It refolds the exact Session suffix, samples the decision clock, constructs fixed reminder framing with JSON-escaped values, synchronously queues one `followup()`, and appends dispatch before releasing maintenance. A one-shot appends an id-only terminal dispatch. A fixed-rate batch appends one `id + acceptedAt` transition per participating record. Waking input remains parked until release, so the message cannot be claimed before dispatch enters the log; afterward the owner checkpoints dispatch. - -Dispatch records queue admission, not model completion or user receipt. Framing or synchronous enqueue failure appends no dispatch. An append failure faults that owner because the message may already be queued. Agent or plugin disposal cancels timers, stops new work, unwinds tool registrations, and awaits in-flight work without deleting durable records. A crash after follow-up admission but before durable dispatch can repeat the reminder after recovery; the design makes no exactly-once promise. - -### Read-only Web catalog - -The Schedule overlay enables the otherwise-disabled [`dsh-client-ui-schedule`](../../../../packages/client/ui-schedule/README.md) client together with the Host service. The complete active projection also feeds [`dsh-client-ui-workspace`](../../../../packages/client/ui-workspace/README.md). This note owns that opt-in read-only presentation boundary: the projection is current active state, not a dispatch or delivery receipt, so ordinary Assistant turns remain the delivery presentation. The catalog is a fixed `document.body` portal whose left edge follows the trigger when space permits and shifts left to retain a 16px viewport margin near the right edge. `useAnchoredPosition` owns measurement and resize, captured-scroll, panel-resize, and cleanup behavior; Schedule supplies the trigger and portal refs, bottom placement, a 5px gap, and the existing inside/outside dismissal boundary without adding a general popover abstraction. +Dispatch records queue admission, not model completion or user receipt. Framing or synchronous enqueue failure appends no dispatch. A crash after follow-up admission but before the durable receipt can repeat the reminder after recovery; the design makes no exactly-once promise. ## Alternatives considered -**Use `ctx.jobs`.** Jobs own process-local work, outcomes, and notifications rather than Session-log state and conversation follow-ups. - -**Store reminders in a private database or global scheduler.** This could run cold Sessions but requires a second identity map, startup scan, ownership lease, crash protocol, and notification policy. +**Use `ctx.jobs`.** Jobs own process-local work, outcomes, and notifications rather than durable task state and conversation follow-ups. **Persist a Session time zone and infer local `at`.** This spreads one interpretive default through Session core, Host create/fork, persistence formats, clients, and mismatch recovery. Request-local model guidance plus an explicit tool boundary deletes that coupling. -**Keep an independent durable Web receipt.** Dispatch is an internal queue fact, not the user's reminder. Rendering the ordinary assistant answer avoids a second delivery meaning and removes Schedule code from Host and client layers. +**Claim dispatch before `followup()` or add exactly-once fencing.** Claim-first can silently lose a reminder when enqueue fails. Cross-process exactly-once needs a lease, outbox, acknowledgement, and downstream idempotency boundary outside this design. -**Add a general recurring-rule engine.** Fixed-duration intervals need only anchor arithmetic. A shared recurrence abstraction, global admission gate, and calendar evaluator would enlarge replay and runtime state without serving the retained product behavior. - -**Claim dispatch before `followup()` or add exactly-once fencing.** Claim-first can silently lose a reminder when enqueue fails. Cross-process exactly-once needs a lease, outbox, acknowledgement, and downstream idempotency boundary outside this Session-local scope. - -**Adopt existing roots or register global tools.** Late adoption makes plugin load order activate unseen timers and exposes tools outside the supported root composition. +**Add a general recurring-rule engine for fixed intervals.** Fixed-duration intervals need only anchor arithmetic. A shared recurrence abstraction, global admission gate, and calendar evaluator would enlarge replay and runtime state without serving fixed-rate behavior. The cron selector is a separate wall-clock rule with its own Host-owned dialect and evaluation ([cron input](../../../../docs/subsystems/schedule.md#cron-wall-clock-input)). ## Verification -Package tests pin strict replay, one-shot and Every transitions, creation-anchor arithmetic, latest-only catch-up, multi-record batching, fork suffixes, id reuse, offset and local-calendar profiles, IANA validation, daylight-saving gaps and overlaps, time bounds, timer segmentation, wall-clock movement, overdue admission, fixed framing, enqueue and append failures, barrier recovery, projection registration and restoration, registration rollback, and quiescent disposal at per-file 100% coverage. A property test compares Every calculation and replay across varied intervals and skipped spans. A production JSONL restart test proves one overdue reminder dispatches through the real Agent lifecycle and does not redispatch after another restart. Focused client suites own catalog and sidebar behavior, including the body portal, spacious left alignment, portal-inside pointer handling, outside dismissal, Escape, live empty, and timer cleanup. The shared primitive suite owns the positioning hook's resize, captured-scroll, panel-resize, and cleanup lifecycle. Keyless assembled Web scenarios retain ordinary After/At/Every delivery evidence plus one 900×900 Schedule-catalog smoke for overlay reachability, fixed portal placement, right-edge clamping, width and overflow, ordinary/search alarms, narrow dark layout, a light-theme browser screenshot, and one live empty update. +Package tests pin fixed-rate arithmetic, creation anchors, latest-only catch-up, batch selection, IANA validation, daylight-saving gaps and overlaps, and time bounds at per-file 100% coverage. A property test compares Every calculation and replay across varied intervals and skipped spans. ## Consequences -- Reminder state survives restart through ordinary Session persistence without a new database or public service. -- Cold Sessions do no work and send no external notification; reopening one may deliver overdue work. - Absolute input is deterministic without persistent Session-zone state or a dependency from Schedule to time-context. -- Users see normal conversation output; dispatch never overstates model success or acknowledgement. -- Opt-in Web users can inspect the complete active set and recognize cache-known active Sessions in ordinary or search rows without creating a second durable state, runtime signal, or delivery meaning. -- Each live root adds only fold-derived timers, an optional idle wait, and one in-flight operation. -- Fixed-rate recurrence is bounded by a five-minute minimum, latest-only catch-up, and one batched occurrence per overdue record; calendar recurrence remains outside this product boundary. +- A fixed interval stays aligned to its creation anchor, presents one occurrence per overdue record, and cannot accumulate a replay backlog. +- Delivery never overstates model success or acknowledgment, and a crash between queue admission and the durable receipt can repeat a message. diff --git a/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.zh.md b/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.zh.md index 8d84be3e35..dec8916db7 100644 --- a/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.zh.md +++ b/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.zh.md @@ -1,93 +1,49 @@ -# Agent Note: 持久、仅限 Session 内的提醒 +# Agent Note: 持久定时提醒 Status: implemented [English](2026-08-05-durable-web-schedule.md) | 中文 +[Host 拥有的定时消息决策](../architecture/2026-09-16-host-schedule-storage.zh.md)拥有任务存储、timer 激活、投递、发送记录和任务目录。本记录拥有在该决策之下仍然成立的两个时间决策——显式绝对时间边界与有界固定速率计算——以及二者共有的队列准入边界。 + ## 问题 -在对话中创建的提醒必须始终归属于确切的那个 Session,并且跨进程重启存活。进程本地 timer 或 inbox 项无法提供这种持久性,而全局 scheduler 或私有数据库又会引入第二套身份、持久化和生命周期系统。 - -繁忙的 Agent(智能体)、长等待、墙钟变化、cold Session、fork、持久化失败、绝对日历输入和资源释放,使简单 timeout 无法满足要求。设计必须区分持久记录与可丢弃的 live wait,阻止 fork 继承父 Session 的活动提醒,并避免把 Schedule 专属的呈现或时区状态扩散到无关组件。 +在对话中创建的提醒必须始终归属于确切的那个 Session,并且跨进程重启存活。繁忙的 Agent(智能体)、长等待、墙钟变化、cold Session 和持久化失败使简单 timeout 无法满足要求。绝对日历输入与重复唤醒带来两个计时问题,而存储与激活方式的选择并不能回答它们:当重复规则不保存时区时,绝对时间意味着什么;固定间隔在停机后如何追赶,而不重放每一个错过的发生时点。 ## 决策 -[Schedule 指南](../../../../docs/user/guide/schedule.zh.md)使用显式加载 `@deepseek-ai/dsh-time-context` 与 `@deepseek-ai/dsh-schedule`,并启用 Web bundle 中默认 disabled 的 `ui-schedule` row 的 overlay。默认 Web 启动图不会激活 Schedule。Schedule 只观察插件加载后发布的根 Agent,并在该 Agent scope 中安装三个工具和一个可丢弃 owner。cold history 读取、已发布的根、child Agent 与其他 host 都不会激活 runtime。 - -用户可见边界是 `session-local`:原 Session 只有在 live 时才会准时运行提醒,cold 期间不发送任何外部通知;该 Session 再次 live 后才会处理 overdue 提醒。到期工作会等待 Agent 完全 idle,再通过 `followup()` 进入普通的下一轮队列;它绝不会中途引导当前轮次,也没有独立 Web 回执([对话式交付](../../archived/simplification/2026-08-09-conversational-schedule-delivery.md))。 - -| 场景 | 持久事实 | live 行为 | 用户可见结果 | -| --- | --- | --- | --- | -| 创建与管理 | 原 Session 中的 `schedule/change` create/delete | Agent-scoped 工具在读取前、变更后执行 checkpoint | 稳定 id、UTC 目标、状态与 `session-local` 说明 | -| 到期时繁忙 | 活动 create 仍在 fold 中 | owner 等待 idle maintenance,排入一个 follow-up,再追加 dispatch | 后续一个普通对话轮次 | -| 多条 Every 记录逾期 | 每条活动记录都保留最早一个尚未接受且与锚点对齐的目标 | 一次决策选择每条记录的最新发生时点,并将其推进到当前时刻之后 | 一个普通 follow-up,其中每条记录各有一个发生时点 | -| 进程停止或 Session cold | 活动 create 仍在 persistence 中 | 不存在 timer 或后台扫描;resume 重建 owner | 未来目标继续等待;overdue 目标会被尝试 | -| fork | 父 event 留在继承前缀 | child fold 从精确 `inheritedEventCount` 开始 | 父工作不会在 child 中变为活动状态 | - -### Session 日志权威与工具 - -版本 1 `schedule/change` stream 是唯一持久的 Schedule 权威。create 记录拥有一个 Session 内不复用的品牌 id、trim 后的提示词、规则判别字段和 UTC 目标。delete 与一次性 dispatch 是终结转换。Every dispatch 会存储 id 与决策时点,使 fold 将该记录直接推进到错过的发生时点之后。严格 decoder 与纯 fold 会拒绝未知版本、额外字段、重复使用的 id、形状不匹配的 dispatch,以及针对非活动记录的转换。普通 Session 折叠完整 stream;fork 只折叠传入 projection 初始化的 `inheritedEventCount` 位置及其后的 event。 - -`ctx.sessionProjections` 存在时,Schedule 会注册一个复用同一 transition 的严格单元,并发布完整的活动 `ScheduleRecord[]`;共享的 [projection state 决策](../../archived/architecture/2026-08-19-session-projection-state-and-client-views.md)拥有其初始化与 restore 约定。损坏的持久输入会使既有读取路径失败,而不会产生部分数组。浏览器安全的记录词汇通过纯类型子路径 `@deepseek-ai/dsh-schedule/client` 暴露。 - -当前规则 union 接受非空提示词和恰好一个 selector。`after_seconds` 是正的安全整数 delay,其记录为 `{ id, kind: 'after', prompt, afterSeconds, scheduledAt }`。`at` 可以是带 `Z` 或数值偏移量且严格符合 RFC 3339 的值,也可以是带显式时区的结构化 `{ date, time, time_zone }`;其记录为 `{ id, kind: 'at', prompt, scheduledAt }`。`every_seconds` 是不小于 300 的安全整数,其 `{ id, kind: 'every', prompt, everySeconds, scheduledAt }` 记录始终与从创建时刻加一个间隔开始的序列对齐。一次性 dispatch 只存储 id;Every dispatch 存储 `id + acceptedAt`。工具值派生 `scheduled` 或 `overdue`,并包含 `deliveryMode: 'session-local'`。 - -一个 Agent-scoped FIFO 会将管理事务与 live owner 的到期事务从 preflight 到 post-append barrier 全程串行化。每项工具读取都会先等待 `ctx.sessions.flush(session)`。create 会尽可能在进入 FIFO 前拒绝输入形状错误,随后执行 preflight、分配 id、追加记录并再次 checkpoint。delete 会在进入 FIFO 前验证 id,在判断其是否活动前执行 preflight,并且只在追加后再次 checkpoint。list 与 not-found delete 绝不会根据未经确认的 live 后缀作答。barrier 失败会返回 `persistence_uncertain`,而不是猜测 eager write 是否已经提交。 - -每次成功的管理 preflight 也会要求 live owner 重新计算。因此,如果先前的 post-append 被拒绝,后续 list 可以确认保留的 create 并将其 arm,而无需私有的 persistence 重试 timer。 - ### 显式绝对时间边界 自然语言解释与 Schedule 解析被有意分开([时区简化](../simplification/2026-08-09-explicit-schedule-time-zone.zh.md))。每条浏览器提示词只在其对应的持久 user message 上携带由 Host 校验过的 IANA 时区。Time-context 会告诉模型,把未明确限定时区的日期和时间解释为该时区。Schedule 既不导入该插件,也不存储 Session 时区:模型必须把其解释结果转换为带偏移量的 RFC 3339 值,或带显式 `time_zone` 的本地对象。 -Schedule 会校验精确的日历形状、偏移量、时区名称,以及一个严格位于未来、年份为四位数的时点。落在夏令时缺口内的本地时间会被拒绝;遇到重叠时会选择第一次出现的较早时点。创建成功后只存储规范化后的 UTC `scheduledAt`,不会存储原始偏移量、本地字段或时区。 +Schedule 会校验精确的日历形状、偏移量、时区名称,以及严格位于未来、年份为四位数的时点。结构化本地时间落在夏令时缺口内会被拒绝;遇到重叠时选择第一次出现的较早时点。一次性 `at` 或 `after` 记录只存储规范化的 UTC `scheduledAt`,不存储输入的偏移量、本地字段或时区。`daily`、`weekly` 或 `cron` 记录则存储规范化后的本地规则及其显式 `timeZone`([时间选择器](../../../../packages/schedule/schedule/README.zh.md))。 ### 有界固定速率语义 -Every 是固定时长间隔,而不是日历规则。第一个目标是创建时刻加上一个间隔。作出到期决策时,整数除法会选出不晚于所采样墙钟的最新序列点,以及其后的第一个序列点。选中的发生时点只呈现一次,记录会直接推进到未来目标,因此 cold Session 绝不会积累回放任务,延迟执行的模型工作也绝不会使该序列漂移。 +Every 是固定时长间隔,而不是日历规则。其首个目标是创建时刻加上该间隔。作出到期决策时,整数除法选出不晚于所采样墙钟的最新序列点,以及其后的第一个序列点。选中的发生时点只呈现一次,记录直接推进到未来目标,因此 cold Session 绝不会积累回放任务,延迟执行的模型工作也绝不会使该序列漂移。同一 Session 内到期的 Every、Daily、Weekly 和 Cron 记录共用一条消息,每条记录只贡献其最新一次发生时点([存储与投递](../architecture/2026-09-16-host-schedule-storage.zh.md))。 -所有不同的逾期 Every 记录都会参与同一个批次,每条记录各自提供一个最新发生时点,并共享同一个 `acceptedAt`。系统不存在跨记录的冷却、门控、配额或保留的批次时间戳。至少 5 分钟的限制约束了唤醒与模型请求频率。如果下一个序列点会超出四位年份存储范围,dispatch 会终结该记录。 +至少五分钟的下限约束唤醒与模型请求频率。系统不存在跨记录的冷却、门控、配额或保留的批次时间戳。如果下一个序列点会超出四位年份存储范围,dispatch 会终结该记录。 -日历表达式与 Cron 表达式被有意排除([有界周期性简化](../../archived/simplification/2026-08-09-bounded-fixed-rate-schedule.md));支持这些表达式需要增加时区敏感的日历语言、求值器依赖、校验范围和 tzdata 回放策略,而这些都与固定速率提醒无关。 +### 队列准入不是完成 -### Live 交付生命周期 - -Agent-scoped owner 从持久 fold 派生最早目标。超长目标使用有界 timer 分段,每次 wake 都会重新读取墙钟,因此回拨不会提前触发,前跳则会形成 overdue。已到期的一次性提醒优先,每次准入一条;否则,所有逾期 Every 记录会按目标时间和创建顺序进入同一个批次。如果 Agent 已被某个轮次或另一项 maintenance task 占用,`runMaintenance()` 会拒绝此次认领;这些记录保持活动,并由一次 `whenIdle()` wait 触发另一次尝试。被拒绝的 preflight 或被收容的 framing/入队失败同样会使其保持活动,但不会启动私有重试 timer。 - -获得准入的路径会刷新所有 pending persistence 并认领真正的 idle phase。它会重新折叠确切的 Session 后缀、采样 decision clock、用经过 JSON 转义的值构造固定提醒 framing、同步排入一个 `followup()`,并在释放 maintenance 前追加 dispatch。一次性提醒会追加只含 id 的终结 dispatch。固定速率批次会为每条参与记录追加一个 `id + acceptedAt` 转换。触发唤醒的 input 会保持 parked,直到 maintenance 释放,因此在 dispatch 进入日志前,消息不会被认领;随后 owner 会为 dispatch 执行 checkpoint。 - -dispatch 记录的是队列准入,而不是模型完成或用户收到提醒。framing 构造或同步入队失败不会追加 dispatch。append 失败会使该 owner fault,因为消息可能已经入队。Agent 或插件 dispose 会取消 timer、停止新工作、撤销工具注册,并等待进行中的工作,且不会删除持久记录。follow-up 获得准入后、持久 dispatch 前发生崩溃,可能使提醒在恢复后重复;本设计不作 exactly-once 承诺。 - -### 只读 Web 目录 - -Schedule overlay 会把默认禁用的 [`dsh-client-ui-schedule`](../../../../packages/client/ui-schedule/README.zh.md) client 与 Host 服务一同启用。完整活动 projection 也会交给 [`dsh-client-ui-workspace`](../../../../packages/client/ui-workspace/README.zh.md)。本 Note 拥有这条 opt-in 只读呈现边界:该 projection 表示当前活动状态,而非 dispatch 或交付回执,因此普通 Assistant 轮次仍是交付呈现。目录是挂到 `document.body` 的 fixed portal;空间足够时左边缘跟随触发按钮,靠近视口右侧时向左避让并保留 16px 边距。`useAnchoredPosition` 拥有测量以及 resize、捕获阶段 scroll、面板 resize 与清理行为;Schedule 提供触发器与 portal ref、bottom 放置、5px 间距和既有内外 dismissal 边界,不增加通用 popover 抽象。 +dispatch 记录的是队列准入,而不是模型完成或用户收到提醒。framing 构造或同步入队失败不会追加 dispatch。follow-up 获得准入后、持久回执前发生崩溃,可能使提醒在恢复后重复;本设计不作 exactly-once 承诺。 ## 已考虑的替代方案 -**使用 `ctx.jobs`。** Task 拥有进程本地工作、结果和通知,而不是 Session 日志状态和对话 follow-up。 - -**把提醒存入私有数据库或全局 scheduler。** 这样可以运行 cold Session,却需要第二套身份映射、启动扫描、ownership lease、崩溃协议和通知策略。 +**使用 `ctx.jobs`。** Task 拥有进程本地工作、结果和通知,而不是持久任务状态和对话 follow-up。 **持久化 Session 时区并推断本地 `at`。** 这会让一个解释默认值扩散到 Session core、Host create/fork、持久化格式、client 和不匹配恢复中。请求本地的模型指导与显式工具边界消除了这种耦合。 -**保留独立的持久 Web 回执。** dispatch 是内部队列事实,而不是用户的提醒。渲染普通 assistant 回答既避免了第二种交付含义,也从 Host 与 client 层移除了 Schedule 代码。 +**在 `followup()` 前认领 dispatch,或增加 exactly-once fencing。** claim-first 会在入队失败时静默丢失提醒。跨进程 exactly-once 需要 lease、outbox、acknowledgement 与下游幂等边界,超出了本设计范围。 -**增加通用周期规则引擎。** 固定时长间隔只需要锚点运算。共享的周期抽象、全局准入门控和日历求值器会扩大回放与运行时状态,却不能服务于保留的产品行为。 - -**在 `followup()` 前认领 dispatch,或增加 exactly-once fencing。** claim-first 会在入队失败时静默丢失提醒。跨进程 exactly-once 需要 lease、outbox、acknowledgement 与下游幂等边界,超出了此 Session-local 范围。 - -**接管既有根或注册全局工具。** 晚接管会让插件加载顺序激活不可见的 timer,并把工具暴露到受支持的根组合之外。 +**为固定间隔增加通用周期规则引擎。** 固定时长间隔只需要锚点运算。共享的周期抽象、全局准入门控和日历求值器会扩大回放与运行时状态,却不能服务于固定速率行为。cron 选择器是独立的钟表规则,拥有自己的 Host 所有方言与求值([cron 输入](../../../../docs/subsystems/schedule.zh.md#cron-wall-clock-input))。 ## 验证 -包测试以逐文件 100% coverage 固定严格回放、一次性与 Every 状态转换、创建锚点运算、只追赶最新一次、多记录批处理、fork 后缀、id 复用、偏移量与本地日历 profile、IANA 校验、夏令时缺口与重叠、时间边界、timer 分段、墙钟变化、overdue 准入、固定 framing、入队与 append 失败、barrier 恢复、projection 注册与恢复、注册 rollback 和完全停稳的 dispose。属性测试会在不同间隔与跳过跨度下比较 Every 计算与回放。production JSONL restart 测试证明一条 overdue 提醒会经过真实 Agent 生命周期 dispatch,并且再次 restart 后不会重复 dispatch。聚焦 client suite 拥有目录与侧边栏行为,包括 body portal、空间充足时的左对齐、portal 内指针处理、外部 dismissal、Escape、live empty 与 timer 清理。共享 primitive suite 拥有定位 hook 的 resize、捕获阶段 scroll、面板 resize 与清理生命周期。无密钥组装 Web 场景保留普通 After/At/Every 交付证据,再由一个 900×900 Schedule 目录 smoke 覆盖 overlay 可达性、fixed portal 定位、右侧钳制、宽度与 overflow、普通/搜索闹钟、窄屏暗色布局、浅色主题浏览器截图与一次 live empty 更新。 +包测试以逐文件 100% coverage 固定固定速率计算、创建锚点、只追赶最新一次、批次选择、IANA 校验、夏令时缺口与重叠以及时间边界。属性测试会在不同间隔与跳过跨度下比较 Every 计算与回放。 ## 后果 -- 提醒状态通过普通 Session persistence 跨重启存活,无需新数据库或公开 service。 -- cold Session 不工作、不发送外部通知;重新打开后可能交付 overdue 工作。 - 无需持久 Session 时区状态或从 Schedule 到 time-context 的依赖,绝对时间输入仍然具有确定性。 -- 用户看到普通对话输出;dispatch 绝不会夸大模型成功或 acknowledgement。 -- 显式启用 Schedule 的 Web 用户可以查看完整活动集合,并在普通行或搜索结果中辨认 cache 已知的活动 Session,而不会引入第二份持久状态、runtime 信号或第二种交付含义。 -- 每个 live 根只增加从 fold 派生的 timer、可选 idle wait 与一个 in-flight operation。 -- 固定速率周期性受到至少 5 分钟、只追赶最新一次,以及每条逾期记录只在一个批次中贡献一个发生时点的约束;日历周期性仍在此产品边界之外。 +- 固定间隔始终与其创建锚点对齐,每条逾期记录只呈现一个发生时点,且不会积累回放任务。 +- 投递绝不会夸大模型成功或 acknowledgement;队列准入与持久回执之间发生崩溃可能使消息重复。 diff --git a/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.i18n.yaml b/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.i18n.yaml index ff0246f556..8862a5bc60 100644 --- a/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-06-continuable-subagent-interrupt.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.md -2026-08-06-continuable-subagent-interrupt.md: e865415bbba4ea196afd7d075a079412f18e5a1e -2026-08-06-continuable-subagent-interrupt.zh.md: ed4981bdac12a5c8b09b2e8dbc6363817e4d7dea +/agent-note-continuable-subagent-current-turn-interrupt: + en: 0940bfeaf12caf8c + zh: e6a1da625950371d +/agent-note-continuable-subagent-current-turn-interrupt/problem: + en: be2b1e9ef5bb2511 + zh: 36c7ee54c37c0700 +/agent-note-continuable-subagent-current-turn-interrupt/decision: + en: db543685b2fd2f88 + zh: fcc848c04036253c +/agent-note-continuable-subagent-current-turn-interrupt/alternatives-considered: + en: e7e953783cc4a332 + zh: be5d47a503b47170 +/agent-note-continuable-subagent-current-turn-interrupt/consequences: + en: 8e75516b07cdc842 + zh: 10e31033e14241e7 +/agent-note-continuable-subagent-current-turn-interrupt/testing: + en: e46413bc89f9238e + zh: 4fb1639ae696e9a4 diff --git a/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.md b/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.md index e865415bbb..3da06ff860 100644 --- a/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.md +++ b/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.md @@ -41,7 +41,7 @@ The address-only RPC exposes one bit of live residency: an absent target is acce The Web surface keeps Send and Stop as independent actions for a running continuable child: the client `Session.cancel()` routes Stop through `subagent.interrupt` (one-shot addresses stay uncancellable, ordinary sessions keep their existing primary Send/Stop toggle through `session.cancel`), while Send delivers follow-ups through the busy-Enter setting's mode — Queue by default, Steer when selected — exactly as plain Enter does ([busy Send button](../bug-fix/2026-09-04-busy-send-button-follows-enter-setting.md)). A running parent-offline continuable child keeps the default composer with input and Send disabled but Stop reachable, returning to the read-only takeover once it stops ([Web subagent conversations](2026-07-27-web-subagent-conversations.md) owns the surrounding catalog and composer contract). -The model-facing `interrupt_agent(agent_id)` tool in `dsh-tool-subagent-control` passes `exec.agent` as the `ancestor` authority and adds none of its own: the core primitive verifies live registry identity and recorded lineage, so the tool can name a direct child or a deeper descendant with the same generic `agent_id` parameter — deliberately not `subagent_id`, which would imply direct children only. Discovery rides `list_agents({ scope: 'descendants' })` over the new `SubagentRuntime.listDescendants()` one-trace pre-order walk with verified `parentId`/`depth` per entry ([durable catalog note](../../archived/feature/2026-07-22-durable-subagent-catalog-and-list-agents.md) owns the listing contract); discovery is a hint, never authority. `send_message` keeps its exact-direct-parent authority — only interrupt is ancestor-wide. +The model-facing `interrupt_agent(agent_id)` tool in `dsh-tool-subagent-control` passes `exec.agent` as the `ancestor` authority and adds none of its own: the core primitive verifies live registry identity and recorded lineage, so the tool can name a direct child or a deeper descendant with the same generic `agent_id` parameter — deliberately not `subagent_id`, which would imply direct children only. Discovery rides `list_agents({ scope: 'descendants' })` over the `SubagentRuntime.listDescendants()` recursive catalog walk with `parentId`/`depth` per entry ([parent-catalog note](../architecture/2026-09-01-parent-owned-subagent-catalog.md) owns discovery); discovery is a hint, never authority. `send_message` keeps its exact-direct-parent authority — only interrupt is ancestor-wide. ## Testing diff --git a/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.zh.md b/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.zh.md index ed4981bdac..0ef423905c 100644 --- a/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.zh.md +++ b/.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.zh.md @@ -41,7 +41,7 @@ Host RPC `subagent.interrupt` 接收 continuable 的 `SubagentAddress` 并返回 在 Web 侧,正在运行的 continuable child 使用相互独立的 Send 与 Stop 操作:客户端 `Session.cancel()` 将 Stop 路由到 `subagent.interrupt`(one-shot 地址保持不可取消,普通会话仍通过 `session.cancel` 保留既有的 primary Send/Stop 切换),同时 Send 按繁忙态 Enter 设置的模式投递后续消息——默认 Queue,选择后为 Steer——与 plain Enter 完全一致([繁忙态 Send 按钮](../bug-fix/2026-09-04-busy-send-button-follows-enter-setting.zh.md))。parent 离线但仍在运行的 continuable child 保留默认 composer,禁用输入区与 Send,但 Stop 仍然可达;停止后恢复为只读接管界面(周边目录与 composer 约定由 [Web subagent 对话](2026-07-27-web-subagent-conversations.zh.md)拥有)。 -`dsh-tool-subagent-control` 中面向模型的 `interrupt_agent(agent_id)` 工具把 `exec.agent` 作为 `ancestor` 授权传入,自身不增加任何权限:核心原语校验在线注册表身份与记录的 lineage,因此该工具可以用同一个通用 `agent_id` 参数指定直接 child 或更深的后代——刻意不用会暗示仅限直接 child 的 `subagent_id`。发现依赖 `list_agents({ scope: 'descendants' })`,其底层是新的 `SubagentRuntime.listDescendants()` 单次追踪 pre-order 遍历,每个条目带经校验的 `parentId`/`depth`(列表约定由[持久化目录 note](../../archived/feature/2026-07-22-durable-subagent-catalog-and-list-agents.md)拥有);发现只是提示,绝非权限。`send_message` 保持其确切直接 parent 权限——只有中断是 ancestor 级的。 +`dsh-tool-subagent-control` 中面向模型的 `interrupt_agent(agent_id)` 工具把 `exec.agent` 作为 `ancestor` 授权传入,自身不增加任何权限:核心原语校验在线注册表身份与记录的 lineage,因此该工具可以用同一个通用 `agent_id` 参数指定直接 child 或更深的后代——刻意不用会暗示仅限直接 child 的 `subagent_id`。发现依赖 `list_agents({ scope: 'descendants' })`,其底层是 `SubagentRuntime.listDescendants()` 递归目录遍历,每个条目带 `parentId`/`depth`(发现机制由[父目录 note](../architecture/2026-09-01-parent-owned-subagent-catalog.zh.md)拥有);发现只是提示,绝非权限。`send_message` 保持其确切直接 parent 权限——只有中断是 ancestor 级的。 ## 测试 diff --git a/.agents/notes/implemented/feature/2026-08-06-manager-owned-subagent-settlement-delivery.i18n.yaml b/.agents/notes/implemented/feature/2026-08-06-manager-owned-subagent-settlement-delivery.i18n.yaml index a8b84e3d55..c405aca74b 100644 --- a/.agents/notes/implemented/feature/2026-08-06-manager-owned-subagent-settlement-delivery.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-06-manager-owned-subagent-settlement-delivery.i18n.yaml @@ -1,6 +1,43 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-06-manager-owned-subagent-settlement-delivery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-06-manager-owned-subagent-settlement-delivery.md -2026-08-06-manager-owned-subagent-settlement-delivery.md: 7f6cfc90862b5bb32368b4b0e1fbe068ba0cbf66 -2026-08-06-manager-owned-subagent-settlement-delivery.zh.md: 23c5506f79d4d95308b0533e8d507ac856c4d85e +/agent-note-settlement-delivery-belongs-to-the-continuation-manager: + en: e8e4fec15acfe5d4 + zh: 6dac0279cf244edc +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/problem: + en: 325f283354af59f6 + zh: 059179e883da78c2 +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/decision: + en: 472a34f28ed5200a + zh: 70dcbbd2e26dc32f +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/decision/closing-text: + en: 229151705efda8a9 + zh: b4e94b52280a2076 +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/decision/runtime-source: + en: b2e4931dfb6c21b1 + zh: 9bf619cd5b697e68 +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/decision/two-ordering-rules-and-why-the-manager-owns-them: + en: 34fad866d5c6377b + zh: e865e2cb70c3e00a +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/decision/establishment-holds-ownership-open: + en: bcaf3f22ba44fa01 + zh: d7b0968990f41a66 +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/decision/scheduling: + en: 3d1862329727a379 + zh: 92fcf4ffd366ea30 +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/decision/the-epoch-s-own-log-is-the-whole-account: + en: f444a596a75f0180 + zh: ec9c0b61a38a3458 +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/decision/snapshot-coverage: + en: 9e50e4014df1d5b0 + zh: 1a111b53a149a21b +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/alternatives-considered: + en: dd3073a05a8e13bd + zh: e58debc18a591077 +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/consequences: + en: 10ebfbc70ff94e20 + zh: c32a335007de89d1 +/agent-note-settlement-delivery-belongs-to-the-continuation-manager/consequences/accepted-risks: + en: 615cd09443411b4d + zh: f74b5dcab43975d3 diff --git a/.agents/notes/implemented/feature/2026-08-08-web-background-job-display.i18n.yaml b/.agents/notes/implemented/feature/2026-08-08-web-background-job-display.i18n.yaml index ce21dc1c9a..adc20bec51 100644 --- a/.agents/notes/implemented/feature/2026-08-08-web-background-job-display.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-08-web-background-job-display.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-08-web-background-job-display.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-08-web-background-job-display.md -2026-08-08-web-background-job-display.md: 1ebd600e4d423f95ad663c333572a990d0c9efa7 -2026-08-08-web-background-job-display.zh.md: 56d062b5079e15c90cffc30b538efe162bc19d9d +/agent-note-web-background-job-display: + en: 78eff738bc5ed554 + zh: c8a8a83853fa806b +/agent-note-web-background-job-display/problem: + en: 41ddca92193cbbf1 + zh: ec8f39ad20044d1c +/agent-note-web-background-job-display/decision: + en: 50058c6557e05f15 + zh: bbf35bb475474cd8 +/agent-note-web-background-job-display/decision/wire-shape: + en: 4d6b92cbfde80add + zh: d32e0421100eeb71 +/agent-note-web-background-job-display/decision/the-task-registry-change-feed: + en: a7a9416ab3b325dc + zh: 448820bad0224785 +/agent-note-web-background-job-display/decision/the-session-controller-carrier: + en: e9ef574e65e8fb7d + zh: d1a6e446c48a0921 +/agent-note-web-background-job-display/decision/the-client-mirror: + en: 6185994020e639ee + zh: df9b464f95c0f3e2 +/agent-note-web-background-job-display/decision/the-header-action: + en: 8985aa8f6ade32c3 + zh: 94ea0844ed8649b5 +/agent-note-web-background-job-display/decision/what-this-deliberately-does-not-do: + en: c9ff2d1fec1459d9 + zh: b28a573ca9fbb1c2 +/agent-note-web-background-job-display/alternatives-considered: + en: a648d1748674d866 + zh: 0f68b82476121c38 +/agent-note-web-background-job-display/testing: + en: f41d5017ea4beabb + zh: cb216dd1d802ebe2 +/agent-note-web-background-job-display/consequences: + en: 5204e04c3ed02d53 + zh: 9eaa9b52b69be7b2 diff --git a/.agents/notes/implemented/feature/2026-08-08-windows-acl-restricted-token-sandbox.i18n.yaml b/.agents/notes/implemented/feature/2026-08-08-windows-acl-restricted-token-sandbox.i18n.yaml index 65bc426f49..cfa5b6c2ad 100644 --- a/.agents/notes/implemented/feature/2026-08-08-windows-acl-restricted-token-sandbox.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-08-windows-acl-restricted-token-sandbox.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-08-windows-acl-restricted-token-sandbox.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-08-windows-acl-restricted-token-sandbox.md -2026-08-08-windows-acl-restricted-token-sandbox.md: 65780b9bba31605db02dc9be4c1b2454c74eb0f4 -2026-08-08-windows-acl-restricted-token-sandbox.zh.md: fe9aadb97b172d77d65ca6b0a843f05751075502 +/agent-note-windows-sandbox-rung-raw-acl-restricted-tokens-over-mxc-and-appcontainer: + en: cfc871213b6d8360 + zh: 18ff96c2272fee09 +/agent-note-windows-sandbox-rung-raw-acl-restricted-tokens-over-mxc-and-appcontainer/problem: + en: 86e01a1c009ac595 + zh: 91844972d41dd6f9 +/agent-note-windows-sandbox-rung-raw-acl-restricted-tokens-over-mxc-and-appcontainer/decision: + en: 125dea7427047966 + zh: 5d0bfd3921b38714 +/agent-note-windows-sandbox-rung-raw-acl-restricted-tokens-over-mxc-and-appcontainer/how-the-restriction-works-why-no-new-identity: + en: ac9b3d800889ea39 + zh: 9db1065b6027f65f +/agent-note-windows-sandbox-rung-raw-acl-restricted-tokens-over-mxc-and-appcontainer/alternatives-considered: + en: 6119e2aff3b6be5a + zh: 4237c596c10e1ee9 +/agent-note-windows-sandbox-rung-raw-acl-restricted-tokens-over-mxc-and-appcontainer/alternatives-considered/why-not-mxc-microsoft-xcontainer: + en: 0bb56896664ab257 + zh: de921ecab11cf572 +/agent-note-windows-sandbox-rung-raw-acl-restricted-tokens-over-mxc-and-appcontainer/alternatives-considered/why-not-appcontainer: + en: 6e7ed26630c25476 + zh: edd52735b36b0b12 +/agent-note-windows-sandbox-rung-raw-acl-restricted-tokens-over-mxc-and-appcontainer/alternatives-considered/why-not-landstrip: + en: e2c573d90c4ddeb9 + zh: f0259213e1321722 +/agent-note-windows-sandbox-rung-raw-acl-restricted-tokens-over-mxc-and-appcontainer/consequences: + en: b9f3a7c6890707f1 + zh: c9a344b50732c296 +/agent-note-windows-sandbox-rung-raw-acl-restricted-tokens-over-mxc-and-appcontainer/testing: + en: b223cb2cf13193c9 + zh: 61ddd0a0b99f8f56 +/agent-note-windows-sandbox-rung-raw-acl-restricted-tokens-over-mxc-and-appcontainer/related: + en: dd16f0c5815df991 + zh: df3c1cf511ee52bf diff --git a/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml index b4d5d4a95a..0841a07056 100644 --- a/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-10-subagent-approval-pinned-never.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.md -2026-08-10-subagent-approval-pinned-never.md: a21c6b966b1ad00ed63e0fe87b0ce982f0daf490 -2026-08-10-subagent-approval-pinned-never.zh.md: 32f367303559eecbfd5049cd370e48c8ce57de33 +/agent-note-delegated-subagents-run-with-approvals-pinned-to-never: + en: f38cf8f2c67fc976 + zh: a4b357a3452383c3 +/agent-note-delegated-subagents-run-with-approvals-pinned-to-never/problem: + en: fa1add8bd8bb3733 + zh: 35ac0951e676acaf +/agent-note-delegated-subagents-run-with-approvals-pinned-to-never/decision: + en: 2d2e42923663abc7 + zh: 5728346e7c5ea291 +/agent-note-delegated-subagents-run-with-approvals-pinned-to-never/alternatives-considered: + en: 32fe1eb5bd7cd5ab + zh: ea437edee4fbc1c6 +/agent-note-delegated-subagents-run-with-approvals-pinned-to-never/consequences: + en: 4503eecfc7f17fed + zh: 1f201ba769ec0354 diff --git a/.agents/notes/implemented/feature/2026-08-11-background-job-completion-wakes-an-idle-owner.i18n.yaml b/.agents/notes/implemented/feature/2026-08-11-background-job-completion-wakes-an-idle-owner.i18n.yaml index 3b96b194f6..562d31b711 100644 --- a/.agents/notes/implemented/feature/2026-08-11-background-job-completion-wakes-an-idle-owner.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-11-background-job-completion-wakes-an-idle-owner.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-11-background-job-completion-wakes-an-idle-owner.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-11-background-job-completion-wakes-an-idle-owner.md -2026-08-11-background-job-completion-wakes-an-idle-owner.md: f13f09d326dc7b4e7b2998f3124f70c185c50922 -2026-08-11-background-job-completion-wakes-an-idle-owner.zh.md: f9b563ebbf90e2ca19d1fc5ca9fa5b028e4429f1 +/agent-note-background-job-completion-wakes-an-idle-owner: + en: b761777a02303d0e + zh: a65eb415e75bcac5 +/agent-note-background-job-completion-wakes-an-idle-owner/problem: + en: da112fe20077acdf + zh: b0e3e099c3aacde5 +/agent-note-background-job-completion-wakes-an-idle-owner/decision: + en: c5d7901d87803d0c + zh: 8a1e473e88f3e400 +/agent-note-background-job-completion-wakes-an-idle-owner/decision/the-busy-owner-keeps-injection: + en: 841588bc73fc4613 + zh: 7fb4095bd55ee241 +/agent-note-background-job-completion-wakes-an-idle-owner/decision/the-cap-on-consecutive-wakes-is-opt-in-and-it-is-not-time: + en: fa9f572f763bc6b0 + zh: f3924fa49d2be22d +/agent-note-background-job-completion-wakes-an-idle-owner/decision/teardown-claims-the-report: + en: f79257596c755a32 + zh: 856bf42492425f9c +/agent-note-background-job-completion-wakes-an-idle-owner/decision/completion-is-announced-last: + en: 9cab013b3513f1e0 + zh: 78ea1b05df94d8a8 +/agent-note-background-job-completion-wakes-an-idle-owner/alternatives-considered: + en: debb2c9b924474c3 + zh: 90e2cefc230e3ec8 +/agent-note-background-job-completion-wakes-an-idle-owner/consequences: + en: a2a6f76c8cc92d57 + zh: 6eed3e6a5c75dfb9 +/agent-note-background-job-completion-wakes-an-idle-owner/consequences/accepted-risks: + en: 2141374aa4f79a2b + zh: acff1b68abf2db7e diff --git a/.agents/notes/implemented/feature/2026-08-11-deepseek-request-user-id-header.i18n.yaml b/.agents/notes/implemented/feature/2026-08-11-deepseek-request-user-id-header.i18n.yaml index 4d8cfe3580..8f60e2293e 100644 --- a/.agents/notes/implemented/feature/2026-08-11-deepseek-request-user-id-header.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-11-deepseek-request-user-id-header.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-11-deepseek-request-user-id-header.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-11-deepseek-request-user-id-header.md -2026-08-11-deepseek-request-user-id-header.md: 54f59a3f69a933af4f80d629f32f5089676263f6 -2026-08-11-deepseek-request-user-id-header.zh.md: 4904a08fcf4320211fd4253403bddda062bd496e +/agent-note-deepseek-request-user-and-session-identity-headers: + en: 6888d1c6a57a6839 + zh: e3817ccbcd782a44 +/agent-note-deepseek-request-user-and-session-identity-headers/problem: + en: fdeb3bc22bab88c0 + zh: 089ea4713776fb7a +/agent-note-deepseek-request-user-and-session-identity-headers/decision: + en: b168d3c975d191aa + zh: fdd92a1a92f87537 +/agent-note-deepseek-request-user-and-session-identity-headers/verification: + en: 3984cb1cb953605e + zh: 59e06d6eac8070d7 +/agent-note-deepseek-request-user-and-session-identity-headers/alternatives-considered: + en: 2233f9f6a934a48f + zh: c73d1db971239742 +/agent-note-deepseek-request-user-and-session-identity-headers/consequences: + en: 1621a8eab7787622 + zh: 636cf922cf76d2bc diff --git a/.agents/notes/implemented/feature/2026-08-11-minimal-profiles-bare-two-tool-runtime.i18n.yaml b/.agents/notes/implemented/feature/2026-08-11-minimal-profiles-bare-two-tool-runtime.i18n.yaml index 98786c2a8b..13d32374f6 100644 --- a/.agents/notes/implemented/feature/2026-08-11-minimal-profiles-bare-two-tool-runtime.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-11-minimal-profiles-bare-two-tool-runtime.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-11-minimal-profiles-bare-two-tool-runtime.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-11-minimal-profiles-bare-two-tool-runtime.md -2026-08-11-minimal-profiles-bare-two-tool-runtime.md: 8cfa4aa71e33317947d0661641df1e6e814f5e90 -2026-08-11-minimal-profiles-bare-two-tool-runtime.zh.md: f1f916bdde92fd104c3d879ff058b2e0474eef38 +/agent-note-minimal-profiles-use-a-bare-runtime: + en: b086c2a8d0fca111 + zh: 3c81b90a2818e7ff +/agent-note-minimal-profiles-use-a-bare-runtime/problem: + en: 725fe45436a65f26 + zh: 97f96497173bec4f +/agent-note-minimal-profiles-use-a-bare-runtime/decision: + en: ef9aa81743b6bc46 + zh: 86bcf7e3a7e34f4b +/agent-note-minimal-profiles-use-a-bare-runtime/verification: + en: c9d0b2145e4c1271 + zh: 186919163b20379c +/agent-note-minimal-profiles-use-a-bare-runtime/alternatives-considered: + en: 35b3346928cb6c3f + zh: 6e60d1073b5a95e3 +/agent-note-minimal-profiles-use-a-bare-runtime/consequences: + en: 462abbbe168de14c + zh: 13f9e257a5f18984 diff --git a/.agents/notes/implemented/feature/2026-08-15-product-subagent-noninteractive-permissions.i18n.yaml b/.agents/notes/implemented/feature/2026-08-15-product-subagent-noninteractive-permissions.i18n.yaml index 7e9849194b..c0058f198d 100644 --- a/.agents/notes/implemented/feature/2026-08-15-product-subagent-noninteractive-permissions.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-15-product-subagent-noninteractive-permissions.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-15-product-subagent-noninteractive-permissions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-15-product-subagent-noninteractive-permissions.md -2026-08-15-product-subagent-noninteractive-permissions.md: 1ec45f9adafa2364f9d0f37f3914d97054942226 -2026-08-15-product-subagent-noninteractive-permissions.zh.md: 80e99d9ee47da859456faf66560d42e73c88cf3d +/agent-note-product-subagents-use-profile-selected-non-interactive-permissions: + en: feb20636c72ade23 + zh: fd2e9f192a3fa527 +/agent-note-product-subagents-use-profile-selected-non-interactive-permissions/problem: + en: 905b54b06f35015a + zh: b0b3a79e9f92b33d +/agent-note-product-subagents-use-profile-selected-non-interactive-permissions/decision: + en: a4635e16af21d478 + zh: 6cd59ad7e2bb9885 +/agent-note-product-subagents-use-profile-selected-non-interactive-permissions/decision/claude-code: + en: dbbd5e37924de6f7 + zh: 33c327f0737894c4 +/agent-note-product-subagents-use-profile-selected-non-interactive-permissions/decision/codex: + en: 75114f6529699ebd + zh: 19dab70be62fb3d7 +/agent-note-product-subagents-use-profile-selected-non-interactive-permissions/decision/failure-diagnostic: + en: 5439f8ab6ad61d42 + zh: 4b3f9bee3794b2f2 +/agent-note-product-subagents-use-profile-selected-non-interactive-permissions/decision/ownership-and-lifecycle: + en: 987eec9a67ba131d + zh: 735399cd3ac78a45 +/agent-note-product-subagents-use-profile-selected-non-interactive-permissions/verification: + en: 16a02354fe427b8e + zh: 948225be10331c8d +/agent-note-product-subagents-use-profile-selected-non-interactive-permissions/alternatives-considered: + en: 7b6bbb52fd5e4cbc + zh: c8e7ab515cd6c0db +/agent-note-product-subagents-use-profile-selected-non-interactive-permissions/consequences: + en: 6e995471b4cb9ff4 + zh: 9baf59015a911310 diff --git a/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.i18n.yaml b/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.i18n.yaml index 792f97a11a..167308d649 100644 --- a/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-18-arbitrary-seq-session-fork.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-18-arbitrary-seq-session-fork.md -2026-08-18-arbitrary-seq-session-fork.md: c02ba6c1f24462224cb7f4f245d82063f29c4d61 -2026-08-18-arbitrary-seq-session-fork.zh.md: fe78e505313b2177435abd93e1d8056972b2646b +/agent-note-exact-event-session-forks-with-shared-crash-repair: + en: f75e952184cae150 + zh: 32c2519c85aa6822 +/agent-note-exact-event-session-forks-with-shared-crash-repair/problem: + en: e01b73d9d4b50c50 + zh: 14f7816869b76241 +/agent-note-exact-event-session-forks-with-shared-crash-repair/decision: + en: 0b7afc12950ce308 + zh: 384d26f698a344a7 +/agent-note-exact-event-session-forks-with-shared-crash-repair/alternatives-considered: + en: 49544ba70825c8e9 + zh: 41c7dceb9241fc5a +/agent-note-exact-event-session-forks-with-shared-crash-repair/consequences: + en: a829fc736a132d89 + zh: 03b116766bd44d64 +/agent-note-exact-event-session-forks-with-shared-crash-repair/testing: + en: f15e826fa12a4f55 + zh: fe053fa01304e072 diff --git a/.agents/notes/implemented/feature/2026-08-18-model-selected-subagent-routes.i18n.yaml b/.agents/notes/implemented/feature/2026-08-18-model-selected-subagent-routes.i18n.yaml index 5e0f82335f..2095b6be29 100644 --- a/.agents/notes/implemented/feature/2026-08-18-model-selected-subagent-routes.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-18-model-selected-subagent-routes.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-18-model-selected-subagent-routes.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-18-model-selected-subagent-routes.md -2026-08-18-model-selected-subagent-routes.md: 9cdbdbec3b79a93043fa6ae95a6a6dedf6072086 -2026-08-18-model-selected-subagent-routes.zh.md: 3b81f5417339325dd60884049a853d1094a9f1eb +/agent-note-model-selected-subagent-routes: + en: 1e719fd754836549 + zh: 603cce7a5f9ec6bd +/agent-note-model-selected-subagent-routes/problem: + en: f4010276228f4441 + zh: 50ac98640dbf519a +/agent-note-model-selected-subagent-routes/decision: + en: 39836773d1830515 + zh: 537c96bfa93573e7 +/agent-note-model-selected-subagent-routes/alternatives-considered: + en: 3b9fd91294fbfd27 + zh: 2854dd690ead3d15 +/agent-note-model-selected-subagent-routes/consequences: + en: 55969d3742da39ce + zh: a248167f9bb2fa4e +/agent-note-model-selected-subagent-routes/related-decisions: + en: 28c4eb2e90488ff0 + zh: ba59bb2fafdd4720 diff --git a/.agents/notes/implemented/feature/2026-08-20-unified-image-request-pipeline.i18n.yaml b/.agents/notes/implemented/feature/2026-08-20-unified-image-request-pipeline.i18n.yaml index 4f9e640fe2..6e1c636324 100644 --- a/.agents/notes/implemented/feature/2026-08-20-unified-image-request-pipeline.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-20-unified-image-request-pipeline.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-20-unified-image-request-pipeline.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-20-unified-image-request-pipeline.md -2026-08-20-unified-image-request-pipeline.md: b79eeb7d908d664362851c28bda64dab163aac89 -2026-08-20-unified-image-request-pipeline.zh.md: 444234715256c48167b0b45dbd8843a9c80079f7 +/agent-note-unified-normalized-attachments-request-versions-and-provider-files: + en: 79d1a6f50ac76c3d + zh: 9af0070009537602 +/agent-note-unified-normalized-attachments-request-versions-and-provider-files/problem: + en: 7ce3a351a1492dd0 + zh: 7c7e3bb6799822f8 +/agent-note-unified-normalized-attachments-request-versions-and-provider-files/decision: + en: 98e7aad889f5b79c + zh: 84b24f6fd9209fcf +/agent-note-unified-normalized-attachments-request-versions-and-provider-files/decision/provider-independent-normalized-attachment: + en: 75b1d3732f3a9d05 + zh: c8683df3c6f0c989 +/agent-note-unified-normalized-attachments-request-versions-and-provider-files/decision/deterministic-request-versions: + en: 8afa51d02643bd40 + zh: d27d9a5b09fc6d74 +/agent-note-unified-normalized-attachments-request-versions-and-provider-files/decision/stable-handles: + en: 1b204c138b0d8e6c + zh: 3d6a2e82372e6825 +/agent-note-unified-normalized-attachments-request-versions-and-provider-files/decision/deepseek-files-lifecycle: + en: b35a18963d122b21 + zh: faa21c45cef3555a +/agent-note-unified-normalized-attachments-request-versions-and-provider-files/decision/diagnostics: + en: e4c79434bedfc385 + zh: 9e7de1061629ef5e +/agent-note-unified-normalized-attachments-request-versions-and-provider-files/alternatives-considered: + en: 7bfd39c761549b85 + zh: 6ac48c5842f7df91 +/agent-note-unified-normalized-attachments-request-versions-and-provider-files/verification: + en: 7697f72ce5a7d969 + zh: 733ca1e0a05ae4ed +/agent-note-unified-normalized-attachments-request-versions-and-provider-files/consequences: + en: 1a6ef14a3e13b502 + zh: bc4ab273755b2739 diff --git a/.agents/notes/implemented/feature/2026-08-22-fire-and-forget-webhook-sessions.i18n.yaml b/.agents/notes/implemented/feature/2026-08-22-fire-and-forget-webhook-sessions.i18n.yaml index 3877584618..99cd729035 100644 --- a/.agents/notes/implemented/feature/2026-08-22-fire-and-forget-webhook-sessions.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-22-fire-and-forget-webhook-sessions.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-22-fire-and-forget-webhook-sessions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-22-fire-and-forget-webhook-sessions.md -2026-08-22-fire-and-forget-webhook-sessions.md: 08f718b8063c7ca0d78e93f547c0e0c33c183d07 -2026-08-22-fire-and-forget-webhook-sessions.zh.md: f015d993e61864bbc21d9d55fc331c25118fbde3 +/agent-note-fire-and-forget-webhook-sessions: + en: adb18c2b0d575306 + zh: 2605913ffe5bafaa +/agent-note-fire-and-forget-webhook-sessions/problem: + en: 394e062b7e8f31a0 + zh: bcb26075cf62115c +/agent-note-fire-and-forget-webhook-sessions/decision: + en: 08ff83adfec1a7da + zh: 871b9998631f22ac +/agent-note-fire-and-forget-webhook-sessions/provider-adapters: + en: 8eb2865f18fcf018 + zh: 1b73dfd634a8c07a +/agent-note-fire-and-forget-webhook-sessions/session-creation: + en: fbc57974dd81bf5a + zh: 1a4810df6b7a776f +/agent-note-fire-and-forget-webhook-sessions/alternatives-considered: + en: 59634068f7c22476 + zh: 844472f7a5e9de91 +/agent-note-fire-and-forget-webhook-sessions/verification: + en: e2a3192fc68b1ade + zh: 63c2b07bf5f32696 +/agent-note-fire-and-forget-webhook-sessions/consequences: + en: 8b40a7c91834a281 + zh: 882125d8070d77c1 diff --git a/.agents/notes/implemented/feature/2026-08-22-standard-acp-automation-controls.i18n.yaml b/.agents/notes/implemented/feature/2026-08-22-standard-acp-automation-controls.i18n.yaml index 872993adb4..b6b5b90bc1 100644 --- a/.agents/notes/implemented/feature/2026-08-22-standard-acp-automation-controls.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-22-standard-acp-automation-controls.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-22-standard-acp-automation-controls.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-22-standard-acp-automation-controls.md -2026-08-22-standard-acp-automation-controls.md: dd1e39b84f942417640f741f17a211276b67872c -2026-08-22-standard-acp-automation-controls.zh.md: 2d7160bda164949799652bc2e3e3ab95afdafb0c +/agent-note-standard-acp-v1-automation-controls: + en: e6a4b457afbf12ac + zh: b1d83f4892e05f99 +/agent-note-standard-acp-v1-automation-controls/problem: + en: ba88135e9528b4c7 + zh: 8bc1be92b1f5178e +/agent-note-standard-acp-v1-automation-controls/decision: + en: 0a2b2a83aca7d189 + zh: 8de789db33953283 +/agent-note-standard-acp-v1-automation-controls/per-session-ownership: + en: 5b98c5e68eccfe76 + zh: c22dc47ad8003f22 +/agent-note-standard-acp-v1-automation-controls/persistent-session-controls: + en: 122752f1cb116417 + zh: 96971bcc1fed4a8a +/agent-note-standard-acp-v1-automation-controls/standard-configuration-options: + en: 61cb15891965c67a + zh: a0a958094b60951f +/agent-note-standard-acp-v1-automation-controls/standard-mcp-mapping: + en: 57acbe1c89af4c6b + zh: 3417e3d4b1874d94 +/agent-note-standard-acp-v1-automation-controls/semantic-update-projection: + en: 8e5128cd34629af3 + zh: 6132e78ddf9b3cf9 +/agent-note-standard-acp-v1-automation-controls/alternatives-considered: + en: fc94c87f43787d95 + zh: 17850ecc35e6ab9d +/agent-note-standard-acp-v1-automation-controls/verification: + en: 08e2b98606d9d362 + zh: 99d6aef7c89e287f +/agent-note-standard-acp-v1-automation-controls/consequences: + en: 9f839d4720f07d28 + zh: 5164ae3eb5b52385 diff --git a/.agents/notes/implemented/feature/2026-08-24-activity-observation-seam.i18n.yaml b/.agents/notes/implemented/feature/2026-08-24-activity-observation-seam.i18n.yaml index 548e9f5b36..d5220cd2f4 100644 --- a/.agents/notes/implemented/feature/2026-08-24-activity-observation-seam.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-24-activity-observation-seam.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-24-activity-observation-seam.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-24-activity-observation-seam.md -2026-08-24-activity-observation-seam.md: 21fe08fd21ad95eec7a83f6f29b9b94514358bb9 -2026-08-24-activity-observation-seam.zh.md: ffb6766b3e5d226d324ea2894a6e3f758cf1932a +/agent-note-the-activity-observation-seam-ctx-activities-and-live-output-streaming-to-the-web-client: + en: 7fe6230c2327e0b5 + zh: 13a07f7926f6861c +/agent-note-the-activity-observation-seam-ctx-activities-and-live-output-streaming-to-the-web-client/problem: + en: 8b50b64ed5a852bd + zh: 21d651e0109dc641 +/agent-note-the-activity-observation-seam-ctx-activities-and-live-output-streaming-to-the-web-client/decision: + en: 88b51276287344bd + zh: 0827faa6c822e4a5 +/agent-note-the-activity-observation-seam-ctx-activities-and-live-output-streaming-to-the-web-client/decision/why-not-durable-session-events-the-control-stream-or-the-jobs-seam: + en: 58d884216caa6d85 + zh: aa47eb76bdb1ece0 +/agent-note-the-activity-observation-seam-ctx-activities-and-live-output-streaming-to-the-web-client/decision/two-cursor-regimes-kept-separate: + en: 7ab433f08fa6140a + zh: d001a90815b0156b +/agent-note-the-activity-observation-seam-ctx-activities-and-live-output-streaming-to-the-web-client/alternatives-considered: + en: 4462632fd94010c1 + zh: 01d1285f2ac6e42c +/agent-note-the-activity-observation-seam-ctx-activities-and-live-output-streaming-to-the-web-client/testing: + en: 26687866bbf7be90 + zh: 32dea8052bd5465b +/agent-note-the-activity-observation-seam-ctx-activities-and-live-output-streaming-to-the-web-client/consequences: + en: e975f4f2410e8619 + zh: 42f16406950a4d6f diff --git a/.agents/notes/implemented/feature/2026-08-24-user-authorized-subagent-model-routes.i18n.yaml b/.agents/notes/implemented/feature/2026-08-24-user-authorized-subagent-model-routes.i18n.yaml index 697f943349..75bb4b5177 100644 --- a/.agents/notes/implemented/feature/2026-08-24-user-authorized-subagent-model-routes.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-24-user-authorized-subagent-model-routes.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-24-user-authorized-subagent-model-routes.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-24-user-authorized-subagent-model-routes.md -2026-08-24-user-authorized-subagent-model-routes.md: ef6f90d2cc1ec79e1381d75fd8cc25c568af3067 -2026-08-24-user-authorized-subagent-model-routes.zh.md: 23519bfc6619718e1cbf98dbad65eccd90353c0a +/agent-note-user-authorized-subagent-model-routes: + en: 572df418f108d72b + zh: d17c31e1c4150155 +/agent-note-user-authorized-subagent-model-routes/problem: + en: 3238dfb7db7dfdd8 + zh: ec3bdd9a9da0a321 +/agent-note-user-authorized-subagent-model-routes/decision: + en: 0166e452a774ade5 + zh: 747061b9424b3610 +/agent-note-user-authorized-subagent-model-routes/alternatives-considered: + en: e41c17226190ea8b + zh: d3b1395fafe75f01 +/agent-note-user-authorized-subagent-model-routes/consequences: + en: f1927d31ffc1dee9 + zh: b0fed04b80043c71 +/agent-note-user-authorized-subagent-model-routes/related-decisions: + en: 0b54fad7171103ec + zh: 8cf1d007a42fb991 diff --git a/.agents/notes/implemented/feature/2026-08-25-feedback-gated-telemetry-default.i18n.yaml b/.agents/notes/implemented/feature/2026-08-25-feedback-gated-telemetry-default.i18n.yaml index 511e99e65e..ee45f9f6ea 100644 --- a/.agents/notes/implemented/feature/2026-08-25-feedback-gated-telemetry-default.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-25-feedback-gated-telemetry-default.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-25-feedback-gated-telemetry-default.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-25-feedback-gated-telemetry-default.md -2026-08-25-feedback-gated-telemetry-default.md: 1a5ecd6b34415650db5e5068d96f9d2dc5f30e42 -2026-08-25-feedback-gated-telemetry-default.zh.md: 55936aa4045214b627ecaad39d898b1898a50fc9 +/agent-note-feedback-gated-session-telemetry-default: + en: 213a794503e0d7bc + zh: e086babdf2ad52c9 +/agent-note-feedback-gated-session-telemetry-default/problem: + en: 46b3efd996067d48 + zh: fc59ee763b07987e +/agent-note-feedback-gated-session-telemetry-default/decision: + en: 4136623e5589a592 + zh: db7bc5e9e6ebc19f +/agent-note-feedback-gated-session-telemetry-default/alternatives-considered: + en: 14b51f0de8771943 + zh: 616afb4097857368 +/agent-note-feedback-gated-session-telemetry-default/consequences: + en: d3ed844cc1e29b0b + zh: 76838815edb0a450 diff --git a/.agents/notes/implemented/feature/2026-08-25-promote-open-anywhere-plugin.i18n.yaml b/.agents/notes/implemented/feature/2026-08-25-promote-open-anywhere-plugin.i18n.yaml index a806e17e4e..9c2732ed18 100644 --- a/.agents/notes/implemented/feature/2026-08-25-promote-open-anywhere-plugin.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-25-promote-open-anywhere-plugin.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-25-promote-open-anywhere-plugin.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-25-promote-open-anywhere-plugin.md -2026-08-25-promote-open-anywhere-plugin.md: e5a435d24c2400b68fad8cccb094b176ad83f590 -2026-08-25-promote-open-anywhere-plugin.zh.md: 108091f3e7c2736063d67bc6b2d7fe0c039b35db +/agent-note-promote-open-anywhere-from-community-plugin-to-first-party-package: + en: 279cf946b4f6c386 + zh: cf76602956b811de +/agent-note-promote-open-anywhere-from-community-plugin-to-first-party-package/problem: + en: 08d8d5454fdc2e75 + zh: 22381ce00cb51148 +/agent-note-promote-open-anywhere-from-community-plugin-to-first-party-package/decision: + en: 26a46d3b6f21288a + zh: 94c32f789b3e28ac +/agent-note-promote-open-anywhere-from-community-plugin-to-first-party-package/alternatives-considered: + en: cc7c2ed172e4de3f + zh: b8fed28d9ee835c5 +/agent-note-promote-open-anywhere-from-community-plugin-to-first-party-package/consequences: + en: 5be6b2891e3429c9 + zh: 68ffcff52676824f diff --git a/.agents/notes/implemented/feature/2026-08-26-generic-file-upload.i18n.yaml b/.agents/notes/implemented/feature/2026-08-26-generic-file-upload.i18n.yaml index 6019a38f89..49360cffec 100644 --- a/.agents/notes/implemented/feature/2026-08-26-generic-file-upload.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-26-generic-file-upload.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-26-generic-file-upload.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-26-generic-file-upload.md -2026-08-26-generic-file-upload.md: 196d048da9ffc1342cd62cb9c25674b7cecaffac -2026-08-26-generic-file-upload.zh.md: fce7cef76cf36060f55165d009c568480abb0f16 +/agent-note-generic-file-upload: + en: e82308b967a63c32 + zh: 743f8f4eda638827 +/agent-note-generic-file-upload/problem: + en: e7c3b5d7702714fe + zh: 268f162b553b37d1 +/agent-note-generic-file-upload/decision: + en: 31c7ad96c6ab82c8 + zh: 806922fc8fcd1242 +/agent-note-generic-file-upload/alternatives-considered: + en: 23f386b05e4e79ef + zh: 0756c4fa30e8d0eb +/agent-note-generic-file-upload/consequences: + en: e07df040738c45bb + zh: 9de3b560cb104bd3 +/agent-note-generic-file-upload/testing: + en: 3a50ac370d51cda9 + zh: d490f58922f8795b +/agent-note-generic-file-upload/related: + en: f7e186f0decb4e79 + zh: e5bc9fbd24b6d626 diff --git a/.agents/notes/implemented/feature/2026-08-26-human-job-kill.i18n.yaml b/.agents/notes/implemented/feature/2026-08-26-human-job-kill.i18n.yaml index 151857373f..787b132459 100644 --- a/.agents/notes/implemented/feature/2026-08-26-human-job-kill.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-26-human-job-kill.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-26-human-job-kill.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-26-human-job-kill.md -2026-08-26-human-job-kill.md: efffdbd85bf2fa665565ff584a6938cfee827516 -2026-08-26-human-job-kill.zh.md: 206acca008518dd689351e40a99ff1571f3d1a8f +/agent-note-human-job-kill-an-unclaimed-terminal-report-instead-of-a-second-cancellation-path: + en: d47dedfab1caa170 + zh: 00bb8cd62ed79d54 +/agent-note-human-job-kill-an-unclaimed-terminal-report-instead-of-a-second-cancellation-path/problem: + en: 3690502ccc80b5a3 + zh: cfd3c378e3921864 +/agent-note-human-job-kill-an-unclaimed-terminal-report-instead-of-a-second-cancellation-path/decision: + en: ccd3751d2ecaba5c + zh: f8f820f9492a9bf3 +/agent-note-human-job-kill-an-unclaimed-terminal-report-instead-of-a-second-cancellation-path/alternatives-considered: + en: 74a385c561d8854a + zh: c131a4e386d9b976 +/agent-note-human-job-kill-an-unclaimed-terminal-report-instead-of-a-second-cancellation-path/testing: + en: 094513090d51adfc + zh: b6598110da6c5793 +/agent-note-human-job-kill-an-unclaimed-terminal-report-instead-of-a-second-cancellation-path/consequences: + en: 0bcec15bd9c760fe + zh: 754269206f110f69 diff --git a/.agents/notes/implemented/feature/2026-08-26-shell-execute-projection-and-jobs-at-start.i18n.yaml b/.agents/notes/implemented/feature/2026-08-26-shell-execute-projection-and-jobs-at-start.i18n.yaml index 5359a7b2cd..428a985b5b 100644 --- a/.agents/notes/implemented/feature/2026-08-26-shell-execute-projection-and-jobs-at-start.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-26-shell-execute-projection-and-jobs-at-start.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-26-shell-execute-projection-and-jobs-at-start.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-26-shell-execute-projection-and-jobs-at-start.md -2026-08-26-shell-execute-projection-and-jobs-at-start.md: 2a03cd9f99645c10377dc9d2a5fdc68cb5ab0a4a -2026-08-26-shell-execute-projection-and-jobs-at-start.zh.md: bdc6cc432dbb8e3a0a8d0fc86cf055f3938ff201 +/agent-note-one-shell-execute-foreground-as-a-projection-timeout-as-a-bounded-wait-on-the-job: + en: bbc82e3f79a66fcb + zh: 6c348491e0db97b0 +/agent-note-one-shell-execute-foreground-as-a-projection-timeout-as-a-bounded-wait-on-the-job/problem: + en: e0e1292e5a785322 + zh: 34ec6572ed6cf406 +/agent-note-one-shell-execute-foreground-as-a-projection-timeout-as-a-bounded-wait-on-the-job/decision: + en: 332ddaffd22e473f + zh: 15c0ff6808316770 +/agent-note-one-shell-execute-foreground-as-a-projection-timeout-as-a-bounded-wait-on-the-job/alternatives-considered: + en: d888a561fafa5bb3 + zh: 719d687f2b3e4c10 +/agent-note-one-shell-execute-foreground-as-a-projection-timeout-as-a-bounded-wait-on-the-job/testing: + en: 65f59286de9fa00a + zh: 664d7f82a1479153 +/agent-note-one-shell-execute-foreground-as-a-projection-timeout-as-a-bounded-wait-on-the-job/consequences: + en: 5a5278fc96afacc1 + zh: cc088ea97c6249c9 diff --git a/.agents/notes/implemented/feature/2026-08-27-continuable-subagent-human-inbox-control.i18n.yaml b/.agents/notes/implemented/feature/2026-08-27-continuable-subagent-human-inbox-control.i18n.yaml index 25749576f7..db46bc5f64 100644 --- a/.agents/notes/implemented/feature/2026-08-27-continuable-subagent-human-inbox-control.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-27-continuable-subagent-human-inbox-control.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-27-continuable-subagent-human-inbox-control.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-27-continuable-subagent-human-inbox-control.md -2026-08-27-continuable-subagent-human-inbox-control.md: 6bf8ceb2b8eab7138a1e617bb97e475d5cfa8172 -2026-08-27-continuable-subagent-human-inbox-control.zh.md: 081fb84f75afcc94339ae3bf627480081bc56d89 +/agent-note-human-inbox-controls-for-continuable-subagents: + en: 42b7ed7255c6c527 + zh: c3faf95870ba0e0c +/agent-note-human-inbox-controls-for-continuable-subagents/problem: + en: 4241f01a3a205ff5 + zh: 415c642ad379a53c +/agent-note-human-inbox-controls-for-continuable-subagents/decision: + en: 4f8c53964ac18aff + zh: 31d747618ca608cc +/agent-note-human-inbox-controls-for-continuable-subagents/alternatives-considered: + en: c1f10fb70c8bb500 + zh: 4dc0ec6cac95595c +/agent-note-human-inbox-controls-for-continuable-subagents/consequences: + en: 5fdc5b07eae2633c + zh: 1359d126d182d219 diff --git a/.agents/notes/implemented/feature/2026-08-28-auto-review.i18n.yaml b/.agents/notes/implemented/feature/2026-08-28-auto-review.i18n.yaml index b0a8d7fa60..ab336fff79 100644 --- a/.agents/notes/implemented/feature/2026-08-28-auto-review.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-28-auto-review.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-28-auto-review.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-28-auto-review.md -2026-08-28-auto-review.md: 13b3769b97c27b2ef4ac5cf4f6c2c2dde6323e7f -2026-08-28-auto-review.zh.md: bf7d70b85be43a0b9f451dd20e3bcd5c4b879cd3 +/agent-note-experimental-auto-review-before-each-tool-call: + en: 66cfb9da0816f4f2 + zh: 79f66b9713964a5e +/agent-note-experimental-auto-review-before-each-tool-call/problem: + en: 492ba2355360d81a + zh: 825c0e7ab1cf4beb +/agent-note-experimental-auto-review-before-each-tool-call/decision: + en: fd4103b65b24f6e2 + zh: 5c1a364355b7e9ab +/agent-note-experimental-auto-review-before-each-tool-call/decision/effects-and-authority: + en: 55a79d8572fb4332 + zh: f63d03d0f3bb5811 +/agent-note-experimental-auto-review-before-each-tool-call/decision/one-complete-reviewer-request: + en: d93bd9b8af6b0bfc + zh: 9514c2e5554a721e +/agent-note-experimental-auto-review-before-each-tool-call/decision/result-and-cancellation: + en: 237018634b5f9dcf + zh: cbc49d9c1b794065 +/agent-note-experimental-auto-review-before-each-tool-call/decision/process-catalog-and-children: + en: c305e3506fb4febc + zh: aecc99cda8be3de2 +/agent-note-experimental-auto-review-before-each-tool-call/alternatives-considered: + en: fe97128ed05b9e43 + zh: 4aaa344933fa89b4 +/agent-note-experimental-auto-review-before-each-tool-call/consequences: + en: 1aca35a6d0784f67 + zh: 51cfa397db101600 diff --git a/.agents/notes/implemented/feature/2026-08-28-auto-review.md b/.agents/notes/implemented/feature/2026-08-28-auto-review.md index 13b3769b97..54a2609e33 100644 --- a/.agents/notes/implemented/feature/2026-08-28-auto-review.md +++ b/.agents/notes/implemented/feature/2026-08-28-auto-review.md @@ -10,9 +10,9 @@ Full access lets useful project work proceed without repeated approvals, but it ## Decision -[`dsh-experimental-auto-review`](../../../../packages/experimental/auto-review/README.md) is an explicitly installed experimental Web layer, published under the [experimental package publication decision](../process/2026-09-12-publish-all-experimental-packages.md). Default Web retains Read Only, Workspace Write, and Full access. The layer contributes current-session `auto`, whose only durable identity is `permission/preset:auto`; it shares Full access's unchanged `danger-full-access + never` knobs and tool definitions. Headless, General settings, and new-session defaults exclude the integration. +[`dsh-experimental-auto-review`](../../../../packages/experimental/auto-review/README.md) is an explicitly installed experimental Web layer, published under the [experimental package publication decision](../process/2026-09-12-publish-all-experimental-packages.md). Default Web retains Read Only, Workspace Write, and Full access. The layer contributes current-session `auto`, whose only durable identity is `permission/preset:auto`; it uses Full access's `danger-full-access` sandbox and tool definitions with the approval policy chosen by [the user-approval fallback decision](2026-09-24-auto-review-user-approval-fallback.md). Headless, General settings, and new-session defaults exclude the integration. -Every native call and started PTC `tools.*` inner call receives one review before its body. The outer `run_code` transport and direct Node effects in a PTC program remain outside this guarantee. There are no tool-name exemptions, cached grants, retries, configurable policy, second authorization check, or manual fallback. A repeated call receives a fresh review. +Every native call and started PTC `tools.*` inner call receives one review before its body. The outer `run_code` transport and direct Node effects in a PTC program remain outside this guarantee. There are no tool-name exemptions, cached grants, retries, configurable policy, or second authorization check; [the user-approval fallback decision](2026-09-24-auto-review-user-approval-fallback.md) owns what follows a denial. A repeated call receives a fresh review. ### Effects and authority @@ -46,11 +46,11 @@ The main agent's V3 `system/message` nodes, assistant text/reasoning, and tool r ### Result and cancellation -The reviewer may emit reasoning blocks followed by exactly one JSON text block and terminal `stop`. The closed object admits only `low + allow`, `medium + allow/deny`, and `high + deny`; only deny may carry a string `reason`. Extra fields, duplicate members, invalid combinations, other blocks or termination, and provider failures share the ordinary Auto denial outcome. Risk and reviewer traces are not durable state. +The reviewer may emit reasoning blocks followed by exactly one JSON text block and terminal `stop`. The closed object admits only `low + allow`, `medium + allow/deny`, and `high + deny`; only deny may carry a string `reason`. Extra fields, duplicate members, invalid combinations, other blocks or termination, and provider failures are reviewer failures, which [the user-approval fallback decision](2026-09-24-auto-review-user-approval-fallback.md) reports with their specific error. Risk and reviewer traces are not durable state. -Native results and PTC settle events carry the same structured `AutoReviewDeniedError` / `AUTO_REVIEW_DENIED` and optional raw reason. The main agent receives only `Auto review rejected tool ""; its body was not executed` through ordinary failure rendering. PTC retains the existing program exception/catch behavior; catching a denial does not elevate it to an outer failure. The generic Web tool card supplies the denial identity for the collapsed row and one not-executed output line for the expanded row, with no input body. Only that display trims and collapses line separators or supplies the localized empty-reason fallback; persistence and both SDKs preserve the complete raw reason, without a new length or redaction rule. +A final denial, which [the user-approval fallback decision](2026-09-24-auto-review-user-approval-fallback.md) limits to the `never` approval policy, gives native results and PTC settle events the same structured `AutoReviewDeniedError` / `AUTO_REVIEW_DENIED` and optional raw reason. For a final denial the main agent receives only `Auto review rejected tool ""; its body was not executed` through ordinary failure rendering. PTC retains the existing program exception/catch behavior; catching a denial does not elevate it to an outer failure. The generic Web tool card supplies the denial identity for the collapsed row and one not-executed output line for the expanded row, with no input body. Only that display trims and collapses line separators or supplies the localized empty-reason fallback; persistence and both SDKs preserve the complete raw reason, without a new length or redaction rule. -Admission and active-review enrollment occur synchronously before the first await. The integration owns one lifecycle controller and one set of active operations. Unload closes new selection/review admission, changes live Auto Sessions to Full access through the existing preset writer without changing knobs or closing terminals, then aborts and drains reviews before removing listener and contribution. After provider settlement, a lifecycle abort always produces canonical pre-dispatch cancellation, including late allow, deny, or failure. Caller cancellation retains ToolRuntime's priority: late allow cancels before dispatch; late deny or failure retains that outcome. No cancelled review starts a tool body. +Admission and active-review enrollment occur synchronously before the first await. The integration owns one lifecycle controller and one set of active operations. Unload closes new selection/review admission, changes live Auto Sessions to Full access through the existing preset writer, which writes the `never` approval policy without changing the sandbox value or closing terminals, then aborts and drains reviews before removing listener and contribution. After provider settlement, a lifecycle abort always produces canonical pre-dispatch cancellation, including late allow, deny, or failure. Caller cancellation retains ToolRuntime's priority: late allow cancels before dispatch; a late failure or final denial retains that outcome, and a late denial under `ask` produces a cancelled approval and canonical pre-dispatch cancellation. No cancelled review starts a tool body. A persisted Auto Session cannot publish when the complete integration is absent or failed. Its log is not rewritten, and no background retry runs. Reinstallation allows a user to reopen it; live Sessions migrated to Full access remain there until explicitly switched. diff --git a/.agents/notes/implemented/feature/2026-08-28-auto-review.zh.md b/.agents/notes/implemented/feature/2026-08-28-auto-review.zh.md index bf7d70b85b..6555a7b5cd 100644 --- a/.agents/notes/implemented/feature/2026-08-28-auto-review.zh.md +++ b/.agents/notes/implemented/feature/2026-08-28-auto-review.zh.md @@ -10,9 +10,9 @@ Full access 让有用的项目工作无需反复审批即可继续,但也允 ## 决策 -[`dsh-experimental-auto-review`](../../../../packages/experimental/auto-review/README.zh.md)是显式安装的实验性 Web 层,按[实验包发布决策](../process/2026-09-12-publish-all-experimental-packages.zh.md)参与发布。默认 Web 保持 Read Only、Workspace Write 与 Full access。此层贡献仅限当前会话的 `auto`,唯一持久身份为 `permission/preset:auto`;它共用 Full access 未改变的 `danger-full-access + never` 旋钮与工具定义。Headless、通用设置与新会话默认值都排除此 integration。 +[`dsh-experimental-auto-review`](../../../../packages/experimental/auto-review/README.zh.md)是显式安装的实验性 Web 层,按[实验包发布决策](../process/2026-09-12-publish-all-experimental-packages.zh.md)参与发布。默认 Web 保持 Read Only、Workspace Write 与 Full access。此层贡献仅限当前会话的 `auto`,唯一持久身份为 `permission/preset:auto`;它使用 Full access 的 `danger-full-access` 沙箱与工具定义,审批策略由[用户审批兜底决策](2026-09-24-auto-review-user-approval-fallback.zh.md)决定。Headless、通用设置与新会话默认值都排除此 integration。 -每个原生调用与已开始的 PTC `tools.*` inner call 都在 body 前接受一次审查。外层 `run_code` transport 与 PTC 程序内直接 Node 效果不在保证范围内。不提供按工具名豁免、缓存 grant、重试、可配置策略、第二授权检查或人工 fallback。重复调用也重新审查。 +每个原生调用与已开始的 PTC `tools.*` inner call 都在 body 前接受一次审查。外层 `run_code` transport 与 PTC 程序内直接 Node 效果不在保证范围内。不提供按工具名豁免、缓存 grant、重试、可配置策略或第二授权检查;拒绝之后的行为由[用户审批兜底决策](2026-09-24-auto-review-user-approval-fallback.zh.md)负责。重复调用也重新审查。 ### 效果与权威 @@ -46,11 +46,11 @@ reviewer 从 Session 的完整动作历史构建这两个动作分节:授权 ### 结果与取消 -Reviewer 可以输出 reasoning blocks,随后恰好一个 JSON text block 和终态 `stop`。封闭对象只允许 `low + allow`、`medium + allow/deny` 与 `high + deny`;只有 deny 可携带字符串 `reason`。额外字段、重复成员、非法组合、其他 block 或终态以及 provider 失败均使用普通 Auto 拒绝结果。风险与 reviewer trace 不成为持久状态。 +Reviewer 可以输出 reasoning blocks,随后恰好一个 JSON text block 和终态 `stop`。封闭对象只允许 `low + allow`、`medium + allow/deny` 与 `high + deny`;只有 deny 可携带字符串 `reason`。额外字段、重复成员、非法组合、其他 block 或终态以及 provider 失败都是 reviewer 失败,由[用户审批兜底决策](2026-09-24-auto-review-user-approval-fallback.zh.md)以具体错误报告。风险与 reviewer trace 不成为持久状态。 -原生结果与 PTC 结算事件携带同形结构化 `AutoReviewDeniedError`/`AUTO_REVIEW_DENIED` 及可选原始理由。主 agent 通过普通失败渲染只收到 `Auto review rejected tool ""; its body was not executed`。PTC 保留既有程序异常/catch 行为;捕获拒绝不会将其提升为外层失败。通用 Web 工具卡片为折叠行提供拒绝身份,为展开行提供一行未执行输出,不提供输入正文。只有该显示过程会 trim、折叠行分隔符,或提供本地化空理由 fallback;持久化与两套 SDK 保留完整原始理由,不增加长度或脱敏规则。 +最终拒绝([用户审批兜底决策](2026-09-24-auto-review-user-approval-fallback.zh.md)将其限定在 `never` 审批策略下)让原生结果与 PTC 结算事件携带同形结构化 `AutoReviewDeniedError`/`AUTO_REVIEW_DENIED` 及可选原始理由。对最终拒绝,主 agent 通过普通失败渲染只收到 `Auto review rejected tool ""; its body was not executed`。PTC 保留既有程序异常/catch 行为;捕获拒绝不会将其提升为外层失败。通用 Web 工具卡片为折叠行提供拒绝身份,为展开行提供一行未执行输出,不提供输入正文。只有该显示过程会 trim、折叠行分隔符,或提供本地化空理由 fallback;持久化与两套 SDK 保留完整原始理由,不增加长度或脱敏规则。 -准入与在途 review 登记在首次 await 前同步完成。Integration 拥有一个生命周期 controller 和一个在途操作集合。卸载先关闭新选择/review admission,经由既有 preset writer 把存活 Auto Session 切为 Full access,不改变旋钮、不关闭终端,然后中止并等待 review 结清,最后移除 listener 与 contribution。Provider 结算后,lifecycle abort 始终形成规范的 dispatch 前取消,包括晚到 allow、deny 或 failure。Caller 取消保留 ToolRuntime 优先级:晚到 allow 在 dispatch 前取消;晚到 deny 或 failure 保留原结果。被取消的 review 不启动工具 body。 +准入与在途 review 登记在首次 await 前同步完成。Integration 拥有一个生命周期 controller 和一个在途操作集合。卸载先关闭新选择/review admission,经由既有 preset writer 把存活 Auto Session 切为 Full access,该 writer 写入 `never` 审批策略,不改变沙箱值、不关闭终端,然后中止并等待 review 结清,最后移除 listener 与 contribution。Provider 结算后,lifecycle abort 始终形成规范的 dispatch 前取消,包括晚到 allow、deny 或 failure。Caller 取消保留 ToolRuntime 优先级:晚到 allow 在 dispatch 前取消;晚到 failure 或最终拒绝保留原结果,`ask` 下晚到的拒绝产生已取消的审批与规范的 dispatch 前取消。被取消的 review 不启动工具 body。 完整 integration 缺失或失败时,持久 Auto Session 不能发布。日志不改写,也不后台重试。重装后用户可以重新打开它;已经迁移为 Full access 的存活 Session 保持原状,直到显式切换。 diff --git a/.agents/notes/implemented/feature/2026-08-31-cross-process-session-write-lease.i18n.yaml b/.agents/notes/implemented/feature/2026-08-31-cross-process-session-write-lease.i18n.yaml index 0451d6edcb..679466e91b 100644 --- a/.agents/notes/implemented/feature/2026-08-31-cross-process-session-write-lease.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-31-cross-process-session-write-lease.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-31-cross-process-session-write-lease.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-31-cross-process-session-write-lease.md -2026-08-31-cross-process-session-write-lease.md: bf02ce3eddfb5bcfe2a7d6bd6a6701c47d5f28a4 -2026-08-31-cross-process-session-write-lease.zh.md: b287ab7d6cb4202745fd1112bcb313cb261d674e +/agent-note-cross-process-session-write-lease: + en: 700d2cb4cbf2ba75 + zh: 04a6283f685f4b8a +/agent-note-cross-process-session-write-lease/problem: + en: fa5063a7f8ec786f + zh: f3f7f955d146f00c +/agent-note-cross-process-session-write-lease/decision: + en: fd3a65b3d53ad2d7 + zh: a795f9665045966a +/agent-note-cross-process-session-write-lease/alternatives-considered: + en: c67ce2d14445140a + zh: dd0f531b6e540f9e +/agent-note-cross-process-session-write-lease/consequences: + en: d2a681fa574ebd04 + zh: 4af2e372011bbd59 diff --git a/.agents/notes/implemented/feature/2026-09-01-workflow-run-in-background.i18n.yaml b/.agents/notes/implemented/feature/2026-09-01-workflow-run-in-background.i18n.yaml index 1bc2f5e95d..c220a01232 100644 --- a/.agents/notes/implemented/feature/2026-09-01-workflow-run-in-background.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-01-workflow-run-in-background.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-01-workflow-run-in-background.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-01-workflow-run-in-background.md -2026-09-01-workflow-run-in-background.md: 5a141b384186e7b4f9e8125c37eaf2c01a614a6d -2026-09-01-workflow-run-in-background.zh.md: 102a398d95eef6df07443a919c19dae57b5c1e74 +/agent-note-workflow-runs-gain-run-in-background-over-the-job-registry: + en: f009de4a29acc7d0 + zh: d207b3722564338d +/agent-note-workflow-runs-gain-run-in-background-over-the-job-registry/problem: + en: 4ef955f5184800a3 + zh: 8e4e74557efac4ca +/agent-note-workflow-runs-gain-run-in-background-over-the-job-registry/decision: + en: b0bc1669a6e61b1e + zh: 99ba5afe693aed9d +/agent-note-workflow-runs-gain-run-in-background-over-the-job-registry/alternatives-considered: + en: 70c9a5dd502eae0c + zh: 2b4f7b6a83cfec18 +/agent-note-workflow-runs-gain-run-in-background-over-the-job-registry/consequences: + en: 439882b972d28d4e + zh: 3bd61f42e29f490c diff --git a/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.i18n.yaml b/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.i18n.yaml index 0c14aed1d7..b8b63582e2 100644 --- a/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-02-in-history-system-prompt-replacement.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.md -2026-09-02-in-history-system-prompt-replacement.md: aaaf44d6388e6daf98acf8b1a93a61f1d7c55703 -2026-09-02-in-history-system-prompt-replacement.zh.md: 73003b04de82f45154f9c673654cc492eb62a4fd +/agent-note-in-history-system-prompt-replacement-for-cache-stable-prompt-changes: + en: 7b69ac848815886a + zh: db7a9f4000fe5359 +/agent-note-in-history-system-prompt-replacement-for-cache-stable-prompt-changes/problem: + en: 87965b88be0e831f + zh: d96767a2cef52269 +/agent-note-in-history-system-prompt-replacement-for-cache-stable-prompt-changes/decision: + en: da6d3f0677f0343b + zh: 8b5dcf7e1108edc9 +/agent-note-in-history-system-prompt-replacement-for-cache-stable-prompt-changes/decision/capability: + en: 2f23fa55e1ce652c + zh: 335695fc654ab1db +/agent-note-in-history-system-prompt-replacement-for-cache-stable-prompt-changes/decision/the-decision-rule: + en: 554d01427ebebee1 + zh: 664c9bf0a9337a04 +/agent-note-in-history-system-prompt-replacement-for-cache-stable-prompt-changes/decision/presentation-and-accounting: + en: 00a91b4fb592e1e4 + zh: dac2e4f0a3ee9ecf +/agent-note-in-history-system-prompt-replacement-for-cache-stable-prompt-changes/decision/compaction: + en: c21a3e7a773860e5 + zh: 566669e245ccdbaf +/agent-note-in-history-system-prompt-replacement-for-cache-stable-prompt-changes/alternatives-considered: + en: f3dec242b2550529 + zh: 0397fa07cc1806bb +/agent-note-in-history-system-prompt-replacement-for-cache-stable-prompt-changes/consequences: + en: beda064bcd194a2a + zh: 8a3bb81d5edcd60a +/agent-note-in-history-system-prompt-replacement-for-cache-stable-prompt-changes/testing: + en: 3f9750d67404ac92 + zh: 80cb9aced02e2950 diff --git a/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.md b/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.md index aaaf44d638..644592d2a1 100644 --- a/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.md +++ b/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.md @@ -8,7 +8,7 @@ English | [中文](2026-09-02-in-history-system-prompt-replacement.zh.md) Every system prompt change costs the whole provider prefix cache. The loop renders the prompt on every step; when the bytes differ — a plan-mode section entering or leaving, a skill or tool guidance section registering, an agent-scoped persona shadow, a changed `{{model}}` variable — the request's message 0 changes and the DeepSeek context cache misses from the first token. Long agentic sessions pay this repeatedly, and the [runtime-context snapshot design](../../archived/feature/2026-07-30-current-sandbox-policy-context.md) exists precisely because moving a changing fact out of the prompt was the only way to keep the prefix stable. -A DeepSeek model, recorded here as a model fact supplied for this work, removes that constraint: it accepts a `system` message at any position of the conversation and treats the latest one as the complete effective system prompt, replacing the leading one. Tool schemas remain part of the cached prefix, so a tool-set change still invalidates the cache. With that model the harness can append the new prompt after the cached history instead of rewriting message 0, and the prefix stays warm. +A DeepSeek model, recorded here as a model fact supplied for this work, removes that constraint: it accepts a `system` message at any position of the conversation and treats the latest one as the complete effective system prompt, replacing the leading one. Tool schemas remain part of the cached prefix; [dynamic tool updates](../architecture/2026-09-20-dynamic-tool-updates.md) can defer additions, while changed retained definitions still invalidate reuse. With that model the harness can append the new prompt after the cached history instead of rewriting message 0, and the prefix stays warm. The harness has the representation for this because the [system prompt is surface node 0](../architecture/2026-09-02-system-prompt-as-surface-node.md): a prompt change is an operation on `system/message` surface nodes, and the choice between "replace the latest system node" and "append a new node" is a per-route decision. @@ -33,7 +33,7 @@ The loop records the mode in the session: `RequestContext.systemPromptUpdate` jo | `in-history` | non-empty rendering, a new series starts | log empty replacements for non-empty later system nodes, then rewrite the first system node if needed, even when the latest effective text is unchanged | | any | the rendered prompt is empty | log empty replacements for non-empty later system nodes, then empty the head if needed; no prompt version remains in derived messages | -`startsSeries` is true when the `agent/pre-step` decision declares `startsRequestSeries`, when the surface replace generation moved since the last request (a compaction or any other replacement), or when the visible tool-schema set changed. A provider or model swap alone is not a series start for this rule: on a capable destination route the changed prompt is appended, which costs nothing because the route change already misses the cache. A series start already costs the cache, so consolidation keeps only the current prompt in model history. Logged per-node empty replacements remove later prompts from derived messages without a surface delete operation or any replacement of intervening conversation nodes. This also keeps compaction recovery from appending a system update after users already admitted by the failed attempt. +`startsSeries` is true when the `agent/pre-step` decision declares `startsRequestSeries`, when the surface replace generation moved since the last request (a compaction or any other replacement), or when the visible tool-schema set changed on a route without `toolUpdate` support. Supported tool additions can accompany a prompt append without starting a series. A provider or model swap alone is not a series start for this rule: on a capable destination route the changed prompt is appended, which costs nothing because the route change already misses the cache. A series start already costs the cache, so consolidation keeps only the current prompt in model history. Logged per-node empty replacements remove later prompts from derived messages without a surface delete operation or any replacement of intervening conversation nodes. This also keeps compaction recovery from appending a system update after users already admitted by the failed attempt. The first attempt admits the prompt after assembly, an accepted `agent/pre-step` decision, `step/start`, the `agent/request` waterfall, and `prepareCall()`. A rejected or empty first input opens no step. Neither async request phase commits the pending system prompt or accepted users, and cancellation during either commits neither. Every attempt synchronously reconciles the same rendered assembly after its own `agent/request` and `prepareCall()`, appends the accepted user batch only on the first attempt, logs header/context as needed, and derives and freezes the request before streaming through the same prepared call. Retries do not repeat assembly, `agent/pre-step`, or user admission. Reconciliation sees both pre-step compaction (`compaction-basic` with `auto: true`) and recovery compaction, and consolidates non-empty prompt text at the head when either starts a new series. Resume is series-continuing — the `resume` header is not a series start — so a prompt that changed across a restart is appended; the provider cache may still be warm across a process boundary. @@ -69,7 +69,7 @@ Chat and Trajectory interpret the effective prompt through the pure `uiConversat **Use the preceding request context for admission.** It describes the previous call, not the adapter bound after request middleware. It can select the wrong prompt representation on the first call, after resume, or after a route or capability change. Resolving before prompt and user commits also keeps cancellation from admitting unsent content. Rejected. -**Treat a provider or model swap as a series start.** It would fold the prompt into node 0 on every route change, matching the tools case. The header already records the change and the cache misses either way, so the extra rule bought nothing but a special case in the loop. Rejected. +**Treat a provider or model swap as a series start.** It would fold the prompt into node 0 on every route change, matching a tool change on an incapable route. The header already records the change and the cache misses either way, so the extra rule bought nothing but a special case in the loop. Rejected. **Clear only the latest system node.** Empty nodes project to no message, so an older prompt would become effective again. Clearing all active versions preserves the meaning of an empty rendering without deleting conversation history. Rejected. @@ -89,7 +89,7 @@ Lifecycle verification requires no event for an unchanged prompt and an appended - `packages/core/agent-loop/tests/system-prompt-admission.spec.ts` covers capable-to-incapable routing with changed or unchanged text, incapable-to-capable routing, resumed-route admission, cancellation in request middleware or preparation, and a concurrent selection change while the prepared route stays bound. Retry-compaction cases shadow the latest prompt with or without an earlier surviving update and verify reuse of the admitted assembly, one user admission, and no extra series header on an unchanged retry. Clear cases on capable and incapable routes remove three active prompt versions, keep repeated requests and seeded resume empty without extra prompt events, and restore only the new text; log reconstruction and the pi converter retain no old instructions. Focused coverage of `src/agent.ts` and `src/runtime-context.ts` reaches 100% for statements, branches, functions, and lines. - `packages/core/agent-loop/tests/system-prompt-projection.spec.ts` pins the append on a continuing series, the re-baseline at a series start with or without surviving later nodes and with changed or unchanged effective text, the empty-prompt clearing of all active versions, and the replace-only behaviour without the capability. -- `packages/core/agent-loop/tests/request-reconstruction.spec.ts` pins the appended node under an inherited header with `request/context` carrying `systemPromptUpdate`, the series-start fold into node 0, the compaction-driven re-baseline, and the tool-schema change re-baseline under a `change` header that starts a series. +- `packages/core/agent-loop/tests/request-reconstruction.spec.ts` pins the appended node under an inherited header with `request/context` carrying `systemPromptUpdate`, the series-start fold into node 0, the compaction-driven re-baseline, and the tool-schema change re-baseline on a route without `toolUpdate`, under a `change` header that starts a series. - `packages/llm/llm/tests/service.spec.ts`, `packages/llm/llm-deepseek/tests/adapter.spec.ts`, and `packages/test-support/llm-replay/tests/llm-replay.spec.ts` pin the declared mode on resolved model info and the load-time rejection of any other value. - `packages/llm/token-meter/tests/context-breakdown-projection.spec.ts` pins newest/middle prompt removal, exact heuristic totals, surface ordering after head rewrites, extra source-event citations, dormant empties and fallback clears, immutable transitions, compact retained checkpoints, late registration, replay, and version invalidation. - `packages/client/ui-conversation`, `ui-chat`, and `ui-trajectory` client specs pin the update card, the same-step header dedupe, the absent system change after an update, and the synthetic trajectory header. diff --git a/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.zh.md b/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.zh.md index 73003b04de..b734bc74f7 100644 --- a/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.zh.md +++ b/.agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.zh.md @@ -8,7 +8,7 @@ Status: implemented 每一次系统提示词变更都要付出整个提供方前缀缓存的代价。循环在每个步骤渲染提示词;一旦字节不同——plan 模式片段进入或退出、某个 skill 或工具指引片段完成注册、agent 作用域的 persona 遮蔽、`{{model}}` 变量改变——请求的消息 0 随之改变,DeepSeek 上下文缓存从第一个 token 起失效。长时间的 agent 会话反复为此付费,而[运行时上下文快照设计](../../archived/feature/2026-07-30-current-sandbox-policy-context.md)之所以存在,正是因为把会变化的事实移出提示词是保持前缀稳定的唯一办法。 -一个 DeepSeek 模型——在此按为本项工作提供的模型事实记录——移除了这一限制:它接受对话任意位置的 `system` 消息,并把最新一条视为完整的有效系统提示词,替换最前面那条。工具 schema 仍属于被缓存的前缀,因此工具集变更仍会使缓存失效。有了这样的模型,harness 可以把新提示词追加到已缓存的历史之后而不是重写消息 0,前缀就能保持热态。 +一个 DeepSeek 模型——在此按为本项工作提供的模型事实记录——移除了这一限制:它接受对话任意位置的 `system` 消息,并把最新一条视为完整的有效系统提示词,替换最前面那条。工具 schema 仍属于被缓存的前缀;[动态工具更新](../architecture/2026-09-20-dynamic-tool-updates.zh.md)可以延迟新增声明,而保留定义的变化仍使复用失效。有了这样的模型,harness 可以把新提示词追加到已缓存的历史之后而不是重写消息 0,前缀就能保持热态。 因为[系统提示词是 surface 第 0 号节点](../architecture/2026-09-02-system-prompt-as-surface-node.zh.md),harness 拥有实现这一点的表示:提示词变更是对 `system/message` surface 节点的操作,而「替换最新的系统节点」与「追加新节点」之间的选择是逐路由的决定。 @@ -33,7 +33,7 @@ Status: implemented | `in-history` | 非空渲染文本,新序列开始 | 为非空的后续系统节点记录空内容替换,再按需重写首个系统节点,即使最新有效文本未变也执行 | | 任意 | 渲染后的提示词为空 | 为非空的后续系统节点记录空内容替换,再按需清空头节点;派生消息中不保留任何提示词版本 | -`startsSeries` 在以下情况为真:`agent/pre-step` 决定声明了 `startsRequestSeries`、surface 的替换代数自上次请求以来发生了移动(压缩或任何其他替换)、可见工具 schema 集合发生了变化。仅 provider 或 model 切换对本规则不算序列开始:目标路由具备能力时,变更后的提示词被追加,这不花任何代价,因为路由变更本身已经使缓存未命中。序列开始已经付出了缓存代价,因此归并让模型历史只保留当前提示词。有日志记录的逐节点空内容替换会从派生消息中移除后续提示词,无需 surface 删除操作,也不替换其间的对话节点。这也使压缩恢复不会在失败尝试已接纳的用户消息之后追加系统更新。 +`startsSeries` 在以下情况为真:`agent/pre-step` 决定声明了 `startsRequestSeries`、surface 的替换代数自上次请求以来发生了移动(压缩或任何其他替换)、不支持 `toolUpdate` 的路由上可见工具 schema 集合发生了变化。受支持的工具添加可以与提示词追加一起发生,无需开启新序列。仅 provider 或 model 切换对本规则不算序列开始:目标路由具备能力时,变更后的提示词被追加,这不花任何代价,因为路由变更本身已经使缓存未命中。序列开始已经付出了缓存代价,因此归并让模型历史只保留当前提示词。有日志记录的逐节点空内容替换会从派生消息中移除后续提示词,无需 surface 删除操作,也不替换其间的对话节点。这也使压缩恢复不会在失败尝试已接纳的用户消息之后追加系统更新。 首次尝试在组装、被接纳的 `agent/pre-step` 决策、`step/start`、`agent/request` waterfall 与 `prepareCall()` 之后才接纳提示词。被拒绝或为空的首次输入不打开步骤。两个异步请求阶段都不提交待处理的系统提示词与已接纳用户消息,在任一阶段取消都不会提交这两者。每次尝试都在各自的 `agent/request` 与 `prepareCall()` 之后同步协调同一份已渲染组装结果、仅在首次尝试追加已接纳用户批次、按需记录 header/context、派生并冻结请求,再通过同一个已准备调用发起流式请求。重试不重复组装、`agent/pre-step` 或用户消息准入。协调过程可见 pre-step 压缩(`auto: true` 的 `compaction-basic`)与恢复压缩,并在任一种压缩开启新序列时将非空提示词文本归并到头部。恢复属于序列延续——`resume` header 不是序列开始——因此跨重启发生变化的提示词被追加;提供方缓存在进程边界之后可能仍是热的。 @@ -69,7 +69,7 @@ Chat 与 Trajectory 通过纯操作 `uiConversation.inspectSystemPrompt` 解释 **用先前的请求上下文决定准入。** 它描述上一次调用,而非请求中间件之后绑定的适配器。在首次调用、恢复之后、路由或能力变更之后,它可能选错提示词表示。在提交提示词与用户消息之前解析,还能防止取消时接纳未发送的内容。被否决。 -**把 provider 或 model 切换视为序列开始。** 它会在每次路由变更时把提示词折回第 0 号节点,与 tools 的情形一致。header 已经记录了该变更,缓存无论如何都会未命中,因此这条额外规则除了在循环中多一个特例之外没有任何收益。被否决。 +**把 provider 或 model 切换视为序列开始。** 它会在每次路由变更时把提示词折回第 0 号节点,与不具备能力的路由上的工具变更情形一致。header 已经记录了该变更,缓存无论如何都会未命中,因此这条额外规则除了在循环中多一个特例之外没有任何收益。被否决。 **仅清除最新系统节点。** 空节点不投影为消息,因此更早的提示词会重新生效。清除所有生效版本才能保留空渲染文本的含义,同时不删除对话历史。被否决。 @@ -89,7 +89,7 @@ Chat 与 Trajectory 通过纯操作 `uiConversation.inspectSystemPrompt` 解释 - `packages/core/agent-loop/tests/system-prompt-admission.spec.ts` 覆盖文本变化或未变时从具备能力切换到不具备能力的路由、反向路由切换、恢复时的路由准入、请求中间件或准备阶段取消,以及已准备路由保持绑定时并发选择发生变化。重试压缩用例覆盖遮蔽最新提示词后有或没有更早更新存活的情况,并验证复用已接纳的组装结果、用户消息仅接纳一次,以及未变的后续重试不会多记序列 header。具备和不具备能力路由的清除用例会移除三个生效提示词版本,验证重复请求与带 seed 的恢复保持为空且不多记提示词事件,并仅恢复新文本;日志重建与 pi 转换器都不保留旧指令。`src/agent.ts` 与 `src/runtime-context.ts` 的聚焦覆盖率在语句、分支、函数和行四项均达到 100%。 - `packages/core/agent-loop/tests/system-prompt-projection.spec.ts` 钉住序列延续时的追加、序列开始时无论是否存在后续存活节点、有效文本是否变化都执行的重新基线化、空提示词对所有生效版本的清除,以及不具备能力时只做替换的行为。 -- `packages/core/agent-loop/tests/request-reconstruction.spec.ts` 钉住继承 header 下追加的节点及携带 `systemPromptUpdate` 的 `request/context`、序列开始时折回第 0 号节点、由压缩驱动的重新基线化,以及在开启序列的 `change` header 下由工具 schema 变更驱动的重新基线化。 +- `packages/core/agent-loop/tests/request-reconstruction.spec.ts` 钉住继承 header 下追加的节点及携带 `systemPromptUpdate` 的 `request/context`、序列开始时折回第 0 号节点、由压缩驱动的重新基线化,以及在不支持 `toolUpdate` 的路由上、开启序列的 `change` header 下由工具 schema 变更驱动的重新基线化。 - `packages/llm/llm/tests/service.spec.ts`、`packages/llm/llm-deepseek/tests/adapter.spec.ts` 与 `packages/test-support/llm-replay/tests/llm-replay.spec.ts` 钉住已解析模型信息上声明的模式,以及加载时对任何其他值的拒绝。 - `packages/llm/token-meter/tests/context-breakdown-projection.spec.ts` 钉住最新与中间提示词移除、精确启发式总量、头部改写后的 surface 顺序、额外来源引用、休眠空节点与回退清空、不可变转换、紧凑保留检查点、延迟注册、重放和版本失效。 - `packages/client/ui-conversation`、`ui-chat` 与 `ui-trajectory` 的客户端测试钉住更新卡片、同一步骤 header 的去重、更新之后不存在系统变更,以及合成的轨迹 header。 diff --git a/.agents/notes/implemented/feature/2026-09-04-right-sidebar-docking-infrastructure.i18n.yaml b/.agents/notes/implemented/feature/2026-09-04-right-sidebar-docking-infrastructure.i18n.yaml index 137c5eba63..091e991d76 100644 --- a/.agents/notes/implemented/feature/2026-09-04-right-sidebar-docking-infrastructure.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-04-right-sidebar-docking-infrastructure.i18n.yaml @@ -1,6 +1,43 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-04-right-sidebar-docking-infrastructure.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-04-right-sidebar-docking-infrastructure.md -2026-09-04-right-sidebar-docking-infrastructure.md: c5bfb75730f2037826723bc7fd0aa2bb01005d1e -2026-09-04-right-sidebar-docking-infrastructure.zh.md: 4959032b53f84654205a1973aee781acb356f999 +/agent-note-right-sidebar-docking-infrastructure: + en: 850908fd93d39f7e + zh: 371d9b0d946c2cb4 +/agent-note-right-sidebar-docking-infrastructure/problem: + en: dae256ae605900f2 + zh: 11e9c51126ad836c +/agent-note-right-sidebar-docking-infrastructure/decision: + en: a30a377c8df0e654 + zh: f2577e74c6be3e88 +/agent-note-right-sidebar-docking-infrastructure/decision/package-topology: + en: 7dfd8ad3a822b421 + zh: 338151c69866c7d5 +/agent-note-right-sidebar-docking-infrastructure/decision/layout-engine: + en: af79bc03cd8e8f72 + zh: 88145221570301bf +/agent-note-right-sidebar-docking-infrastructure/decision/the-frame-s-right-column: + en: 78c5b5bf86d0293a + zh: 28b8856d88b78d1e +/agent-note-right-sidebar-docking-infrastructure/decision/state: + en: 7a73e989059c0871 + zh: ef4f8783fc5f3229 +/agent-note-right-sidebar-docking-infrastructure/decision/beyond-the-surface: + en: 82b5fd9d88c3ea43 + zh: d8581e996abbe034 +/agent-note-right-sidebar-docking-infrastructure/decision/entry-points-and-removals: + en: e9cb121a18afadc2 + zh: 37ff2e89d5641e11 +/agent-note-right-sidebar-docking-infrastructure/alternatives-considered: + en: 6569babd25fc0599 + zh: f9d93c937b2cad60 +/agent-note-right-sidebar-docking-infrastructure/consequences: + en: deb3f1a934c49958 + zh: 040de05a3c602858 +/agent-note-right-sidebar-docking-infrastructure/testing: + en: c7ca930dede9f819 + zh: 44c76a4faefe7268 +/agent-note-right-sidebar-docking-infrastructure/deferred: + en: 6c2cd149c6ecf2b0 + zh: b2673dee64de6bd6 diff --git a/.agents/notes/implemented/feature/2026-09-05-sidebar-text-preview-and-file-tree.i18n.yaml b/.agents/notes/implemented/feature/2026-09-05-sidebar-text-preview-and-file-tree.i18n.yaml index 0d328978e1..7c077c2da7 100644 --- a/.agents/notes/implemented/feature/2026-09-05-sidebar-text-preview-and-file-tree.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-05-sidebar-text-preview-and-file-tree.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-sidebar-text-preview-and-file-tree.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-05-sidebar-text-preview-and-file-tree.md -2026-09-05-sidebar-text-preview-and-file-tree.md: e978043545b7f172f2b67053fe44b5936ea9b529 -2026-09-05-sidebar-text-preview-and-file-tree.zh.md: 088d4a58c973843ac5085cfaa1ca9980387bcc8f +/agent-note-sidebar-text-preview-and-file-tree: + en: 2f9ef6cc50ad825d + zh: 5ec8592ac9963f85 +/agent-note-sidebar-text-preview-and-file-tree/problem: + en: 4e647765dfcd2ef9 + zh: 2c362ffdee7ff3d4 +/agent-note-sidebar-text-preview-and-file-tree/decision: + en: f8ea6a52a404b064 + zh: c91528d66487bb33 +/agent-note-sidebar-text-preview-and-file-tree/decision/the-guide: + en: cc4eaeefe4de9a02 + zh: bc9e727d6316ae88 +/agent-note-sidebar-text-preview-and-file-tree/decision/the-text-preview: + en: efc84d800d52a69e + zh: 0061138d7cd12ae7 +/agent-note-sidebar-text-preview-and-file-tree/decision/the-file-tree: + en: f03013eee6c293de + zh: 54796ac3da91047f +/agent-note-sidebar-text-preview-and-file-tree/alternatives-considered: + en: 87fddbd01f117061 + zh: 1810d283202db648 +/agent-note-sidebar-text-preview-and-file-tree/consequences: + en: 00b1675fcd76ad0d + zh: caf3eb340c74aef7 +/agent-note-sidebar-text-preview-and-file-tree/testing: + en: 2987a6417b7e4c14 + zh: 97eeb97e67536c70 +/agent-note-sidebar-text-preview-and-file-tree/deferred: + en: 6c788b26fb65227b + zh: 1bafda76bac92edd +/agent-note-sidebar-text-preview-and-file-tree/related: + en: 0a2531b19968c69b + zh: 4065017075aa11cc diff --git a/.agents/notes/implemented/feature/2026-09-07-composer-session-stats-pills.i18n.yaml b/.agents/notes/implemented/feature/2026-09-07-composer-session-stats-pills.i18n.yaml index d4ef512e91..b54791c599 100644 --- a/.agents/notes/implemented/feature/2026-09-07-composer-session-stats-pills.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-07-composer-session-stats-pills.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-composer-session-stats-pills.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-07-composer-session-stats-pills.md -2026-09-07-composer-session-stats-pills.md: 50d3d3294ed012773657ba9849e45835c361d8be -2026-09-07-composer-session-stats-pills.zh.md: 97b91b601e62e8b06ab13a764babb4dd3b25bfce +/agent-note-composer-session-stats-two-icon-pills-with-click-open-stat-dialogs: + en: 76e613674da56884 + zh: 4c9c5d750eace3e0 +/agent-note-composer-session-stats-two-icon-pills-with-click-open-stat-dialogs/problem: + en: 654462fa4eeb58dc + zh: 7c9cd57947ab8639 +/agent-note-composer-session-stats-two-icon-pills-with-click-open-stat-dialogs/decision: + en: 27eb1718cd80b39b + zh: e39576842a3578c1 +/agent-note-composer-session-stats-two-icon-pills-with-click-open-stat-dialogs/alternatives-considered: + en: 7798b1fb9824b920 + zh: 7e75cd154ab58a0b +/agent-note-composer-session-stats-two-icon-pills-with-click-open-stat-dialogs/consequences: + en: c078fb870536eec6 + zh: 17076d824c74ee9d diff --git a/.agents/notes/implemented/feature/2026-09-07-deepseek-messages-adapter.i18n.yaml b/.agents/notes/implemented/feature/2026-09-07-deepseek-messages-adapter.i18n.yaml index 13e41b76da..65061d8855 100644 --- a/.agents/notes/implemented/feature/2026-09-07-deepseek-messages-adapter.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-07-deepseek-messages-adapter.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-deepseek-messages-adapter.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-07-deepseek-messages-adapter.md -2026-09-07-deepseek-messages-adapter.md: 29f712e57c8048ddb0c05b5f56fd4793c52bec5f -2026-09-07-deepseek-messages-adapter.zh.md: 3cf60fc2101fb835423b74a6532e5edcc5bee911 +/agent-note-deepseek-through-the-anthropic-messages-protocol: + en: 4d1dc31d47e3e8b1 + zh: b80687f6506860d5 +/agent-note-deepseek-through-the-anthropic-messages-protocol/problem: + en: 6c9d47e829752afe + zh: 98bd3b5300bfea8c +/agent-note-deepseek-through-the-anthropic-messages-protocol/decision: + en: 3c28330671a1e6db + zh: 0d7ef9a8cf22c51f +/agent-note-deepseek-through-the-anthropic-messages-protocol/alternatives-considered: + en: 4297bc439e8b23e4 + zh: 2bb4dec78040d81e +/agent-note-deepseek-through-the-anthropic-messages-protocol/consequences: + en: 76aa9259724323d2 + zh: 0aac83847bbd4ab6 diff --git a/.agents/notes/implemented/feature/2026-09-07-model-switch-notice.i18n.yaml b/.agents/notes/implemented/feature/2026-09-07-model-switch-notice.i18n.yaml index a3796aa548..d1cc740eac 100644 --- a/.agents/notes/implemented/feature/2026-09-07-model-switch-notice.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-07-model-switch-notice.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-model-switch-notice.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-07-model-switch-notice.md -2026-09-07-model-switch-notice.md: cb2f915f13b5fa277977b7a768a3531074126f2a -2026-09-07-model-switch-notice.zh.md: b6dd8da02732e4b6c6b2102aef6074b8f136d37d +/agent-note-model-visible-route-change-notices: + en: 8e372ee5814c99d1 + zh: 3fd0faa18fc02f75 +/agent-note-model-visible-route-change-notices/problem: + en: 0c0be027f271e132 + zh: c4f6aa9217633f43 +/agent-note-model-visible-route-change-notices/decision: + en: 86dbb17229ae9634 + zh: 6b0af5f12441461c +/agent-note-model-visible-route-change-notices/alternatives-considered: + en: 9e8ac73976d39c99 + zh: e637370a5f2b0de8 +/agent-note-model-visible-route-change-notices/consequences: + en: 93976aae03285052 + zh: 27791c4f1f36dc92 diff --git a/.agents/notes/implemented/feature/2026-09-07-session-prose-local-media-display.i18n.yaml b/.agents/notes/implemented/feature/2026-09-07-session-prose-local-media-display.i18n.yaml index daa947a20c..ddf9d83bdd 100644 --- a/.agents/notes/implemented/feature/2026-09-07-session-prose-local-media-display.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-07-session-prose-local-media-display.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-session-prose-local-media-display.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-07-session-prose-local-media-display.md -2026-09-07-session-prose-local-media-display.md: fe769d1cbe0b54eed355a7e699bf853a497820cb -2026-09-07-session-prose-local-media-display.zh.md: 2cfff4016f42a13d94a1097602ff2dadbd28d2a7 +/agent-note-session-prose-local-media-paths-display-through-a-same-origin-file-route: + en: 58736e33d45c5578 + zh: 224ab6304833ce7f +/agent-note-session-prose-local-media-paths-display-through-a-same-origin-file-route/problem: + en: 934cbf480461e9e6 + zh: 986d53c72b94cfe4 +/agent-note-session-prose-local-media-paths-display-through-a-same-origin-file-route/decision: + en: 37e189446dd25601 + zh: 0321b091e2250650 +/agent-note-session-prose-local-media-paths-display-through-a-same-origin-file-route/alternatives-considered: + en: b184da259c41e4de + zh: 5c75e50fa595a30e +/agent-note-session-prose-local-media-paths-display-through-a-same-origin-file-route/consequences: + en: 9929a8ad123b21b0 + zh: ac5bf7f3a317d180 +/agent-note-session-prose-local-media-paths-display-through-a-same-origin-file-route/testing: + en: 3c29c3c506a993b2 + zh: 2dfac506ae2ff93a diff --git a/.agents/notes/implemented/feature/2026-09-08-composer-menu-sections-and-localized-rows.i18n.yaml b/.agents/notes/implemented/feature/2026-09-08-composer-menu-sections-and-localized-rows.i18n.yaml index 93a617d08b..9956298fd4 100644 --- a/.agents/notes/implemented/feature/2026-09-08-composer-menu-sections-and-localized-rows.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-08-composer-menu-sections-and-localized-rows.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-composer-menu-sections-and-localized-rows.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-08-composer-menu-sections-and-localized-rows.md -2026-09-08-composer-menu-sections-and-localized-rows.md: 50b97ce2c7e59d53bf5607fef74a799a359d27c8 -2026-09-08-composer-menu-sections-and-localized-rows.zh.md: 92bcb04bfe9b4f7b5581c80d7c0b843f98096e52 +/agent-note-composer-menu-sections-localized-rows-and-the-file-row: + en: c917d19351c56a78 + zh: f443c8b88e4f71dd +/agent-note-composer-menu-sections-localized-rows-and-the-file-row/problem: + en: 3047bf5dd9f33e93 + zh: 34b017add5329b49 +/agent-note-composer-menu-sections-localized-rows-and-the-file-row/decision: + en: 7f9b8265d826561e + zh: e2eca2e3f58d296f +/agent-note-composer-menu-sections-localized-rows-and-the-file-row/alternatives-considered: + en: a7806a39ab7a1bac + zh: 421815a13d53e306 +/agent-note-composer-menu-sections-localized-rows-and-the-file-row/consequences: + en: 8d4daba9e67cdfaa + zh: 6ef43f58f9abf3bc diff --git a/.agents/notes/implemented/feature/2026-09-08-desktop-uninstall-preserve-dsh-home.i18n.yaml b/.agents/notes/implemented/feature/2026-09-08-desktop-uninstall-preserve-dsh-home.i18n.yaml index 3bdaabeccf..ea1536b2ae 100644 --- a/.agents/notes/implemented/feature/2026-09-08-desktop-uninstall-preserve-dsh-home.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-08-desktop-uninstall-preserve-dsh-home.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-desktop-uninstall-preserve-dsh-home.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-08-desktop-uninstall-preserve-dsh-home.md -2026-09-08-desktop-uninstall-preserve-dsh-home.md: 921d9681aa6a26c39e8861d2156dc868237f5b37 -2026-09-08-desktop-uninstall-preserve-dsh-home.zh.md: cb9187bb6d7c3f619dc083fcc3b36cca09494515 +/agent-note-windows-uninstall-retains-the-harness-home: + en: ae26a8eee5e5ef6e + zh: 2549190b3d8890e1 +/agent-note-windows-uninstall-retains-the-harness-home/problem: + en: 7e0091e3af8b52d8 + zh: b40193a58711c6a5 +/agent-note-windows-uninstall-retains-the-harness-home/decision: + en: fd2608389491a1f8 + zh: b007e1d35a049292 +/agent-note-windows-uninstall-retains-the-harness-home/alternatives-considered: + en: f3a2c8263d598b30 + zh: 226a3203c940bdd3 +/agent-note-windows-uninstall-retains-the-harness-home/deferred: + en: 7d13267e5928961a + zh: 79398501c8e099dd +/agent-note-windows-uninstall-retains-the-harness-home/consequences: + en: 9f94a327edbd7685 + zh: fa53c77c2d9df54d diff --git a/.agents/notes/implemented/feature/2026-09-08-feedback-dialog-and-categories.i18n.yaml b/.agents/notes/implemented/feature/2026-09-08-feedback-dialog-and-categories.i18n.yaml index c18c6397ed..5de5db011a 100644 --- a/.agents/notes/implemented/feature/2026-09-08-feedback-dialog-and-categories.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-08-feedback-dialog-and-categories.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-feedback-dialog-and-categories.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-08-feedback-dialog-and-categories.md -2026-09-08-feedback-dialog-and-categories.md: 1d544e6ef978c10008ac62768b6faaf9eaaf8b73 -2026-09-08-feedback-dialog-and-categories.zh.md: 6e58820bf308a3a9f7d15b64027f90e7e6771bd4 +/agent-note-feedback-dialog-categories-and-the-acknowledgement-toast: + en: 0ca76fe002b0b0fc + zh: 14fa2772a6a23e25 +/agent-note-feedback-dialog-categories-and-the-acknowledgement-toast/problem: + en: 90ac7f116156c209 + zh: 20274add2ffbcdc0 +/agent-note-feedback-dialog-categories-and-the-acknowledgement-toast/decision: + en: 4cde40e5b1ad6beb + zh: fb49e47434faf06f +/agent-note-feedback-dialog-categories-and-the-acknowledgement-toast/alternatives-considered: + en: 3713257ee75869da + zh: 5892d375fe8d0764 +/agent-note-feedback-dialog-categories-and-the-acknowledgement-toast/consequences: + en: a55c05291a78e922 + zh: 1373131586665daf diff --git a/.agents/notes/implemented/feature/2026-09-08-file-display-through-filesystem.i18n.yaml b/.agents/notes/implemented/feature/2026-09-08-file-display-through-filesystem.i18n.yaml index 0817dcd4f1..efe36291ac 100644 --- a/.agents/notes/implemented/feature/2026-09-08-file-display-through-filesystem.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-08-file-display-through-filesystem.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-file-display-through-filesystem.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-08-file-display-through-filesystem.md -2026-09-08-file-display-through-filesystem.md: b1f93f8c9fbd245ad69bc732b2a599c6e0abeb0d -2026-09-08-file-display-through-filesystem.zh.md: faa3fdb757c9a3fc60cae37692a559158e02ceee +/agent-note-authenticated-file-display-reuses-filesystem-byte-reads: + en: 1db6d91b6011384e + zh: 68152c2e3fff2931 +/agent-note-authenticated-file-display-reuses-filesystem-byte-reads/problem: + en: c8e25473775da151 + zh: af807ea30d423858 +/agent-note-authenticated-file-display-reuses-filesystem-byte-reads/decision: + en: d448ed98f635fd14 + zh: 81795f947a0c1c99 +/agent-note-authenticated-file-display-reuses-filesystem-byte-reads/alternatives-considered: + en: 80e52b422305ca28 + zh: d0e38b1cd96be951 +/agent-note-authenticated-file-display-reuses-filesystem-byte-reads/consequences: + en: 15ec0dd18d621f24 + zh: e4925a96395edd8c +/agent-note-authenticated-file-display-reuses-filesystem-byte-reads/testing: + en: 9d28b1552a2decde + zh: 6ea9f91992bcfa1a diff --git a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml index 057e138853..e2c08a0acd 100644 --- a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-present-workspace-source-files.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.md -2026-09-08-present-workspace-source-files.md: 52cc3e9cdbcd30d378117a327b86062523a2cb3e -2026-09-08-present-workspace-source-files.zh.md: 99b7b9df1d9ca2da2175df1ae7e9d8acbb5c5fdd +/agent-note-present-declares-workspace-source-files: + en: 8e9f703ce074f949 + zh: 37e27d1591d31b9d +/agent-note-present-declares-workspace-source-files/problem: + en: 8598b8d2e92bcfa1 + zh: e3ae5fc294711095 +/agent-note-present-declares-workspace-source-files/decision: + en: 481549ced705b010 + zh: 8cad3ea14f84decf +/agent-note-present-declares-workspace-source-files/alternatives-considered: + en: b959eae9786351da + zh: 030c06051d6ac4be +/agent-note-present-declares-workspace-source-files/consequences: + en: 98cd6d2356003a58 + zh: 6e0b46c4ec6ba4b5 diff --git a/.agents/notes/implemented/feature/2026-09-08-shared-file-type-icons.i18n.yaml b/.agents/notes/implemented/feature/2026-09-08-shared-file-type-icons.i18n.yaml index 35f8f4dc56..569b09933e 100644 --- a/.agents/notes/implemented/feature/2026-09-08-shared-file-type-icons.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-08-shared-file-type-icons.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-shared-file-type-icons.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-08-shared-file-type-icons.md -2026-09-08-shared-file-type-icons.md: 5dbe0ade14c15e1d509f56eba6e0266c61089c46 -2026-09-08-shared-file-type-icons.zh.md: 9dbccdf10f188b30dcbbbe11d45b238af42ca112 +/agent-note-shared-file-type-icons: + en: d83f437754356503 + zh: 7f5b673537312d8c +/agent-note-shared-file-type-icons/problem: + en: 67d8c2d11e0ae0a2 + zh: fb2a576b528db3ad +/agent-note-shared-file-type-icons/decision: + en: 418ba69021928ba0 + zh: 7fc1b5cef5f22004 +/agent-note-shared-file-type-icons/alternatives-considered: + en: 67dc36a02b841541 + zh: cf262c343957ff69 +/agent-note-shared-file-type-icons/testing: + en: 16768b2ea13d16ef + zh: e7455e31220bb2e6 +/agent-note-shared-file-type-icons/consequences: + en: fb30a1c743dbe885 + zh: 858fb79479434d69 diff --git a/.agents/notes/implemented/feature/2026-09-08-sidebar-default-pages.i18n.yaml b/.agents/notes/implemented/feature/2026-09-08-sidebar-default-pages.i18n.yaml index e6392aa970..b7a60a735c 100644 --- a/.agents/notes/implemented/feature/2026-09-08-sidebar-default-pages.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-08-sidebar-default-pages.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-sidebar-default-pages.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-08-sidebar-default-pages.md -2026-09-08-sidebar-default-pages.md: 13374ab294cab74b54ada8550a6dff5af2cd9cd1 -2026-09-08-sidebar-default-pages.zh.md: 6730a87fbe9c59ef6d448fe0f2d4c3c2cb75e6bb +/agent-note-sidebar-default-pages: + en: 0b6b9c156b3653d9 + zh: f4650c41660ea99d +/agent-note-sidebar-default-pages/problem: + en: 48127a7f5a873a52 + zh: a722f139876a415a +/agent-note-sidebar-default-pages/decision: + en: b6707d5c48eb414a + zh: c920061739304dfc +/agent-note-sidebar-default-pages/alternatives-considered: + en: 8d981eef6c5088b8 + zh: 0bc9541a7f7d7b53 +/agent-note-sidebar-default-pages/consequences: + en: eb418364a7c202e2 + zh: d2372099a1ed3e6e diff --git a/.agents/notes/implemented/feature/2026-09-08-sidebar-last-tab-close-rules.i18n.yaml b/.agents/notes/implemented/feature/2026-09-08-sidebar-last-tab-close-rules.i18n.yaml index 2846db77ba..a4049b0446 100644 --- a/.agents/notes/implemented/feature/2026-09-08-sidebar-last-tab-close-rules.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-08-sidebar-last-tab-close-rules.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-sidebar-last-tab-close-rules.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-08-sidebar-last-tab-close-rules.md -2026-09-08-sidebar-last-tab-close-rules.md: ed76b0ad0b8bbadcf5eace12a7da3bd38c733d0e -2026-09-08-sidebar-last-tab-close-rules.zh.md: bcc54c0c39cc65434f21ef8f6f81a382b6eecdb7 +/agent-note-last-tab-close-rules-on-the-sidebar-s-docked-surface: + en: 4f38145de396b08f + zh: 3e65231a5ebb8fdd +/agent-note-last-tab-close-rules-on-the-sidebar-s-docked-surface/problem: + en: 90a9c3dc146c7d11 + zh: a12b784b66fa3979 +/agent-note-last-tab-close-rules-on-the-sidebar-s-docked-surface/decision: + en: a760dcb29bb9645c + zh: ad4dafd7d5b407e7 +/agent-note-last-tab-close-rules-on-the-sidebar-s-docked-surface/alternatives-considered: + en: 4e2673d521d6540e + zh: 0d5f0b99ea80d5ff +/agent-note-last-tab-close-rules-on-the-sidebar-s-docked-surface/consequences: + en: 3e43dd3066e8b05b + zh: ed6ed81abb18131b diff --git a/.agents/notes/implemented/feature/2026-09-09-headless-machine-readable-run-surface.i18n.yaml b/.agents/notes/implemented/feature/2026-09-09-headless-machine-readable-run-surface.i18n.yaml index d704c77ad2..f4cc113bc2 100644 --- a/.agents/notes/implemented/feature/2026-09-09-headless-machine-readable-run-surface.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-09-headless-machine-readable-run-surface.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-headless-machine-readable-run-surface.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-09-headless-machine-readable-run-surface.md -2026-09-09-headless-machine-readable-run-surface.md: 317f213095f86e94104c013139390cdf988f95fe -2026-09-09-headless-machine-readable-run-surface.zh.md: 0114f87aef4f25db0887663464973bb2f762b2d5 +/agent-note-headless-machine-readable-run-surface: + en: bcf2251478004e35 + zh: 70ade47c837c6bab +/agent-note-headless-machine-readable-run-surface/problem: + en: 9d2c64ed47b82129 + zh: bb0de126368e9f07 +/agent-note-headless-machine-readable-run-surface/decision: + en: ed08acff9c4ea030 + zh: 484c2646de4aa5d8 +/agent-note-headless-machine-readable-run-surface/decision/command-line-contract: + en: 59470d5c2eba0a57 + zh: 342c1ac9042c6b46 +/agent-note-headless-machine-readable-run-surface/decision/event-stream: + en: b6837e3de1305559 + zh: 183956da3319a126 +/agent-note-headless-machine-readable-run-surface/decision/session-identity: + en: ebb2c5da4ea076a9 + zh: a706416d290e7424 +/agent-note-headless-machine-readable-run-surface/consequences: + en: 1ba14087f533dd8e + zh: 66f4aa9d63a0da23 +/agent-note-headless-machine-readable-run-surface/alternatives-considered: + en: 42f321bd399f906e + zh: 3b13791afa256781 diff --git a/.agents/notes/implemented/feature/2026-09-09-present-filesystem-access.i18n.yaml b/.agents/notes/implemented/feature/2026-09-09-present-filesystem-access.i18n.yaml index 5bb1142826..4b6f724f0b 100644 --- a/.agents/notes/implemented/feature/2026-09-09-present-filesystem-access.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-09-present-filesystem-access.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-present-filesystem-access.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-09-present-filesystem-access.md -2026-09-09-present-filesystem-access.md: 5c9d5bec47c73ac1c5952b887d56e582148a4cea -2026-09-09-present-filesystem-access.zh.md: 6387f07b17276b3455d19d650b4ae031a7efda4c +/agent-note-present-follows-session-filesystem-access: + en: 33cf0a75284f8392 + zh: 5299af2f77bf6fd8 +/agent-note-present-follows-session-filesystem-access/problem: + en: dda1953cb567c3dc + zh: 3c447175454c844a +/agent-note-present-follows-session-filesystem-access/decision: + en: 2668dd51b07e2653 + zh: 3cd895017f568c42 +/agent-note-present-follows-session-filesystem-access/alternatives-considered: + en: 85336cd165610ddf + zh: 75608e3bfeab5dc5 +/agent-note-present-follows-session-filesystem-access/consequences: + en: e31784fe619d4d1c + zh: 7cadc3941a0c7b33 diff --git a/.agents/notes/implemented/feature/2026-09-09-ptc-trajectory-code-inspection.i18n.yaml b/.agents/notes/implemented/feature/2026-09-09-ptc-trajectory-code-inspection.i18n.yaml index d88fb31e2e..6ae3a85d71 100644 --- a/.agents/notes/implemented/feature/2026-09-09-ptc-trajectory-code-inspection.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-09-ptc-trajectory-code-inspection.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-ptc-trajectory-code-inspection.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-09-ptc-trajectory-code-inspection.md -2026-09-09-ptc-trajectory-code-inspection.md: 19779d20e8d08ce0ca9678ab6626765faa13cf65 -2026-09-09-ptc-trajectory-code-inspection.zh.md: 7cdb2321d61893e43426798d311847662450d289 +/agent-note-inspect-recorded-ptc-source-in-trajectory: + en: 29f601adfcaa6019 + zh: bdd1c59d1bbbff62 +/agent-note-inspect-recorded-ptc-source-in-trajectory/problem: + en: 6b49bc4faca04ae0 + zh: 60165937e0a7c71d +/agent-note-inspect-recorded-ptc-source-in-trajectory/decision: + en: 43dd488c270c1664 + zh: 3fdf6d374c49fee3 +/agent-note-inspect-recorded-ptc-source-in-trajectory/alternatives-considered: + en: bbf705774c5c608a + zh: 1af9b4aa3d4fa025 +/agent-note-inspect-recorded-ptc-source-in-trajectory/consequences: + en: c680634fe8b95880 + zh: 7660cd3354522ef8 diff --git a/.agents/notes/implemented/feature/2026-09-09-sidebar-and-preview-interaction-polish.i18n.yaml b/.agents/notes/implemented/feature/2026-09-09-sidebar-and-preview-interaction-polish.i18n.yaml index 6906decd2f..e82abbb700 100644 --- a/.agents/notes/implemented/feature/2026-09-09-sidebar-and-preview-interaction-polish.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-09-sidebar-and-preview-interaction-polish.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-sidebar-and-preview-interaction-polish.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-09-sidebar-and-preview-interaction-polish.md -2026-09-09-sidebar-and-preview-interaction-polish.md: eba8bd3a2314c7eaf18cd9982aa4e599665dbc62 -2026-09-09-sidebar-and-preview-interaction-polish.zh.md: 93d88d41e99f50621c80d69d615e39852b715c89 +/agent-note-sidebar-and-preview-interaction-polish: + en: bce3b5bc9f49bbff + zh: bebc5b0ce3a370a7 +/agent-note-sidebar-and-preview-interaction-polish/problem: + en: 2d6e8ec1b08dcce9 + zh: 75e1c454d71da103 +/agent-note-sidebar-and-preview-interaction-polish/decision: + en: 7358c236daed510b + zh: 93cf67bbffa2c20b +/agent-note-sidebar-and-preview-interaction-polish/alternatives-considered: + en: c828e83875412d49 + zh: d0277bf0d1f5d7a9 +/agent-note-sidebar-and-preview-interaction-polish/consequences: + en: cb7cb72724552f2b + zh: 05705b4795ade85f diff --git a/.agents/notes/implemented/feature/2026-09-09-web-sidebar-terminal.i18n.yaml b/.agents/notes/implemented/feature/2026-09-09-web-sidebar-terminal.i18n.yaml index 76ed3e8786..73ba0975be 100644 --- a/.agents/notes/implemented/feature/2026-09-09-web-sidebar-terminal.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-09-web-sidebar-terminal.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-web-sidebar-terminal.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-09-web-sidebar-terminal.md -2026-09-09-web-sidebar-terminal.md: 09be4a142f615750799e01106eac7a9b52cbad48 -2026-09-09-web-sidebar-terminal.zh.md: c2ac1468756ee08c713855979119662390ffeadb +/agent-note-web-sidebar-terminals: + en: dfb245f871011059 + zh: d64c0bd9cbe5f652 +/agent-note-web-sidebar-terminals/problem: + en: 71813b1cb1f750ba + zh: 64d2b999933ccd98 +/agent-note-web-sidebar-terminals/decision: + en: d73dc0a37bd7c9dd + zh: f5c6cf8cce36090a +/agent-note-web-sidebar-terminals/alternatives-considered: + en: 0c129fba63a60777 + zh: c334f34dd71bbaf6 +/agent-note-web-sidebar-terminals/consequences: + en: d710787595b5dc89 + zh: 4df9518c32698f85 +/agent-note-web-sidebar-terminals/related: + en: 94540c743da01fc4 + zh: 53e3d9d2268153d1 diff --git a/.agents/notes/implemented/feature/2026-09-10-composer-reference-previews.i18n.yaml b/.agents/notes/implemented/feature/2026-09-10-composer-reference-previews.i18n.yaml index ee5d2b3fa2..e5beccba4f 100644 --- a/.agents/notes/implemented/feature/2026-09-10-composer-reference-previews.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-10-composer-reference-previews.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-composer-reference-previews.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-10-composer-reference-previews.md -2026-09-10-composer-reference-previews.md: e9425851c1dc4ac0c8dc588d3b234c173eeb9262 -2026-09-10-composer-reference-previews.zh.md: c47718468bf1e38469140c12c1096b7bc5da0f40 +/agent-note-composer-reference-previews: + en: 4077f5f4bb6cbbc1 + zh: 0ed641c53ecc9ff9 +/agent-note-composer-reference-previews/problem: + en: b6c93af7ecb4f6df + zh: e6efd6ac2e2193fc +/agent-note-composer-reference-previews/decision: + en: f895747aad30a9ea + zh: 1a736bbf64f82041 +/agent-note-composer-reference-previews/alternatives-considered: + en: c76709c683a56316 + zh: a6708957a465c3ce +/agent-note-composer-reference-previews/consequences: + en: d67f32b4450e8c71 + zh: 7d3a8c6588959e04 diff --git a/.agents/notes/implemented/feature/2026-09-10-symmetric-message-feedback-submission.i18n.yaml b/.agents/notes/implemented/feature/2026-09-10-symmetric-message-feedback-submission.i18n.yaml index bc63e89dd9..9a45958b42 100644 --- a/.agents/notes/implemented/feature/2026-09-10-symmetric-message-feedback-submission.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-10-symmetric-message-feedback-submission.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-symmetric-message-feedback-submission.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-10-symmetric-message-feedback-submission.md -2026-09-10-symmetric-message-feedback-submission.md: 51c754dbd3ecc566e15ec1b7a276fc2a3cf7c551 -2026-09-10-symmetric-message-feedback-submission.zh.md: 0ba5d1a1c53f08b76c5bbc32b84687c3dcd38ec2 +/agent-note-symmetric-message-feedback-submission: + en: 40f6c11f8f4332a2 + zh: fa31c26c296f892c +/agent-note-symmetric-message-feedback-submission/problem: + en: f5afa64229a1e8db + zh: b73e730754f33cc5 +/agent-note-symmetric-message-feedback-submission/decision: + en: a8a9598cb30f8f8e + zh: 3073219d585bc5fd +/agent-note-symmetric-message-feedback-submission/alternatives-considered: + en: b425d01d854f8962 + zh: f74131c171c9f74a +/agent-note-symmetric-message-feedback-submission/consequences: + en: 833bc3370c02fd1e + zh: 2718d60cdf762436 diff --git a/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.i18n.yaml b/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.i18n.yaml index 32ae05e725..fd0a14a09f 100644 --- a/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-desktop-mandatory-update-client.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.md -2026-09-11-desktop-mandatory-update-client.md: ff55f30836a37e49229adac6414cb3a98bca4d6c -2026-09-11-desktop-mandatory-update-client.zh.md: 6c17a9fbd0ce2741b635b742be682d4c5fd9f8c6 +/agent-note-desktop-mandatory-update-client-and-blocking-window: + en: 059254153764a162 + zh: 17dfd84fd2ba6eea +/agent-note-desktop-mandatory-update-client-and-blocking-window/problem: + en: f1aeaa7df97a744f + zh: 039b2cccd9a45198 +/agent-note-desktop-mandatory-update-client-and-blocking-window/decision: + en: 7d8ece211be36774 + zh: d25c3ebac6420187 +/agent-note-desktop-mandatory-update-client-and-blocking-window/alternatives-considered: + en: 136afb04a37db4a1 + zh: 2b049e0d9fd8aa27 +/agent-note-desktop-mandatory-update-client-and-blocking-window/consequences: + en: 6f7a3decf4f0504f + zh: 16241131d1053989 diff --git a/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.md b/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.md index ff55f30836..838403a2b1 100644 --- a/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.md +++ b/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.md @@ -10,9 +10,11 @@ A local business server does not deliver remote minimum-version policy. The Desk ## Decision +Native update overlays own their parent-visibility subscription until closure. On macOS, hiding a parent hides its child windows without closing them; showing the parent does not restore those children. The overlay waits for both document readiness and a visible parent, then restores itself on subsequent parent show events. Keeping this in the shared overlay preserves ordinary and mandatory presentation without coupling update policy to onboarding or clearing an active block. + The shell polls the guest protocol in the [API proposal](../../proposed/feature/2026-09-08-desktop-mandatory-update-api.md), independently of business traffic. Configuration and application identity are embedded at packaging; packaged applications ignore environment overrides. The [Desktop README](../../../../apps/desktop/README.md) owns configuration fields and defaults. Packaging requires the policy origin selected by the updater deployment before artifact preparation or signing. Test uses isolated Feishu authentication; production remains anonymous. The test login window opens detached DevTools on F12 while retaining its sandbox, navigation allowlist, and memory-only Session. Only unpackaged development can omit policy configuration. This prevents a missing policy setting from silently producing a release without mandatory checks or a test build querying production policy. -A coordinator owns one immutable installed-client identity, one in-flight request, a deadline, interval jitter, and bounded failure backoff. Manual checks bypass scheduling but join in-flight work. Disposal aborts the request, awaits settlement, and prevents late publication. A flattened `40005` establishes blocking independently of optional title, detail, and download-page fields; localized fallback text and a retry action remain available, while an absent or unapproved page is not offered. Transport, JSON, business-code, or HTTP failures cannot clear a known block. Only a valid fresh no-force response clears it. Same-version offline persistence is not implemented because its product behavior remains undecided. +A coordinator owns one in-flight request, a deadline, interval jitter, and bounded failure backoff. The request identifies the installed client with the same five Platform client headers as account requests — platform, client version, locale, UTC offset in seconds, and an intentionally empty bundle id — and adds architecture, update channel, and bundled runtime version. Platform, architecture, update channel, and bundled runtime version are fixed at packaging, while the locale and UTC offset are sampled from the shell for each request and the version is the shared client build version rather than the Electron bundle version. Manual checks bypass scheduling but join in-flight work. Disposal aborts the request, awaits settlement, and prevents late publication. A flattened `40005` establishes blocking independently of optional title, detail, and download-page fields; localized fallback text and a retry action remain available, while an absent or unapproved page is not offered. Transport, JSON, business-code, or HTTP failures cannot clear a known block. Only a valid fresh no-force response clears it. Same-version offline persistence is not implemented because its product behavior remains undecided. User-initiated ordinary checks trigger an independent policy refresh without waiting for or presenting its failures. A confirmed block alone cancels ordinary dialogs and transfers presentation to the mandatory dialog. Test authentication waits until an active ordinary dialog finishes; cancellation and failure leave the updater result intact. Concurrent callers reuse the active ordinary or authentication operation instead of creating competing windows. diff --git a/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.zh.md b/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.zh.md index 6c17a9fbd0..f3c862fdcc 100644 --- a/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.zh.md +++ b/.agents/notes/implemented/feature/2026-09-11-desktop-mandatory-update-client.zh.md @@ -10,9 +10,11 @@ Status: implemented ## 决策 +原生更新浮层在关闭前持有父窗口可见性监听。在 macOS 上,隐藏父窗口会隐藏但不会关闭其子窗口;重新显示父窗口不会恢复这些子窗口。浮层等待文档就绪且父窗口可见,并在后续父窗口显示事件中恢复自身。由公共浮层处理这一行为,既保持普通更新和强更的展示,也不将更新策略与 onboarding 耦合或清除有效阻塞。 + 壳独立于业务流量轮询[接口提案](../../proposed/feature/2026-09-08-desktop-mandatory-update-api.zh.md)中的游客协议。配置和应用身份在打包时嵌入;打包应用忽略环境覆盖。[Desktop README](../../../../apps/desktop/README.zh.md)负责配置字段与默认值。打包在准备产物或签名前要求提供由 updater 部署环境选定的策略源站。测试环境使用隔离的飞书鉴权;正式环境保持匿名。测试登录窗口按 F12 会打开独立的 DevTools,同时保留沙箱、导航允许列表和仅驻内存的 Session。只有未打包开发模式可以省略策略配置。这避免因遗漏策略配置而静默产出没有强更检查的发布包,或让测试包查询正式环境策略。 -协调器拥有一份不可变的已安装客户端身份、单一在途请求、截止时间、间隔抖动和有上限的失败退避。手动检查绕过调度,但复用在途请求。dispose(资源释放)中止请求、等待结算,并阻止迟到发布。扁平化 `40005` 建立阻塞不依赖可选的标题、详情和下载页面字段;本地化兜底文案与重试操作仍可使用,缺失或未获批准的页面地址不会展示。传输、JSON、业务码或 HTTP 错误都不能清除已知阻塞。只有新的有效无需强更响应才能清除它。同版本离线持久化未实现,因为其产品行为尚未确定。 +协调器持有单一在途请求、截止时间、间隔抖动和有上限的失败退避。请求用与账号请求相同的五个 Platform 客户端请求头标识已安装客户端——平台、客户端版本、语言、以秒为单位的 UTC 偏移,以及有意保持为空的 bundle id——并额外携带架构、更新通道和内置运行时版本。平台、架构、更新通道和内置运行时版本在打包时固定;语言与 UTC 偏移在每次请求时从壳采样,版本取自共享的客户端构建版本而非 Electron 打包版本。手动检查绕过调度,但复用在途请求。dispose(资源释放)中止请求、等待结算,并阻止迟到发布。扁平化 `40005` 建立阻塞不依赖可选的标题、详情和下载页面字段;本地化兜底文案与重试操作仍可使用,缺失或未获批准的页面地址不会展示。传输、JSON、业务码或 HTTP 错误都不能清除已知阻塞。只有新的有效无需强更响应才能清除它。同版本离线持久化未实现,因为其产品行为尚未确定。 用户发起常规检查时会触发独立的策略刷新,但不会等待或展示策略失败。只有已确认的强更决定会取消常规弹窗,并把展示移交给强更弹窗。测试环境鉴权会等待当前常规弹窗结束;取消和失败会保留 updater 结果。并发调用方复用当前常规操作或鉴权操作,不创建相互竞争的窗口。 diff --git a/.agents/notes/implemented/feature/2026-09-11-sidebar-document-preview-polish.i18n.yaml b/.agents/notes/implemented/feature/2026-09-11-sidebar-document-preview-polish.i18n.yaml index fe0979cdb2..bffd9997fe 100644 --- a/.agents/notes/implemented/feature/2026-09-11-sidebar-document-preview-polish.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-11-sidebar-document-preview-polish.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-sidebar-document-preview-polish.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-11-sidebar-document-preview-polish.md -2026-09-11-sidebar-document-preview-polish.md: b78141881513167a08050afb287eb4d1bcb43995 -2026-09-11-sidebar-document-preview-polish.zh.md: 43016af0dff72ed09a19271535912ba9abd65d9c +/agent-note-sidebar-document-preview-polish: + en: f6de5780a080c43b + zh: 43c5fe472e41c955 +/agent-note-sidebar-document-preview-polish/problem: + en: 4a52e0a397d95c28 + zh: ecaeb3f570c775da +/agent-note-sidebar-document-preview-polish/decision: + en: 6292b936ed7ee1bb + zh: 1758900c96a6811b +/agent-note-sidebar-document-preview-polish/alternatives-considered: + en: e2e5b8bbd191385e + zh: 29b37f3ec312f5ca +/agent-note-sidebar-document-preview-polish/consequences: + en: 38951cfb55e9214c + zh: 6ca3845e206be2da diff --git a/.agents/notes/implemented/feature/2026-09-11-turn-changed-files-card.i18n.yaml b/.agents/notes/implemented/feature/2026-09-11-turn-changed-files-card.i18n.yaml index 376ac2b6d8..26ab339a79 100644 --- a/.agents/notes/implemented/feature/2026-09-11-turn-changed-files-card.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-11-turn-changed-files-card.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-turn-changed-files-card.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-11-turn-changed-files-card.md -2026-09-11-turn-changed-files-card.md: 0c41783c6d5d02fecd0c85298aed1f07f5c8a65f -2026-09-11-turn-changed-files-card.zh.md: f417b31b899529b664664926c832c28f4b1be6ba +/agent-note-turn-changed-files-card: + en: 21aea14160ab0796 + zh: c8b389f1b684f677 +/agent-note-turn-changed-files-card/problem: + en: f3416b4d37371155 + zh: 52e22bd5a90358e5 +/agent-note-turn-changed-files-card/decision: + en: 75a1a9aa9b204844 + zh: 941fdb3556ebe035 +/agent-note-turn-changed-files-card/alternatives-considered: + en: 7ade7ce52c2a320d + zh: 18832d5f45568429 +/agent-note-turn-changed-files-card/consequences: + en: 33504bcb31f30f84 + zh: c6626b532701fcc7 diff --git a/.agents/notes/implemented/feature/2026-09-12-mcp-resources-and-instructions.i18n.yaml b/.agents/notes/implemented/feature/2026-09-12-mcp-resources-and-instructions.i18n.yaml index 44220ef7f3..05daf52fa7 100644 --- a/.agents/notes/implemented/feature/2026-09-12-mcp-resources-and-instructions.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-12-mcp-resources-and-instructions.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-mcp-resources-and-instructions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-12-mcp-resources-and-instructions.md -2026-09-12-mcp-resources-and-instructions.md: a5eabd6170507d5a4df295b8554e6da47b40b9be -2026-09-12-mcp-resources-and-instructions.zh.md: 44890b23944f482a2e1a38483029f1e61caebbe1 +/agent-note-on-demand-mcp-resources-and-scoped-server-instructions: + en: 052fc1f95f280688 + zh: fdfacc841597d4da +/agent-note-on-demand-mcp-resources-and-scoped-server-instructions/problem: + en: 0d6c75e85a04c36a + zh: fe5043f324369cdd +/agent-note-on-demand-mcp-resources-and-scoped-server-instructions/decision: + en: 69a021dd23820bb8 + zh: 447d2d8d03f12896 +/agent-note-on-demand-mcp-resources-and-scoped-server-instructions/alternatives-considered: + en: 02bc8e76ce4d68ab + zh: 0991cc64ff9e3011 +/agent-note-on-demand-mcp-resources-and-scoped-server-instructions/verification: + en: 41694d9121383436 + zh: 781ea7503ea149f1 +/agent-note-on-demand-mcp-resources-and-scoped-server-instructions/consequences: + en: 432b24aa763eff2e + zh: 236825ede84e2c0d diff --git a/.agents/notes/implemented/feature/2026-09-12-mcp-sdk-protocol-negotiation.i18n.yaml b/.agents/notes/implemented/feature/2026-09-12-mcp-sdk-protocol-negotiation.i18n.yaml index 61450c1d3c..25b2735cf8 100644 --- a/.agents/notes/implemented/feature/2026-09-12-mcp-sdk-protocol-negotiation.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-12-mcp-sdk-protocol-negotiation.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-mcp-sdk-protocol-negotiation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-12-mcp-sdk-protocol-negotiation.md -2026-09-12-mcp-sdk-protocol-negotiation.md: 74f027cead92688b0af71c1028d536b26f2a8059 -2026-09-12-mcp-sdk-protocol-negotiation.zh.md: bc8a9a41b8ccd8cbc844b4b9de8b39a646d1dcbf +/agent-note-mcp-sdk-protocol-negotiation: + en: 9228ca2f4da2f41b + zh: 7cd10429865c3f2d +/agent-note-mcp-sdk-protocol-negotiation/problem: + en: bd614e17c62d137e + zh: ee71fdcd310a9592 +/agent-note-mcp-sdk-protocol-negotiation/decision: + en: ed7b45ffcaeffedd + zh: 2287d525ec04006c +/agent-note-mcp-sdk-protocol-negotiation/alternatives-considered: + en: 1fba2ebdcc100c37 + zh: 45c384641d3b0300 +/agent-note-mcp-sdk-protocol-negotiation/consequences: + en: 1a50179c0254517c + zh: 046e4f72bfc2ea89 diff --git a/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.i18n.yaml b/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.i18n.yaml index d15870537e..ccb4558c12 100644 --- a/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-13-macos-hidden-titlebar-vibrancy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.md -2026-09-13-macos-hidden-titlebar-vibrancy.md: 807c79d06c468e01b8b9df3f18a32e5fbaba1e90 -2026-09-13-macos-hidden-titlebar-vibrancy.zh.md: a521aff7624b1f9dbab18e7d0f02f61af0bdc24a +/agent-note-macos-hidden-titlebar-with-vibrancy-sidebar: + en: 1872fd56128fb565 + zh: dc7b04d80eda9880 +/agent-note-macos-hidden-titlebar-with-vibrancy-sidebar/problem: + en: 199f00b0e7f3c09c + zh: bb331fc8d7d46bbd +/agent-note-macos-hidden-titlebar-with-vibrancy-sidebar/decision: + en: f59c3d276d0fb5c0 + zh: 85509dca9810cd4d +/agent-note-macos-hidden-titlebar-with-vibrancy-sidebar/alternatives-considered: + en: 28d920253012bd11 + zh: ae6a27f959d5afe3 +/agent-note-macos-hidden-titlebar-with-vibrancy-sidebar/consequences: + en: e08ce133c72863d8 + zh: e67b5c3bff579d86 +/agent-note-macos-hidden-titlebar-with-vibrancy-sidebar/testing: + en: a075febd9b78dc5f + zh: 7c59a9b7f0798dac diff --git a/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.md b/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.md index 807c79d06c..7e69fea3a4 100644 --- a/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.md +++ b/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.md @@ -18,11 +18,11 @@ Every macOS web-side adjustment keys off `html[data-platform='darwin']`, which o **Native theme sync.** The vibrancy material follows `nativeTheme.themeSource`, which otherwise tracks the OS appearance and diverges from the app's own theme preference. The ui-theme boot script and ui-layout `ThemePresenter` publish `html[data-ds-theme-source]` (`light`, `dark`, or `system`; a fixed preference, including registered theme ids, publishes its resolved scheme). The app preload observes the attribute and forwards it over `dsh-desktop:native-theme-set`; main validates the value and the sender (the main window's WebContents, including its local static Web document) and assigns `nativeTheme.themeSource`. Publishing the preference rather than the resolved scheme preserves OS-follow while the preference is `system`. -**Sidebar top strip and full hide.** On darwin the sidebar opens with a 52px top strip that clears the traffic lights and carries the collapse toggle; the frame's `.leadingBand` drag band covers the same 52px geometry, so the strip declares no app-region of its own and the toggle subtracts itself through the base.css interactive rule. Collapsing the sidebar hides the column entirely — `computeColumns` takes an explicit `collapsedWidth` and the AppFrame passes 0 on darwin desktop — instead of the 56px rail the other platforms keep. The reopen affordances live in the frame's root-scoped `shell.leading` window-chrome seat, which the AppFrame mounts only while the column is fully hidden; ui-sidebar registers `HeaderLeadingControls` (open sidebar + New Session, reusing the shell's inject face and locale) into it. The seat placement, the `--dsh-frame-leading-clearance` variable panels pad by, and the removal of the earlier conversation-header seat are owned by the [shell.leading Agent Note](../architecture/2026-09-17-frame-shell-leading-window-chrome-seat.md). +**Sidebar top strip and full hide.** On darwin the sidebar opens with a 52px top strip that clears the traffic lights and carries the collapse toggle; the strip marks itself `data-window-drag`, so its own 52px box is the window's drag region (ui-web base.css declares the one darwin drag rule) and the toggle subtracts itself through the base.css interactive rule. Collapsing the sidebar hides the column entirely — `computeColumns` takes an explicit `collapsedWidth` and the AppFrame passes 0 on darwin desktop — instead of the 56px rail the other platforms keep. The reopen affordances live in the frame's root-scoped `shell.leading` window-chrome seat, which the AppFrame mounts only while the column is fully hidden; ui-sidebar registers `HeaderLeadingControls` (open sidebar + New Session, reusing the shell's inject face and locale) into it. The seat placement, the `--dsh-frame-leading-clearance` variable panels pad by, and the removal of the earlier conversation-header seat are owned by the [shell.leading Agent Note](../architecture/2026-09-17-frame-shell-leading-window-chrome-seat.md). **Window fullscreen marker.** macOS fullscreen hides the traffic lights, so layouts built around them must relax. The main process relays `isFullScreen()` over `dsh-desktop:window-fullscreen` on `enter-full-screen`, `leave-full-screen`, and each `did-finish-load`; the app preload's `syncWindowFullscreen()` mirrors it onto `html[data-fullscreen]`. Consumers: the AppFrame drops `--dsh-frame-leading-clearance` to 84px and moves the seat to `left: 12px`, the sidebar's `.topStrip` moves the toggle to the strip's left edge, and the right sidebar's fullscreen panel resets its first pane's dockkit strip inset to the ordinary 10px. -**Drag regions.** Electron computes drag regions from window geometry in DOM order, not stacking, so `-webkit-app-region: drag` is declared only inside the two allowlisted stylesheets: ui-layout `AppFrame.module.css` (the darwin `.leadingBand`, a 52px full-width `pointer-events: none` strip rendered as the frame's first child, and the Windows caption `.frame::before`) and ui-sidebar `SidebarRoot.module.css` (`.logoRow`, which extends the band below 52px). Everything interactive subtracts itself through two global ui-web base.css rules: one `:is(...)` selector opting out every interactive element (buttons, links, inputs, roles, `[tabindex]`), and one `body > :not(#root)` rule covering every overlay portaled beside `#root`. Because the drag bands mount before all content, any later no-drag box wins; content containers never declare drag, which would override earlier-mounted overlays. +**Drag regions.** Electron computes drag regions from window geometry in DOM order, not stacking, so the shell declares `-webkit-app-region: drag` once, over the mark a chrome row puts on its own box, each row's box being its draggable geometry. The ui-theme app-region gate's `CHROME_ROWS` manifest is the list of rows that must carry the mark, so this note keeps only the mechanism. The frame declares none — the Windows caption row is that platform's own chrome — so no fixed band has to match any row's height. Everything interactive subtracts itself through two global ui-web base.css rules: one `:is(...)` selector opting out every interactive element (buttons, links, inputs, roles, `[tabindex]`), and one `body > :not(#root)` rule covering every overlay portaled beside `#root`. The ordering rule those two rest on: a surface that covers the window and must stay clickable portals beside `#root` (the settings overlay does), which puts it after every drag row in document order; content containers never declare drag, which would override earlier-mounted overlays. The [coverage contract note](../architecture/2026-09-19-window-drag-coverage-contract.md) owns the manifest, the browser lane, and the manual state matrix. **Fullscreen traffic-light clearance.** ui-dockkit publishes the tab strip's start inset as `--dsh-dockkit-strip-inline-start` (fallback the design's own 10px). The right sidebar's fullscreen presentation on darwin sets 88px on the panel body and resets 10px for every non-first split cell's subtree, so exactly the pane touching the window's top-left corner clears the lights at any split depth. @@ -43,9 +43,9 @@ Every macOS web-side adjustment keys off `html[data-platform='darwin']`, which o - The macOS window gains a translucent sidebar and hidden titlebar at zero cost to other platforms: every rule is scoped to `[data-platform='darwin']`, which only the Electron preload sets. - The vibrancy material follows the app theme, including third-party registered themes (their resolved scheme). Screenshots and screen recordings differ from the flat web rendering. - The reopen controls occupy the frame's `shell.leading` seat, a public slot in the client catalog; the earlier `conversation.session.header.leading` seat is removed ([shell.leading Agent Note](../architecture/2026-09-17-frame-shell-leading-window-chrome-seat.md)). -- Drag-region ownership is a window-global invariant: `-webkit-app-region: drag` appears only inside the two allowlisted stylesheets (ui-layout `AppFrame.module.css`: darwin `.leadingBand` and Windows caption `.frame::before`; ui-sidebar `SidebarRoot.module.css`: `.logoRow`); other packages rely on the base.css opt-outs or add a scoped `no-drag`, never a new drag surface. The ui-theme app-region stylesheet gate enforces the allowlist over every package stylesheet. +- Drag-region ownership is a window-global invariant: `-webkit-app-region: drag` appears only in ui-web `base.css` (the one darwin rule over `data-window-drag`) and in ui-layout `AppFrame.module.css` (the Windows caption `.frame::before`); other packages rely on the base.css opt-outs or add a scoped `no-drag`, never a new drag surface. The ui-theme app-region gate pairs each chrome row's markup mark with its sheet, selector, and authored height, and refuses a mark anywhere else. - The transparent window plus vibrancy is accepted to look different in screen sharing and may flash on startup; the transparent `backgroundColor` mitigates the flash. ## Testing -ui-theme boot and ui-layout presenter specs pin the `data-ds-theme-source` publication and disposal. The ui-sidebar apply spec pins the `shell.leading` registration (component, locale, shared inject face) and its removal on teardown; the ui-layout app-frame spec pins the seat's darwin mount. The desktop main-startup spec pins the fullscreen relay (transitions, reloads, destroyed-window guard, darwin-only registration) and the preload-platform spec pins the `html[data-fullscreen]` mirror. The ui-theme corner-shape and full-round style gates cover the new stylesheet, and its app-region style gate pins drag-region ownership to the two allowlisted stylesheets across every package stylesheet. +ui-theme boot and ui-layout presenter specs pin the `data-ds-theme-source` publication and disposal. The ui-sidebar apply spec pins the `shell.leading` registration (component, locale, shared inject face) and its removal on teardown; the ui-layout app-frame spec pins the seat's darwin mount. The desktop main-startup spec pins the fullscreen relay (transitions, reloads, destroyed-window guard, darwin-only registration) and the preload-platform spec pins the `html[data-fullscreen]` mirror. The ui-theme corner-shape and full-round style gates cover the new stylesheet, and its app-region gate pins the one darwin drag rule and every chrome row's markup mark. diff --git a/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.zh.md b/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.zh.md index a521aff762..fbba185740 100644 --- a/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.zh.md +++ b/.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.zh.md @@ -18,11 +18,11 @@ Electron 主进程在 darwin 上以 `titleBarStyle: 'hiddenInset'`、`trafficLig **原生主题同步。** 毛玻璃材质跟随 `nativeTheme.themeSource`,后者默认跟踪系统外观,会与应用自身的主题偏好背离。ui-theme 引导脚本与 ui-layout 的 `ThemePresenter` 发布 `html[data-ds-theme-source]`(`light`、`dark` 或 `system`;固定偏好——包括注册主题 id——发布其解析后的配色)。应用 preload 观察该属性并经 `dsh-desktop:native-theme-set` 转发;主进程校验取值与发送者(主窗口的 WebContents,包括其本地静态 Web 文档)后赋给 `nativeTheme.themeSource`。发布偏好而非解析值,可在偏好为 `system` 时保留跟随系统。 -**侧边栏顶部条与完全隐藏。** darwin 上侧边栏展开时有一条 52px 的顶部条,避开红绿灯并承载收起按钮;框架的 `.leadingBand` 拖拽带覆盖同一 52px 几何,顶部条自身不声明 app-region,按钮经 base.css 交互规则自行减除。收起侧边栏时整列隐藏——`computeColumns` 接受显式 `collapsedWidth`,AppFrame 在 darwin 桌面传 0——而非其他平台保留的 56px rail。重新打开的入口位于框架 root 作用域的 `shell.leading` 窗口 chrome 座,由 AppFrame 仅在整列隐藏时挂载;ui-sidebar 向其注册 `HeaderLeadingControls`(打开侧边栏 + 新会话,复用 shell 的 inject face 与 locale)。座的位置、面板用于避让的 `--dsh-frame-leading-clearance` 变量,以及早先会话头部座的移除,归 [shell.leading Agent Note](../architecture/2026-09-17-frame-shell-leading-window-chrome-seat.zh.md) 所有。 +**侧边栏顶部条与完全隐藏。** darwin 上侧边栏展开时有一条 52px 的顶部条,避开红绿灯并承载收起按钮;顶部条自己打上 `data-window-drag`,于是它自身那 52px 盒子就是窗口的拖拽区(唯一的 darwin drag 规则由 ui-web base.css 声明),按钮经 base.css 交互规则自行减除。收起侧边栏时整列隐藏——`computeColumns` 接受显式 `collapsedWidth`,AppFrame 在 darwin 桌面传 0——而非其他平台保留的 56px rail。重新打开的入口位于框架 root 作用域的 `shell.leading` 窗口 chrome 座,由 AppFrame 仅在整列隐藏时挂载;ui-sidebar 向其注册 `HeaderLeadingControls`(打开侧边栏 + 新会话,复用 shell 的 inject face 与 locale)。座的位置、面板用于避让的 `--dsh-frame-leading-clearance` 变量,以及早先会话头部座的移除,归 [shell.leading Agent Note](../architecture/2026-09-17-frame-shell-leading-window-chrome-seat.zh.md) 所有。 **窗口全屏标记。** macOS 全屏隐藏红绿灯,围绕它们构建的布局必须放松。主进程在 `enter-full-screen`、`leave-full-screen` 与每次 `did-finish-load` 时经 `dsh-desktop:window-fullscreen` 转发 `isFullScreen()`;应用 preload 的 `syncWindowFullscreen()` 把它镜像到 `html[data-fullscreen]`。消费者:AppFrame 把 `--dsh-frame-leading-clearance` 降到 84px 并把座移到 `left: 12px`,侧边栏 `.topStrip` 把收起按钮移到条带左端,右侧边栏全屏面板把首格 pane 的 dockkit strip 内边距重置回常规 10px。 -**拖拽区。** Electron 按 DOM 顺序以窗口几何计算拖拽区,不看层叠,因此 `-webkit-app-region: drag` 只在两个允许清单样式表内声明:ui-layout `AppFrame.module.css`(darwin 的 `.leadingBand`——52px 全宽、`pointer-events: none`、作为框架第一个子元素渲染的条带——与 Windows 顶栏 `.frame::before`)和 ui-sidebar `SidebarRoot.module.css`(`.logoRow`,把拖拽带向 52px 以下延伸)。所有可交互内容通过 ui-web base.css 的两条全局规则自行减除:一条 `:is(...)` 选择器让每个交互元素(按钮、链接、输入框、role、`[tabindex]`)退出拖拽,一条 `body > :not(#root)` 规则覆盖所有 portal 到 `#root` 之外的浮层。拖拽带先于全部内容挂载,任何靠后的 no-drag 盒子必然生效;内容容器永不声明 drag——那会覆盖更早挂载的浮层。 +**拖拽区。** Electron 按 DOM 顺序以窗口几何计算拖拽区,不看层叠,因此外壳只声明一次 `-webkit-app-region: drag`,作用于 chrome 行打在自身盒子上的标记,行自身的盒子就是它的可拖几何;哪些行必须带这个标记由 ui-theme app-region 门禁的 `CHROME_ROWS` 清单拥有,本 note 只保留机制。框架不再声明任何 drag——Windows 标题栏行是那个平台自己的 chrome——因此没有一条固定带子需要匹配某一行的高度。所有可交互内容通过 ui-web base.css 的两条全局规则自行减除:一条 `:is(...)` 选择器让每个交互元素(按钮、链接、输入框、role、`[tabindex]`)退出拖拽,一条 `body > :not(#root)` 规则覆盖所有 portal 到 `#root` 之外的浮层。这两条规则依赖的顺序约定:覆盖窗口且必须可点的表面 portal 到 `#root` 之外(settings 浮层即如此),从而在文档顺序上晚于所有 drag 行;内容容器永不声明 drag——那会覆盖更早挂载的浮层。清单、浏览器车道与人工状态矩阵归 [覆盖契约 note](../architecture/2026-09-19-window-drag-coverage-contract.zh.md)。 **全屏避开红绿灯。** ui-dockkit 把 tab 条起始内边距发布为 `--dsh-dockkit-strip-inline-start`(回退为设计自身的 10px)。右侧边栏全屏形态在 darwin 上对面板主体设 88px,并对每个非首格 split 单元的子树重置为 10px,使得任意分屏深度下恰好只有触及窗口左上角的 pane 避开红绿灯。 @@ -43,9 +43,9 @@ Electron 主进程在 darwin 上以 `titleBarStyle: 'hiddenInset'`、`trafficLig - macOS 窗口获得半透明侧边栏与隐藏标题栏,对其他平台零成本:所有规则限定在 `[data-platform='darwin']` 下,该属性仅由 Electron preload 设置。 - 毛玻璃材质跟随应用主题,含第三方注册主题(取其解析配色)。截图与录屏与纯 Web 的平面渲染不同。 - 重新打开控件占据框架的 `shell.leading` 座,是客户端 catalog 中的公开 slot;早先的 `conversation.session.header.leading` 座已移除([shell.leading Agent Note](../architecture/2026-09-17-frame-shell-leading-window-chrome-seat.zh.md))。 -- 拖拽区归属是窗口级全局不变量:`-webkit-app-region: drag` 只出现在两个允许清单样式表内(ui-layout `AppFrame.module.css`:darwin `.leadingBand` 与 Windows 顶栏 `.frame::before`;ui-sidebar `SidebarRoot.module.css`:`.logoRow`);其他包依赖 base.css 的退出规则或添加限定范围的 `no-drag`,永不新增拖拽面。ui-theme 的 app-region 样式门禁对全部包内样式表强制该允许清单。 +- 拖拽区归属是窗口级全局不变量:`-webkit-app-region: drag` 只出现在 ui-web `base.css`(作用于 `data-window-drag` 的唯一 darwin 规则)与 ui-layout `AppFrame.module.css`(Windows 顶栏 `.frame::before`)内;其他包依赖 base.css 的退出规则或添加限定范围的 `no-drag`,永不新增拖拽面。ui-theme 的 app-region 门禁把每个 chrome 行的 markup 标记与它的样式表、选择器和写死高度配成一条,并拒绝别处的标记。 - 接受透明窗口 + 毛玻璃在屏幕共享中呈现不同、启动可能闪烁;透明 `backgroundColor` 缓解闪烁。 ## Testing -ui-theme 引导与 ui-layout presenter 测试钉住 `data-ds-theme-source` 的发布与清除。ui-sidebar apply 测试钉住 `shell.leading` 注册(组件、locale、共享 inject face)及 teardown 移除;ui-layout 的 app-frame 测试钉住 darwin 下座的挂载。desktop main-startup 测试钉住全屏转发(状态切换、重载、已销毁窗口守卫、仅 darwin 注册),preload-platform 测试钉住 `html[data-fullscreen]` 镜像。ui-theme 的 corner-shape 与 full-round 样式门覆盖新样式表,其 app-region 样式门在全部包内样式表上把拖拽区归属钉在两个允许清单样式表内。 +ui-theme 引导与 ui-layout presenter 测试钉住 `data-ds-theme-source` 的发布与清除。ui-sidebar apply 测试钉住 `shell.leading` 注册(组件、locale、共享 inject face)及 teardown 移除;ui-layout 的 app-frame 测试钉住 darwin 下座的挂载。desktop main-startup 测试钉住全屏转发(状态切换、重载、已销毁窗口守卫、仅 darwin 注册),preload-platform 测试钉住 `html[data-fullscreen]` 镜像。ui-theme 的 corner-shape 与 full-round 样式门覆盖新样式表,其 app-region 门禁钉住唯一那条 darwin drag 规则与每个 chrome 行的 markup 标记。 diff --git a/.agents/notes/implemented/feature/2026-09-13-mcp-resources-in-profiles.i18n.yaml b/.agents/notes/implemented/feature/2026-09-13-mcp-resources-in-profiles.i18n.yaml index ea2358fcd3..854c136a37 100644 --- a/.agents/notes/implemented/feature/2026-09-13-mcp-resources-in-profiles.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-13-mcp-resources-in-profiles.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-13-mcp-resources-in-profiles.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-13-mcp-resources-in-profiles.md -2026-09-13-mcp-resources-in-profiles.md: 236cd2849383e32fee523c56a43aae2fcae1f07a -2026-09-13-mcp-resources-in-profiles.zh.md: d2e0fbc45cdffe16ac482173d75c13329b98b868 +/agent-note-mcp-resource-availability-follows-configured-servers: + en: 2f520034ae7711ed + zh: 0e76516042ef51c1 +/agent-note-mcp-resource-availability-follows-configured-servers/problem: + en: 729c308d0bb4e142 + zh: 42df44189f83a701 +/agent-note-mcp-resource-availability-follows-configured-servers/decision: + en: 6d79d22b7a2d118a + zh: 9e7aaccbcb6535c0 +/agent-note-mcp-resource-availability-follows-configured-servers/alternatives-considered: + en: e60cb2c45a8a8cf7 + zh: e74f3b9ca5157278 +/agent-note-mcp-resource-availability-follows-configured-servers/verification: + en: d07e735ad317655c + zh: c9419acac96f0740 +/agent-note-mcp-resource-availability-follows-configured-servers/consequences: + en: 270341820e2713d4 + zh: d56cdd72625fd570 diff --git a/.agents/notes/implemented/feature/2026-09-14-composer-selection-keyboard.i18n.yaml b/.agents/notes/implemented/feature/2026-09-14-composer-selection-keyboard.i18n.yaml index 9c3ae26c74..ce405a2db5 100644 --- a/.agents/notes/implemented/feature/2026-09-14-composer-selection-keyboard.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-14-composer-selection-keyboard.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-composer-selection-keyboard.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-14-composer-selection-keyboard.md -2026-09-14-composer-selection-keyboard.md: 675e7239108604c51f4e9a82b98e164833ff9173 -2026-09-14-composer-selection-keyboard.zh.md: 2b296a609cdd76a407fd4ddcc5855eef2fcfa047 +/agent-note-composer-selection-surfaces-mirror-the-composer-s-enter-and-escape-keys: + en: d3af1337a24bd411 + zh: ebf464a7f3d9b5c3 +/agent-note-composer-selection-surfaces-mirror-the-composer-s-enter-and-escape-keys/problem: + en: e5f4084d8eda4d0e + zh: 4dc98999d008fecd +/agent-note-composer-selection-surfaces-mirror-the-composer-s-enter-and-escape-keys/decision: + en: d6a84d4b3d935fbb + zh: b842b20d197fc1a6 +/agent-note-composer-selection-surfaces-mirror-the-composer-s-enter-and-escape-keys/alternatives-considered: + en: f062131fb8b9cbcf + zh: a14b718ed6381b3f +/agent-note-composer-selection-surfaces-mirror-the-composer-s-enter-and-escape-keys/verification: + en: 81508f6216c1cde0 + zh: 764a8cafea8594e5 +/agent-note-composer-selection-surfaces-mirror-the-composer-s-enter-and-escape-keys/consequences: + en: 1310807e3a7a259d + zh: c35aca580ee553b7 diff --git a/.agents/notes/implemented/feature/2026-09-14-desktop-primary-runtime.i18n.yaml b/.agents/notes/implemented/feature/2026-09-14-desktop-primary-runtime.i18n.yaml index 27bbadb4ae..56a6a1ef1e 100644 --- a/.agents/notes/implemented/feature/2026-09-14-desktop-primary-runtime.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-14-desktop-primary-runtime.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-desktop-primary-runtime.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-14-desktop-primary-runtime.md -2026-09-14-desktop-primary-runtime.md: a1491ca0c47e40c6d5b885c9f6a42ccf8180b78c -2026-09-14-desktop-primary-runtime.zh.md: 6447086a6948ed262699b62061eb44af8d6071d7 +/agent-note-desktop-primary-runtime: + en: aac537d0aef9e6c3 + zh: 30166e8f8627087f +/agent-note-desktop-primary-runtime/problem: + en: 36bf235f0821ef6a + zh: a86bf07af03d54a3 +/agent-note-desktop-primary-runtime/decision: + en: b3b104e314762322 + zh: 77478c007893201f +/agent-note-desktop-primary-runtime/alternatives-considered: + en: 566fd91c30cb0a0a + zh: 70758ae2617f6ebb +/agent-note-desktop-primary-runtime/consequences: + en: d0583f2397b7f778 + zh: cf42263bc62ee947 diff --git a/.agents/notes/implemented/feature/2026-09-14-docs-mermaid-viewer.i18n.yaml b/.agents/notes/implemented/feature/2026-09-14-docs-mermaid-viewer.i18n.yaml index a2eba8f020..f43d81c749 100644 --- a/.agents/notes/implemented/feature/2026-09-14-docs-mermaid-viewer.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-14-docs-mermaid-viewer.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-docs-mermaid-viewer.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-14-docs-mermaid-viewer.md -2026-09-14-docs-mermaid-viewer.md: 5cb4bae84fcafb49c559b7678e9a9dc1aa961ab0 -2026-09-14-docs-mermaid-viewer.zh.md: 665ab65e48e15651ebb9323e96e6a950c0b48deb +/agent-note-documentation-diagram-and-image-viewer: + en: c43de97ff7fbe82d + zh: 5e2ecb9d39255ad7 +/agent-note-documentation-diagram-and-image-viewer/problem: + en: 3630dd02a8e8dfdf + zh: f25b00903e05bd05 +/agent-note-documentation-diagram-and-image-viewer/decision: + en: e82d48a7ebee05c8 + zh: af5c517d1d728f07 +/agent-note-documentation-diagram-and-image-viewer/alternatives-considered: + en: bdebec164a27c787 + zh: 8acb59417c96b807 +/agent-note-documentation-diagram-and-image-viewer/consequences: + en: f7bc4c0588dda49d + zh: 9261c0bde08031b1 diff --git a/.agents/notes/implemented/feature/2026-09-14-unattended-browser-terminal-reclamation.i18n.yaml b/.agents/notes/implemented/feature/2026-09-14-unattended-browser-terminal-reclamation.i18n.yaml index b8b927d5ab..11e6f533a5 100644 --- a/.agents/notes/implemented/feature/2026-09-14-unattended-browser-terminal-reclamation.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-14-unattended-browser-terminal-reclamation.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-unattended-browser-terminal-reclamation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-14-unattended-browser-terminal-reclamation.md -2026-09-14-unattended-browser-terminal-reclamation.md: 6eca6faa222ed744b8ebd4ef59b2dbaec25fd8ce -2026-09-14-unattended-browser-terminal-reclamation.zh.md: 9065fe53a7d7970c4523beaffb08b3df30a4944f +/agent-note-two-hour-reclamation-of-unattended-browser-terminals: + en: 7d9283383e551b42 + zh: c9d9ed029a0afcf2 +/agent-note-two-hour-reclamation-of-unattended-browser-terminals/problem: + en: bd5cfc222df1a98c + zh: b58a3570a98298ee +/agent-note-two-hour-reclamation-of-unattended-browser-terminals/decision: + en: 079c8a1e95099239 + zh: 613d888fd7bf6b61 +/agent-note-two-hour-reclamation-of-unattended-browser-terminals/alternatives-considered: + en: 165fedee22bdb52e + zh: 6b9b7054ddb2a3a9 +/agent-note-two-hour-reclamation-of-unattended-browser-terminals/consequences: + en: ded45621bb710e52 + zh: f5f9624fa5f608e8 diff --git a/.agents/notes/implemented/feature/2026-09-15-bundled-office-skills.i18n.yaml b/.agents/notes/implemented/feature/2026-09-15-bundled-office-skills.i18n.yaml index 00f68c0337..d220a04f6f 100644 --- a/.agents/notes/implemented/feature/2026-09-15-bundled-office-skills.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-15-bundled-office-skills.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-bundled-office-skills.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-15-bundled-office-skills.md -2026-09-15-bundled-office-skills.md: 089ca0326a7c53d4ee023608010efd49a8616db2 -2026-09-15-bundled-office-skills.zh.md: cd10aa863b1149594e9eb6b6a8e479511424f20d +/agent-note-bundled-office-skills-with-structural-verification: + en: 8cc7012d7343c387 + zh: 8565543be5d94a56 +/agent-note-bundled-office-skills-with-structural-verification/problem: + en: d1e1e74b0fa286de + zh: 61ce855e4726d4a3 +/agent-note-bundled-office-skills-with-structural-verification/decision: + en: 486c2b40a0a4fe3c + zh: 317f47318b27e8f8 +/agent-note-bundled-office-skills-with-structural-verification/alternatives-considered: + en: c5389aef638deb0c + zh: a11a99a269e81c6a +/agent-note-bundled-office-skills-with-structural-verification/consequences: + en: a6035aefa4443df3 + zh: f87c6f099e4f3c7d diff --git a/.agents/notes/implemented/feature/2026-09-15-changed-file-diff-preview.i18n.yaml b/.agents/notes/implemented/feature/2026-09-15-changed-file-diff-preview.i18n.yaml index bb657950e7..b52514834c 100644 --- a/.agents/notes/implemented/feature/2026-09-15-changed-file-diff-preview.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-15-changed-file-diff-preview.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-changed-file-diff-preview.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-15-changed-file-diff-preview.md -2026-09-15-changed-file-diff-preview.md: e265c1f4528f2de3a95ce0fab3e20cab1c83a3f6 -2026-09-15-changed-file-diff-preview.zh.md: 48571cd9866cb01e31609c90500d26b19802bb8e +/agent-note-turn-review-tab: + en: cdcf921443075122 + zh: 177609e61939922a +/agent-note-turn-review-tab/problem: + en: 91d904d836519a4b + zh: c0aec4e184ff924b +/agent-note-turn-review-tab/decision: + en: 8169e63f8bf8416d + zh: 24c1e3fb394983e3 +/agent-note-turn-review-tab/alternatives-considered: + en: e648f82b78a2c0d3 + zh: f4e6511766ace168 +/agent-note-turn-review-tab/consequences: + en: 2147596d8c6574da + zh: db8b2e1ce86465df diff --git a/.agents/notes/implemented/feature/2026-09-15-continuable-activation-capacity.i18n.yaml b/.agents/notes/implemented/feature/2026-09-15-continuable-activation-capacity.i18n.yaml index be51075feb..a373848ad2 100644 --- a/.agents/notes/implemented/feature/2026-09-15-continuable-activation-capacity.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-15-continuable-activation-capacity.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-continuable-activation-capacity.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-15-continuable-activation-capacity.md -2026-09-15-continuable-activation-capacity.md: a6403d10fd4bcfb73147a0482293429e108939e2 -2026-09-15-continuable-activation-capacity.zh.md: 75cf6ca7a352d503cfffef29416c0990f98185db +/agent-note-shared-continuable-activation-capacity: + en: 56a51d29c97b2c8e + zh: c99085a3b2deb97c +/agent-note-shared-continuable-activation-capacity/problem: + en: f940cc05cf90362d + zh: 1cdb4281d845c0da +/agent-note-shared-continuable-activation-capacity/decision: + en: e03ae0d516885585 + zh: bd81d197e097b1ee +/agent-note-shared-continuable-activation-capacity/alternatives-considered: + en: 54aefa812e00ce1e + zh: 08251d541b7991df +/agent-note-shared-continuable-activation-capacity/consequences: + en: 4792e84eeaac32ee + zh: 4c941792d03130a0 +/agent-note-shared-continuable-activation-capacity/verification: + en: f599edb8fb0112af + zh: a66f9102a79234f0 diff --git a/.agents/notes/implemented/feature/2026-09-15-docs-page-markdown-actions.i18n.yaml b/.agents/notes/implemented/feature/2026-09-15-docs-page-markdown-actions.i18n.yaml index 776fa5a823..87e8807409 100644 --- a/.agents/notes/implemented/feature/2026-09-15-docs-page-markdown-actions.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-15-docs-page-markdown-actions.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-docs-page-markdown-actions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-15-docs-page-markdown-actions.md -2026-09-15-docs-page-markdown-actions.md: ff4002fd69d670b743b7394544cf8486b141b5ce -2026-09-15-docs-page-markdown-actions.zh.md: 4e2db5e55f47104d1b2f401099648cc1d6a7dc34 +/agent-note-page-markdown-actions-in-the-documentation-site: + en: 135670d1e466e923 + zh: b071c98c104c6aa5 +/agent-note-page-markdown-actions-in-the-documentation-site/problem: + en: d8c4d91741fe4a3f + zh: 0dae755314b52d9d +/agent-note-page-markdown-actions-in-the-documentation-site/decision: + en: b02d9faf0f2dfa91 + zh: 994a9755e0ddf16c +/agent-note-page-markdown-actions-in-the-documentation-site/alternatives-considered: + en: 96b23eb170e4edf2 + zh: 63e91e6c425afe1b +/agent-note-page-markdown-actions-in-the-documentation-site/consequences: + en: 57a6d0707d1793cd + zh: b63d4f3f82f8c38f diff --git a/.agents/notes/implemented/feature/2026-09-15-docs-platform-command-tabs.i18n.yaml b/.agents/notes/implemented/feature/2026-09-15-docs-platform-command-tabs.i18n.yaml index f6c0f88653..ceadaacf73 100644 --- a/.agents/notes/implemented/feature/2026-09-15-docs-platform-command-tabs.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-15-docs-platform-command-tabs.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-docs-platform-command-tabs.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-15-docs-platform-command-tabs.md -2026-09-15-docs-platform-command-tabs.md: 4d44d1191a7ffc1601e15aa4d9f119a90e06b0dd -2026-09-15-docs-platform-command-tabs.zh.md: 450765b52d1507fa9b9e6a20a1854e6861655838 +/agent-note-platform-command-tabs-in-the-python-sdk-guide: + en: 3d96f04869d2a2fb + zh: 4a6ebfb3ccf9c69d +/agent-note-platform-command-tabs-in-the-python-sdk-guide/problem: + en: 8fb6ad2440352a06 + zh: 0809a5c9866e52ee +/agent-note-platform-command-tabs-in-the-python-sdk-guide/decision: + en: 0ec36e0eccea6209 + zh: 5df6069c60a55f31 +/agent-note-platform-command-tabs-in-the-python-sdk-guide/alternatives-considered: + en: a98aa2b8d03f11aa + zh: 0aefaa161a20a24e +/agent-note-platform-command-tabs-in-the-python-sdk-guide/consequences: + en: f3af5502a73e7725 + zh: 4ca34dfd993fcc21 diff --git a/.agents/notes/implemented/feature/2026-09-15-markdown-file-preview-links.i18n.yaml b/.agents/notes/implemented/feature/2026-09-15-markdown-file-preview-links.i18n.yaml index 182ff386d9..43efd357fe 100644 --- a/.agents/notes/implemented/feature/2026-09-15-markdown-file-preview-links.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-15-markdown-file-preview-links.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-markdown-file-preview-links.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-15-markdown-file-preview-links.md -2026-09-15-markdown-file-preview-links.md: d9d535afc5b005ae453bd7623e05c411e4d6932b -2026-09-15-markdown-file-preview-links.zh.md: 63c18e284b785ed5686721a0b04cf73c78c0ceb3 +/agent-note-markdown-file-preview-links: + en: 98c528496f33598e + zh: 640619a2dfa0255e +/agent-note-markdown-file-preview-links/problem: + en: ba7789f83fadbe95 + zh: 34bcaa0aed5f5c3b +/agent-note-markdown-file-preview-links/decision: + en: b986fe2640c2ebf4 + zh: e69700b233e7bd69 +/agent-note-markdown-file-preview-links/alternatives-considered: + en: d8a4d6ab17eb2880 + zh: 089419d53f71305a +/agent-note-markdown-file-preview-links/consequences: + en: c0fc2dd3d860edfa + zh: 129aa543b4a39e10 diff --git a/.agents/notes/implemented/feature/2026-09-15-profile-command-shorthand.i18n.yaml b/.agents/notes/implemented/feature/2026-09-15-profile-command-shorthand.i18n.yaml index 2ef9ed7383..5665220ce2 100644 --- a/.agents/notes/implemented/feature/2026-09-15-profile-command-shorthand.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-15-profile-command-shorthand.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-profile-command-shorthand.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-15-profile-command-shorthand.md -2026-09-15-profile-command-shorthand.md: 15bdf30b98eb814e299e8e2c3af3756b1f59aad1 -2026-09-15-profile-command-shorthand.zh.md: 77ffd2324fc8fe518368fce44f52ad85274eb7b5 +/agent-note-profile-command-shorthand: + en: 35f20a1162b8407f + zh: 33d263d534df0b1d +/agent-note-profile-command-shorthand/problem: + en: b5c950343e5fbe8c + zh: df2a055d2c0b3f53 +/agent-note-profile-command-shorthand/decision: + en: cc8d5ebd595fee34 + zh: 99cb3ade0f17fb7b +/agent-note-profile-command-shorthand/alternatives-considered: + en: 8d10eee94348e187 + zh: 5930dee3861058e1 +/agent-note-profile-command-shorthand/consequences: + en: bbfeb6e59bb8ba55 + zh: fc33289f717cb805 diff --git a/.agents/notes/implemented/feature/2026-09-15-sidebar-workspace-hierarchy.i18n.yaml b/.agents/notes/implemented/feature/2026-09-15-sidebar-workspace-hierarchy.i18n.yaml index fe452cfeb2..5f0daf0064 100644 --- a/.agents/notes/implemented/feature/2026-09-15-sidebar-workspace-hierarchy.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-15-sidebar-workspace-hierarchy.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-sidebar-workspace-hierarchy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-15-sidebar-workspace-hierarchy.md -2026-09-15-sidebar-workspace-hierarchy.md: 82e63684ec1d8c5d86e062b125aff6e1144ef8fa -2026-09-15-sidebar-workspace-hierarchy.zh.md: 07f9ff89b6e33fd4d46b5e386b4240ad12c177c5 +/agent-note-sidebar-workspace-hierarchy: + en: 6be9fd74b0422158 + zh: ba6dbc81479b75b5 +/agent-note-sidebar-workspace-hierarchy/problem: + en: dc209dd9d8c73af4 + zh: cc5384ba15ea0be0 +/agent-note-sidebar-workspace-hierarchy/decision: + en: 9f34c1e903475d25 + zh: 6b22b19f6da3d390 +/agent-note-sidebar-workspace-hierarchy/alternatives-considered: + en: b30322d71fc7c464 + zh: 36b218a82690cd19 +/agent-note-sidebar-workspace-hierarchy/consequences: + en: bf890a80351fa883 + zh: 05da81c7026a5204 diff --git a/.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.i18n.yaml b/.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.i18n.yaml index 5edfca99c1..caa8355929 100644 --- a/.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-browser-excel-preview.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-16-browser-excel-preview.md -2026-09-16-browser-excel-preview.md: 8a4bbd5dc838bc79e61f9b412af43b912a8fe019 -2026-09-16-browser-excel-preview.zh.md: f04170b28fe4c6d267b12958f47a392638bfaadb +/agent-note-browser-excel-preview-with-saved-formula-results: + en: 2437d7b03a82ed8b + zh: 7ca514afeba1ffde +/agent-note-browser-excel-preview-with-saved-formula-results/problem: + en: 518507d82a9f15f5 + zh: b857b75e0359ae6d +/agent-note-browser-excel-preview-with-saved-formula-results/decision: + en: f962826fcf5e3949 + zh: 8a9932d86332fb47 +/agent-note-browser-excel-preview-with-saved-formula-results/alternatives-considered: + en: 8d7ac06eaa3ba42c + zh: b6e43ae09e4df4fa +/agent-note-browser-excel-preview-with-saved-formula-results/consequences: + en: 62595b9a9b948422 + zh: 0618904d9ebfa7fc diff --git a/.agents/notes/implemented/feature/2026-09-16-desktop-onboarding.i18n.yaml b/.agents/notes/implemented/feature/2026-09-16-desktop-onboarding.i18n.yaml new file mode 100644 index 0000000000..636682a60e --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-16-desktop-onboarding.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-16-desktop-onboarding.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-16-desktop-onboarding.md +/agent-note-device-local-desktop-onboarding: + en: 84a5519665d72899 + zh: beaadffa0e139459 +/agent-note-device-local-desktop-onboarding/problem: + en: 50c7c883a2115b7e + zh: 60533d618a3b2da7 +/agent-note-device-local-desktop-onboarding/decision: + en: e228d2a308f8ad8a + zh: c5eee26119226f32 +/agent-note-device-local-desktop-onboarding/alternatives-considered: + en: 82debfeba02ecfdb + zh: c15d8fcc012058e3 +/agent-note-device-local-desktop-onboarding/consequences: + en: 65d1dbaf6b39d57a + zh: fa5b562c059b3203 diff --git a/.agents/notes/implemented/feature/2026-09-16-desktop-onboarding.md b/.agents/notes/implemented/feature/2026-09-16-desktop-onboarding.md new file mode 100644 index 0000000000..e8b1b99279 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-16-desktop-onboarding.md @@ -0,0 +1,33 @@ +# Agent Note: Device-local Desktop onboarding + +Status: implemented + +English | [中文](2026-09-16-desktop-onboarding.zh.md) + +## Problem + +Account users need an introduction to credit and display choices after native authentication. The native credential entry already has a separate startup responsibility; repeating browser onboarding or treating missing account data as a new user would couple presentation to authentication failures. + +## Decision + +The [account UI](../../../../packages/client/ui-settings-account/README.md#desktop-onboarding) mounts one shell overlay only when the Desktop preload marker exists, an account credential is stored, and the local introduction is unfinished. Host settings own versioned progress and completion for the installation, without a Platform completion flag or per-account history. Restart resumes the saved step; signing out hides the introduction without erasing it. A signed-out installation with configured model credentials records API-key completion after applying standard process, detailed usage, and enabled developer tools. Account sign-in discards a failed API-key completion write so retry cannot bypass the required welcome page. + +Welcome requires an explicit start. The credit page always appears, including for positive balances. Only a ready balance with no positive wallet triggers the additional continue-without-credit confirmation; failed or pending queries never imply zero. Returning from native recharge retains the credit page while the account owner refreshes details. Closing the application during recharge retains the credit step. + +Purpose and process selections persist as drafts. Office-only completion selects compact presentation. Development or both purposes require a process choice. Skipping any supported step selects standard process with compact usage and developer tools off. Completion applies Chat and shared developer-tool preferences before saving the done marker so a refused preference write cannot silently finish onboarding. Compact, standard, and detailed persist their corresponding `ui-chat.transcriptView` values. + +The existing [native welcome decision](../architecture/2026-09-08-desktop-welcome-window-material.md) owns credential entry, IPC restrictions, and window material. Desktop suppresses automatic Web credential onboarding while retaining explicit API-key editing. Onboarding creates no workspace, demonstration task, or Session event. Static Figma illustrations use transparent, palette-compressed 3× PNG assets; welcome layers are merged with local sidebar blur; recharge uses a 70% opaque foreground window with local blur of the covered illustration. The account package owns the full-window overlay and its control styling; shared primitives retain generic behavior. Brand headings load a bundled, licensed Montserrat WOFF2 font through the Web entry. Choices retain focus during writes, reduced-motion preferences disable animation, and the application remains inert until the exit overlay unmounts. The confirmation dialog blurs its source page instead of sampling another backdrop in the translucent window. + +## Alternatives considered + +**Cloud or per-account completion.** The current release requires device-local progress and has no account completion API. Reusing login state as completion would conflate successful authentication with finished setup. + +**Skipping credit for positive balances or waiting for recharge confirmation.** The introduction explains billing independently of wallet state. Waiting for a balance query would turn return navigation into a network-dependent action without establishing whether a payment completed. + +**Duplicating preference controls.** Onboarding writes work details, usage, and developer tools through their existing owners. + +## Consequences + +An existing API-key installation without an onboarding completion marker also receives these defaults on its first upgraded launch, replacing any prior Chat display, usage, and developer-tools preferences. Installations already marked complete retain their preferences. + +One installation's completion applies across account changes, and another installation runs its own introduction. Preference and completion writes are ordered but are not one transaction; retry can reapply the same preference after a failed completion write. Completed installations do not reapply preferences on subsequent launches. The [controller tests](../../../../packages/client/ui-settings-account/tests/onboarding-state.client.spec.ts) and [UI tests](../../../../packages/client/ui-settings-account/tests/desktop-onboarding.client.spec.tsx) own state and interaction coverage; production authorization and payment behavior remain separate integration validation. diff --git a/.agents/notes/implemented/feature/2026-09-16-desktop-onboarding.zh.md b/.agents/notes/implemented/feature/2026-09-16-desktop-onboarding.zh.md new file mode 100644 index 0000000000..8a23ff191a --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-16-desktop-onboarding.zh.md @@ -0,0 +1,33 @@ +# Agent Note: 设备本地 Desktop 引导 + +Status: implemented + +[English](2026-09-16-desktop-onboarding.md) | 中文 + +## 问题 + +账号用户在完成原生认证后,需要了解额度并选择展示方式。原生凭证入口已经承担独立的启动职责;重复运行浏览器引导,或将缺失的账号数据当成新用户,会把展示流程与认证故障耦合。 + +## 决策 + +[账号 UI](../../../../packages/client/ui-settings-account/README.zh.md#desktop-onboarding)仅在存在 Desktop preload 标记、已存储账号凭证且本地引导未完成时,挂载一个 shell 覆盖层。Host 设置持有当前安装的版本化进度与完成状态,不使用 Platform 完成标记或逐账号历史。重启恢复已保存的步骤;退出登录会隐藏引导,但不清除进度。未登录且已配置模型凭证的安装会记录 API Key 完成状态,并应用标准过程、详细用量和开启开发者工具的配置。账号登录时丢弃失败的 API Key 完成写入,避免重试绕过必需的欢迎页。 + +欢迎页必须显式开始。额度页始终出现,包括余额为正的情况。仅在余额已就绪且没有正余额钱包时,才额外确认是否继续而不充值;查询失败或等待中绝不表示余额为零。从原生充值页面返回后保留额度页,由账号属主在后台刷新资料。充值期间关闭应用会保留额度步骤。 + +用途和过程选择会作为草稿持久化。仅选办公用途时采用简洁展示并完成。选择开发或两种用途时必须选择过程详情。任意可跳过步骤均采用标准过程、简洁用量和关闭开发者工具。完成时先应用 Chat 和共享开发者工具偏好,再保存完成标记,避免偏好写入被拒绝后静默完成引导。compact、standard 和 detailed 各自持久化为对应的 `ui-chat.transcriptView` 值。 + +既有[原生欢迎决策](../architecture/2026-09-08-desktop-welcome-window-material.zh.md)负责凭证入口、IPC 限制和窗口材质。Desktop 抑制自动 Web 凭证引导,保留显式 API Key 编辑。引导不创建工作区、示例任务或 Session 事件。静态 Figma 插图使用透明、调色板压缩的 3× PNG 资源;欢迎页图层合并并烘焙侧栏局部模糊;充值页前景窗口不透明度为 70%,仅烘焙其覆盖插图区域的模糊。账号包负责整窗覆盖层及其控件样式,共享基础组件保留通用行为。品牌标题通过 Web 入口加载附带许可的 Montserrat WOFF2 字体。保存选择时保留焦点,减少动态效果偏好会禁用动画,应用在退出覆盖层卸载前保持不可交互。确认弹窗模糊源页面,避免在半透明窗口内再次采样背景。 + +## 考虑过的替代方案 + +**云端或逐账号完成状态。** 当前版本要求设备本地进度,且没有账号完成 API。将登录状态用作完成标记,会混淆认证成功与设置完成。 + +**正余额时跳过额度页,或等待充值确认。** 引导独立于钱包状态说明计费。等待余额查询会使返回导航依赖网络,却无法确定是否完成支付。 + +**重复实现偏好控制。** 引导通过现有属主写入工作过程、用量与开发者工具配置。 + +## 后果 + +尚无引导完成标记的已有 API Key 安装,在升级后首次启动时也会应用这些默认值,覆盖之前的 Chat 展示、用量和开发者工具偏好;已经标记完成的安装保留原偏好。 + +同一安装的完成状态适用于切换后的账号,另一安装则运行自己的引导。偏好与完成状态按顺序写入,但不属于同一事务;完成标记写入失败后,重试可能再次应用同一偏好。已完成引导的安装不会在后续启动时重新应用偏好。[控制器测试](../../../../packages/client/ui-settings-account/tests/onboarding-state.client.spec.ts)与 [UI 测试](../../../../packages/client/ui-settings-account/tests/desktop-onboarding.client.spec.tsx)负责状态和交互覆盖;生产授权与支付行为仍需独立的集成验证。 diff --git a/.agents/notes/implemented/feature/2026-09-16-open-in-default-app-for-sidebar-files.i18n.yaml b/.agents/notes/implemented/feature/2026-09-16-open-in-default-app-for-sidebar-files.i18n.yaml index 7614cd0318..e3f4c53695 100644 --- a/.agents/notes/implemented/feature/2026-09-16-open-in-default-app-for-sidebar-files.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-16-open-in-default-app-for-sidebar-files.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-open-in-default-app-for-sidebar-files.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-16-open-in-default-app-for-sidebar-files.md -2026-09-16-open-in-default-app-for-sidebar-files.md: fa7506be77e8a62e5dfd97b59de6ebc4be510ae0 -2026-09-16-open-in-default-app-for-sidebar-files.zh.md: af124182dc1b38658ff55736277e499e963a6281 +/agent-note-open-sidebar-previewed-files-in-the-default-application: + en: 948e52b8edac6120 + zh: 0898da7049f15ca5 +/agent-note-open-sidebar-previewed-files-in-the-default-application/problem: + en: 6caae0cf235cdb1d + zh: e80f02c05d65598a +/agent-note-open-sidebar-previewed-files-in-the-default-application/decision: + en: ebd2273122d077db + zh: 8a596d0a49fb4e4e +/agent-note-open-sidebar-previewed-files-in-the-default-application/alternatives-considered: + en: f42e5763bf52e401 + zh: 4b2d954904505fc9 +/agent-note-open-sidebar-previewed-files-in-the-default-application/consequences: + en: 618062f56d294415 + zh: 5eb57d17854fa805 diff --git a/.agents/notes/implemented/feature/2026-09-16-performance-usage-preference.i18n.yaml b/.agents/notes/implemented/feature/2026-09-16-performance-usage-preference.i18n.yaml index 2da6cd2bfa..369511d545 100644 --- a/.agents/notes/implemented/feature/2026-09-16-performance-usage-preference.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-16-performance-usage-preference.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-performance-usage-preference.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-16-performance-usage-preference.md -2026-09-16-performance-usage-preference.md: 36ab30561fccc6c824ee8483f5a533a9178f11c5 -2026-09-16-performance-usage-preference.zh.md: ecfd19c41c861116d18829b355bf8c8df4ea929a +/agent-note-performance-and-usage-detail-preference: + en: 6179732355b5c019 + zh: 3a620cf25a5580c4 +/agent-note-performance-and-usage-detail-preference/problem: + en: 3b420f5fb2952b3e + zh: 6fa1ef1090e595ec +/agent-note-performance-and-usage-detail-preference/decision: + en: 953b5fcaed000c9e + zh: 2ff9d6ff0535d846 +/agent-note-performance-and-usage-detail-preference/alternatives-considered: + en: 7c676c0b192d03eb + zh: 2e994f30fc99c5d4 +/agent-note-performance-and-usage-detail-preference/consequences: + en: 2bc7b780efbae1e9 + zh: c7ecaffd29dfbbff diff --git a/.agents/notes/implemented/feature/2026-09-16-sandbox-same-mode.i18n.yaml b/.agents/notes/implemented/feature/2026-09-16-sandbox-same-mode.i18n.yaml index 426e7d8c80..dfc86aee32 100644 --- a/.agents/notes/implemented/feature/2026-09-16-sandbox-same-mode.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-16-sandbox-same-mode.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-sandbox-same-mode.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-16-sandbox-same-mode.md -2026-09-16-sandbox-same-mode.md: f1b7c3ae05103363f47f28fab1ae534a8a8b04c2 -2026-09-16-sandbox-same-mode.zh.md: 0bb04415230ec7a0f0f3fdd3c7f00bd7b76d9d9b +/agent-note-repeated-sandbox-modes-need-no-approval: + en: 85325770757063d8 + zh: 9c55052551299ddf +/agent-note-repeated-sandbox-modes-need-no-approval/problem: + en: 0d5832fd63b9cd7b + zh: f07b20a91b92de25 +/agent-note-repeated-sandbox-modes-need-no-approval/decision: + en: b102948c4acbdd96 + zh: 7220f043716d571c +/agent-note-repeated-sandbox-modes-need-no-approval/alternatives-considered: + en: fb337915525ed95c + zh: d0584f998f0a3b8f +/agent-note-repeated-sandbox-modes-need-no-approval/consequences: + en: bde9f3b22f5159c2 + zh: 105c24546f0943bb diff --git a/.agents/notes/implemented/feature/2026-09-16-shared-subagent-settings-card.i18n.yaml b/.agents/notes/implemented/feature/2026-09-16-shared-subagent-settings-card.i18n.yaml index e98c3c4e39..eab4632401 100644 --- a/.agents/notes/implemented/feature/2026-09-16-shared-subagent-settings-card.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-16-shared-subagent-settings-card.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-shared-subagent-settings-card.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-16-shared-subagent-settings-card.md -2026-09-16-shared-subagent-settings-card.md: d9457b3e9b9786d77dcced4cac8ca1086914699a -2026-09-16-shared-subagent-settings-card.zh.md: ccde0c97df24239b4e5113fecbaec6e85f19b145 +/agent-note-shared-subagent-settings-card: + en: 63fcf9d6ab8a601d + zh: 0f824893329679f2 +/agent-note-shared-subagent-settings-card/problem: + en: a63f47c29f3a6305 + zh: 9f2150e9a9c5bc4b +/agent-note-shared-subagent-settings-card/decision: + en: 2c4056b23e053d3a + zh: d46c391f9b5be135 +/agent-note-shared-subagent-settings-card/alternatives-considered: + en: 8674979fbd8197f1 + zh: 6c2169803839f70b +/agent-note-shared-subagent-settings-card/consequences: + en: 4a3671620dfa64b6 + zh: eb6eb20e864f77a1 +/agent-note-shared-subagent-settings-card/verification: + en: 8d9956c13fb6658b + zh: 3d95564e51595bca diff --git a/.agents/notes/implemented/feature/2026-09-16-sidebar-browser.i18n.yaml b/.agents/notes/implemented/feature/2026-09-16-sidebar-browser.i18n.yaml index fac9746b09..70686c479d 100644 --- a/.agents/notes/implemented/feature/2026-09-16-sidebar-browser.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-16-sidebar-browser.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-sidebar-browser.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-16-sidebar-browser.md -2026-09-16-sidebar-browser.md: eff143cc042da7c6455152f684ec83dfa654a1ec -2026-09-16-sidebar-browser.zh.md: a037c2fb54be745a3a85f43561c0bd587873c008 +/agent-note-sandboxed-sidebar-browser: + en: eae586a5966353a5 + zh: ca3a7283e3fae594 +/agent-note-sandboxed-sidebar-browser/problem: + en: 5236141e90e42b81 + zh: 1af6306b20797603 +/agent-note-sandboxed-sidebar-browser/decision: + en: 9e89a0fe77cd8b9f + zh: 7aba8507320cf504 +/agent-note-sandboxed-sidebar-browser/web-navigation-states: + en: 6aec277c70600c7d + zh: e2b53f01072b2423 +/agent-note-sandboxed-sidebar-browser/electron-carrier: + en: dd20fa5656fc5779 + zh: 94b5908de0695755 +/agent-note-sandboxed-sidebar-browser/alternatives-considered: + en: 73919eb8d5618982 + zh: 18d2f5becae72790 +/agent-note-sandboxed-sidebar-browser/verification: + en: 91563b2be0b76a37 + zh: 24e55764bc85b8ae +/agent-note-sandboxed-sidebar-browser/consequences: + en: d9844d90ebdeb553 + zh: 7f05c8e911bd73c4 diff --git a/.agents/notes/implemented/feature/2026-09-16-unified-model-input-controls.i18n.yaml b/.agents/notes/implemented/feature/2026-09-16-unified-model-input-controls.i18n.yaml index e74186da34..4a74dfb669 100644 --- a/.agents/notes/implemented/feature/2026-09-16-unified-model-input-controls.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-16-unified-model-input-controls.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-unified-model-input-controls.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-16-unified-model-input-controls.md -2026-09-16-unified-model-input-controls.md: 73913880924577caf86b30990baef98efdbe751e -2026-09-16-unified-model-input-controls.zh.md: 691ca5229c017919e708bf7df92285dee25ef6b4 +/agent-note-unified-model-input-controls: + en: a22f2dd1b73eb314 + zh: 1f43526fa6af593a +/agent-note-unified-model-input-controls/problem: + en: e28035e73033057d + zh: 262cf7551cdb783a +/agent-note-unified-model-input-controls/decision: + en: 6b4872a76d480c8a + zh: f833a14a48d2e9d7 +/agent-note-unified-model-input-controls/alternatives-considered: + en: 83f8ffa39259a9f4 + zh: e158cb5868c82d74 +/agent-note-unified-model-input-controls/consequences: + en: 768bb77e3a4d72be + zh: 81080b075b0cc26c diff --git a/.agents/notes/implemented/feature/2026-09-16-windows-desktop-titlebar.i18n.yaml b/.agents/notes/implemented/feature/2026-09-16-windows-desktop-titlebar.i18n.yaml index d85ac2b2b2..6c3b3ddfe0 100644 --- a/.agents/notes/implemented/feature/2026-09-16-windows-desktop-titlebar.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-16-windows-desktop-titlebar.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-windows-desktop-titlebar.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-16-windows-desktop-titlebar.md -2026-09-16-windows-desktop-titlebar.md: 17fd2aac308cff0b4357a0c39c3fe757cfc60f5b -2026-09-16-windows-desktop-titlebar.zh.md: 05903d86960942204d7b18d4155266c144effc1a +/agent-note-windows-desktop-caption-and-application-menus: + en: 4220f3c0d8058ca7 + zh: 4751c2cffb9b8e2a +/agent-note-windows-desktop-caption-and-application-menus/problem: + en: 9a3d1b6d02197c6b + zh: 5eba9f9bf6928430 +/agent-note-windows-desktop-caption-and-application-menus/decision: + en: be4b50d09caa5d46 + zh: 20b0572be5941b0c +/agent-note-windows-desktop-caption-and-application-menus/alternatives-considered: + en: db7703a7a37ac5da + zh: 704a2a289b8f7cb0 +/agent-note-windows-desktop-caption-and-application-menus/consequences: + en: a52bfa0c00b4e26d + zh: c479cc99fd1bff03 +/agent-note-windows-desktop-caption-and-application-menus/testing: + en: d72a6473a7d385cf + zh: ededb7391908db38 diff --git a/.agents/notes/implemented/feature/2026-09-17-compact-translucent-menu-surfaces.i18n.yaml b/.agents/notes/implemented/feature/2026-09-17-compact-translucent-menu-surfaces.i18n.yaml index cf44de1cb6..101417360a 100644 --- a/.agents/notes/implemented/feature/2026-09-17-compact-translucent-menu-surfaces.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-17-compact-translucent-menu-surfaces.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-compact-translucent-menu-surfaces.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-17-compact-translucent-menu-surfaces.md -2026-09-17-compact-translucent-menu-surfaces.md: 08fcb2d851e4c75ce9069fc797e8dbcb070acc5b -2026-09-17-compact-translucent-menu-surfaces.zh.md: 8e13634995d46b7414f17bbb51443df85cb3ac3c +/agent-note-compact-translucent-menu-surfaces: + en: 629cdf857a84d1f3 + zh: 676a34bac03903be +/agent-note-compact-translucent-menu-surfaces/problem: + en: f1ff5b408b409003 + zh: 1f548352bc075cc4 +/agent-note-compact-translucent-menu-surfaces/decision: + en: 30cbe72206e81f96 + zh: 21cb393871fe6420 +/agent-note-compact-translucent-menu-surfaces/alternatives-considered: + en: f06228674ee82029 + zh: 385603bebcd17d5f +/agent-note-compact-translucent-menu-surfaces/consequences: + en: e76746c0b95549df + zh: 9ff34644703d565c diff --git a/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.i18n.yaml b/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.i18n.yaml index 6485deaade..68731414ce 100644 --- a/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-developer-tools-settings.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-17-developer-tools-settings.md -2026-09-17-developer-tools-settings.md: 5ae8861efa701042e0730310ddb23f6f559d14d7 -2026-09-17-developer-tools-settings.zh.md: e7a9d3c28d53ba9fe14c970bd48f2a6031248e58 +/agent-note-shared-developer-tool-settings: + en: 353fa09368362d0f + zh: b36c06c8b49833b1 +/agent-note-shared-developer-tool-settings/problem: + en: e22ee243b1503319 + zh: b53c1a932d547f55 +/agent-note-shared-developer-tool-settings/decision: + en: 62f71b49af7b9971 + zh: f0f12da4cb0c7fc0 +/agent-note-shared-developer-tool-settings/alternatives-considered: + en: df1b80e5b8d2a178 + zh: 0136d16fc44d57bf +/agent-note-shared-developer-tool-settings/consequences: + en: c1e05aebc88fc12c + zh: 0ace5bced7b32437 diff --git a/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.md b/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.md index 5ae8861efa..4d9f0fea89 100644 --- a/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.md +++ b/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.md @@ -12,9 +12,9 @@ Diagnostic views, preset selection and changed-file summaries add complexity to The settings-owned `ctx.configForms.developerTools` preference uses a shared entry form and exposes one accepted `ui-settings.enabled` preference. The initial default-off choice reduces routine-task complexity; [Developer tools default on after preference resolution](2026-09-20-developer-tools-default-on.md) supersedes that default and owns startup enablement. General Settings offers the same switch on Web and desktop. The existing settings transport owns validation, ordered writes, persistence and recovery; loopback Web and desktop follow Host acceptance. Remote Web owns one browser-local observable shared by all consumers until reload, with no Host writes. -Off hides the Trajectory View, hides tool Inspect actions when no visible View declares tool-call inspection, hides the conversation View tab bar while fewer than two Views are available, hides the new-session preset chip and the settings row that allows switching Agent modes, and omits the changed-files card and its summary read. Views registered by other plugins stay available. Turning it off while Trajectory is active activates Chat. The preset composition, saved default, Session events and explicit delivery cards remain unchanged. This preference is presentation policy, not Host authorization. +Off hides the Trajectory View, hides tool Inspect actions when no visible View declares tool-call inspection, hides the conversation View tab bar while fewer than two Views are available, hides the new-session preset chip and refuses the Agent-preset cards' selection, and omits the changed-files card and its summary read. Views registered by other plugins stay available. Turning it off while Trajectory is active activates Chat. The preset composition, saved default, Session events and explicit delivery cards remain unchanged. This preference is presentation policy, not Host authorization. -Plugin assembly translates the shared preference into component-specific capabilities (`showCodeDiff`, `showPresetPicker`, and `interactivePreview`). Conversation supplies the inspection callback using the visible target's `toolCallFocus`; Chat does not name the target. The builtin HTML renderer uses DOMPurify for complete-document sanitization and parser-mutation defenses. Off preserves root styling, removes active documents, resource hints, SVG animation and all `href` attributes, and mounts an iframe with no sandbox permissions and a CSP denying scripts and external resources. It reads no related files. On retains the opaque scripted Blob renderer and its bounded related-file reads. Switching modes replaces the browsing context and disposes pending reads. The [document-preview decision](../architecture/2026-09-08-document-preview-operations.md) and [filesystem-read authority](../architecture/2026-09-09-workspace-file-read-authority.md) remain authoritative for advanced rendering and Host read access. +Plugin assembly translates the shared preference into component-specific capabilities (`showCodeDiff`, the Agent-preset surfaces' `developerTools`, and `interactivePreview`). Conversation supplies the inspection callback using the visible target's `toolCallFocus`; Chat does not name the target. The builtin HTML renderer uses DOMPurify for complete-document sanitization and parser-mutation defenses. Off preserves root styling, removes active documents, resource hints, SVG animation and all `href` attributes, and mounts an iframe with no sandbox permissions and a CSP denying scripts and external resources. It reads no related files. On retains the opaque scripted Blob renderer and its bounded related-file reads. Switching modes replaces the browsing context and disposes pending reads. The [document-preview decision](../architecture/2026-09-08-document-preview-operations.md) and [filesystem-read authority](../architecture/2026-09-09-workspace-file-read-authority.md) remain authoritative for advanced rendering and Host read access. ## Alternatives considered diff --git a/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.zh.md b/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.zh.md index e7a9d3c28d..ac5829ed95 100644 --- a/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.zh.md +++ b/.agents/notes/implemented/feature/2026-09-17-developer-tools-settings.zh.md @@ -12,9 +12,9 @@ Status: implemented 设置域内的 `ctx.configForms.developerTools` 偏好对象使用共享条目表单,提供一个已接受的 `ui-settings.enabled` 偏好。最初默认关闭的选择用于降低日常任务的复杂度;[偏好解析后默认开启开发者工具](2026-09-20-developer-tools-default-on.zh.md)取代该默认值并负责启动时的启用策略。Web 和桌面端的通用设置提供同一个开关。现有设置传输负责验证、有序写入、持久化和恢复;回环 Web 和桌面端跟随 Host 接受的状态。远程 Web 持有一个所有消费者共享的浏览器本地可观察值,刷新后重置,不发送 Host 写入。 -关闭时隐藏 Trajectory View,在没有可见 View 声明工具调用检查能力时隐藏 Inspect 操作,可见 View 少于两个时隐藏会话 View 标签栏,隐藏新会话预设入口和「允许切换agent模式」设置行,并省略改动文件卡片及其摘要读取。其他插件注册的 View 保持可用。在 Trajectory 中关闭开关会激活 Chat。预设组合、保存的默认值、Session 事件和显式交付卡片保持不变。此偏好是展示策略,不是 Host 授权。 +关闭时隐藏 Trajectory View,在没有可见 View 声明工具调用检查能力时隐藏 Inspect 操作,可见 View 少于两个时隐藏会话 View 标签栏,隐藏新会话预设入口并拒绝 Agent 预设卡片的选择操作,并省略改动文件卡片及其摘要读取。其他插件注册的 View 保持可用。在 Trajectory 中关闭开关会激活 Chat。预设组合、保存的默认值、Session 事件和显式交付卡片保持不变。此偏好是展示策略,不是 Host 授权。 -插件组装层将共享偏好转换为组件自身的能力(`showCodeDiff`、`showPresetPicker` 和 `interactivePreview`)。Conversation 根据可见目标的 `toolCallFocus` 提供检查回调;Chat 不再指定目标名称。内置 HTML 渲染器使用 DOMPurify 清理完整文档并防护解析变异。关闭时保留根节点样式,移除主动文档、资源提示、SVG 动画及所有 `href` 属性,再放入不授予沙箱权限的 iframe,并通过 CSP 禁止脚本和外部资源。不读取关联文件。开启时保留不透明源的脚本 Blob 渲染器及其有界关联文件读取。切换模式会替换浏览上下文并清理待处理读取。[文档预览决策](../architecture/2026-09-08-document-preview-operations.zh.md)和[文件系统读取权限](../architecture/2026-09-09-workspace-file-read-authority.zh.md)继续定义高级渲染与 Host 读取访问。 +插件组装层将共享偏好转换为组件自身的能力(`showCodeDiff`、Agent 预设各界面读取的 `developerTools`,以及 `interactivePreview`)。Conversation 根据可见目标的 `toolCallFocus` 提供检查回调;Chat 不再指定目标名称。内置 HTML 渲染器使用 DOMPurify 清理完整文档并防护解析变异。关闭时保留根节点样式,移除主动文档、资源提示、SVG 动画及所有 `href` 属性,再放入不授予沙箱权限的 iframe,并通过 CSP 禁止脚本和外部资源。不读取关联文件。开启时保留不透明源的脚本 Blob 渲染器及其有界关联文件读取。切换模式会替换浏览上下文并清理待处理读取。[文档预览决策](../architecture/2026-09-08-document-preview-operations.zh.md)和[文件系统读取权限](../architecture/2026-09-09-workspace-file-read-authority.zh.md)继续定义高级渲染与 Host 读取访问。 ## Alternatives considered diff --git a/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.i18n.yaml b/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.i18n.yaml index da8a49ddb6..bc17196684 100644 --- a/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-persistent-plan-cards.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-17-persistent-plan-cards.md -2026-09-17-persistent-plan-cards.md: 096c89c7ed3e52293787a2724b0c7231ae3740ae -2026-09-17-persistent-plan-cards.zh.md: 95cce3fed84dd802195b87f593654b7d511933cb +/agent-note-persistent-plan-cards-and-sidebar-reading: + en: e84bc0e16f40cafb + zh: b11a06e7800e3f9a +/agent-note-persistent-plan-cards-and-sidebar-reading/problem: + en: 273400b515da3a1d + zh: 13b508617f08c6d0 +/agent-note-persistent-plan-cards-and-sidebar-reading/decision: + en: 243abb4fe9944c97 + zh: 6e66ddceb9c89aee +/agent-note-persistent-plan-cards-and-sidebar-reading/alternatives-considered: + en: f1f8dbe0f29b89cd + zh: 4fc73f1f4b4bcbae +/agent-note-persistent-plan-cards-and-sidebar-reading/consequences: + en: 4d1740b16711041d + zh: 412ac19a3705045e diff --git a/.agents/notes/implemented/feature/2026-09-17-sidebar-file-and-directory-auto-refresh.i18n.yaml b/.agents/notes/implemented/feature/2026-09-17-sidebar-file-and-directory-auto-refresh.i18n.yaml index bee0b26a39..f8fc347f32 100644 --- a/.agents/notes/implemented/feature/2026-09-17-sidebar-file-and-directory-auto-refresh.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-17-sidebar-file-and-directory-auto-refresh.i18n.yaml @@ -1,6 +1,73 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-sidebar-file-and-directory-auto-refresh.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-17-sidebar-file-and-directory-auto-refresh.md -2026-09-17-sidebar-file-and-directory-auto-refresh.md: f509a8cf2642d3ca816d40e9e9817d3c962c79a6 -2026-09-17-sidebar-file-and-directory-auto-refresh.zh.md: ff7a950aa86c663d4f5d2fb8e20d64bb2b077f6b +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees: + en: 8dfe4436b064776d + zh: acb3f1e2fae231f4 +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/problem: + en: f7e7751fe98be91e + zh: e1d6c4f042c7d75d +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/decision: + en: b51a6972761816ef + zh: 6f50b2a09b8d6abc +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/implementation-and-responsibilities: + en: 79480338424c1829 + zh: c32ff30ccf3d9b87 +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/implementation-and-responsibilities/fs-and-host: + en: ca63fb903b447c2d + zh: 3014adbdb0a890ee +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/implementation-and-responsibilities/client-and-sidebar: + en: 5cb8326d8a5b0407 + zh: a31173f990276856 +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/watch-requests-and-notifications: + en: 025ba83ae78824df + zh: 264d74d2bdfe3d27 +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/watch-requests-and-notifications/one-stream-per-explicit-target: + en: 75d1c4e35d0f4d74 + zh: a6b11f70a64d6922 +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/watch-requests-and-notifications/os-watching-and-access-scope: + en: 48af866f541caf04 + zh: c3df4edf7f7ddb4a +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/complete-file-preview-data-flow: + en: f8468653186b2a60 + zh: 0c624d957c9ce332 +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/html-resourcegroup: + en: 0f2419d75906ca0a + zh: 3ff0dbb7382ba02c +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/automatic-refresh-controls: + en: a00c8265a48e910d + zh: e1aa7c639a4e2c10 +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/complete-files-panel-data-flow: + en: d688642e5f272d48 + zh: 96088fbc0471aeae +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/directory-node-tree-and-lifecycle: + en: 2ea8615be8d5229b + zh: 0c73fa4ebb06445e +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/user-flows: + en: eb4005a334103895 + zh: e2c207faffa64e57 +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/user-flows/edit-a-previewed-file: + en: 2b7d90550ad49eff + zh: a8136d5d00390635 +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/user-flows/browse-changing-directories: + en: d375f21c1ae106ef + zh: 5a39f248cc98f20a +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/user-flows/deletion-renaming-and-failure: + en: 4f343f7a6c4d3ba4 + zh: a4390843a20f8dde +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/readiness-races-and-refresh-coalescing: + en: caadd187479e9074 + zh: 3deedd8093f60703 +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/alternatives-considered: + en: 8a8c19229647c760 + zh: 2de283fc2c815e65 +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/verification: + en: e8143b93c93b4dc2 + zh: a90105eb5823a2ff +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/consequences: + en: 8faa05de777dea21 + zh: 2f0b1ff65bdba75b +/agent-note-on-demand-watching-and-automatic-refresh-for-sidebar-previews-and-file-trees/relationship-to-existing-agent-notes: + en: 8ddc059f64cb3b1c + zh: f6d6836458ef9522 diff --git a/.agents/notes/implemented/feature/2026-09-17-state-dot-visual-language.i18n.yaml b/.agents/notes/implemented/feature/2026-09-17-state-dot-visual-language.i18n.yaml index d86602a99e..711a40b14b 100644 --- a/.agents/notes/implemented/feature/2026-09-17-state-dot-visual-language.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-17-state-dot-visual-language.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-state-dot-visual-language.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-17-state-dot-visual-language.md -2026-09-17-state-dot-visual-language.md: 751abbaa33919721c7e71738ad9b6bed744fcad7 -2026-09-17-state-dot-visual-language.zh.md: 9746ec9af79e15fc41ea8e6601cc52c1cfafba02 +/agent-note-statedot-solid-marks-and-loading-spinner: + en: 74ca1dda90213e27 + zh: 14851ca8d3d4617d +/agent-note-statedot-solid-marks-and-loading-spinner/problem: + en: 4739e4079e950c72 + zh: 4633fc299da13565 +/agent-note-statedot-solid-marks-and-loading-spinner/decision: + en: 98dd1c4ac95913b9 + zh: c3c53bae1ffc430a +/agent-note-statedot-solid-marks-and-loading-spinner/alternatives-considered: + en: 962827b807ebf026 + zh: dfe83e98956dd2cd +/agent-note-statedot-solid-marks-and-loading-spinner/testing: + en: 9d5f7bfb69b7bded + zh: 281db4c0e7ddd8c2 +/agent-note-statedot-solid-marks-and-loading-spinner/consequences: + en: 17a7a8d9c3923666 + zh: 84d941223b079f2b diff --git a/.agents/notes/implemented/feature/2026-09-18-account-quota-top-up.i18n.yaml b/.agents/notes/implemented/feature/2026-09-18-account-quota-top-up.i18n.yaml new file mode 100644 index 0000000000..daa3d1e95a --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-18-account-quota-top-up.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-18-account-quota-top-up.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-18-account-quota-top-up.md +/agent-note-account-quota-top-up-action: + en: c9f0d30bc28f815c + zh: 472505b18ee2e669 +/agent-note-account-quota-top-up-action/problem: + en: 4c0caf28d02faec2 + zh: a6cc3e175a2f9f4a +/agent-note-account-quota-top-up-action/decision: + en: d8046306e6488932 + zh: a0d29f3949c96955 +/agent-note-account-quota-top-up-action/alternatives-considered: + en: ec6731c63d9c42ee + zh: 535b67062ce0269b +/agent-note-account-quota-top-up-action/consequences: + en: 72febb3835a50018 + zh: 0125b875f35b829e diff --git a/.agents/notes/implemented/feature/2026-09-18-account-quota-top-up.md b/.agents/notes/implemented/feature/2026-09-18-account-quota-top-up.md new file mode 100644 index 0000000000..f48b12be29 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-18-account-quota-top-up.md @@ -0,0 +1,35 @@ +# Agent Note: Account quota top-up action + +Status: implemented + +English | [中文](2026-09-18-account-quota-top-up.zh.md) + +## Problem + +A provider quota failure can mean an exhausted first-party account balance, an API-key account problem, or a custom gateway response. All require a useful explanation, but only the first case can be repaired by opening the signed-in user's embedded DeepSeek recharge page. Inferring that case from provider prose or current UI configuration would make historical failures unstable and could expose an irrelevant billing action. + +## Decision + +The `llm-deepseek-account` plugin classifies quota failures for its own route. The credential callback it hands the shared Messages transport releases the account token only for the configured inference origin, and the plugin rewrites the provider-neutral `QUOTA` failure to `ACCOUNT_QUOTA` for both HTTP 402 responses and in-band SSE errors. The API-key plugin registers `deepseek-official` independently and keeps `QUOTA`; neither route borrows the other's credentials, and a separately configured API key does not affect account-route quota actions. + +A quota failure reaches the transcript and the frame-wide notice as two separate facts. The durable terminal-error record keeps the request-time code and always renders the same provider-neutral quota copy, so the Chat transcript, history paging, and the Session log do not depend on current credentials. A newly appended `QUOTA` or `ACCOUNT_QUOTA` failure in a Session this Client has bound and materialized also publishes one frame-wide notice; the newest notice replaces the previous one, and history replacement, pagination, and Sessions the Client never opened publish none. + +Chat owns the notice host and registers it into the frame-wide `shell.overlay` slot, so a notice outlives the Chat panel that reported it. The host offers the one live notice, with `code`, `message`, `dismiss`, and `keepOpen`, to its `shell.quota-notice` chain child, and renders a generic warning Toast when no entry claims the code. The account package claims `ACCOUNT_QUOTA` only, showing a Cancel/Top up Modal; without the shared host entry, or with a snapshot that reports no stored credential or a failed account stream, the entry renders the neutral Toast itself, and with that host entry it waits for the first account snapshot instead of rendering a Toast that its own timer could discard. The plugin keeps one shared `PlatformPages` request channel and one `shell.overlay` host entry for the Desktop host's single native view: the Account settings page, the quota notice, and the Desktop onboarding recharge page request a page there instead of mounting their own container, the latest request retires the previous owner before the newer page shows, the shared host only closes the page it is given, and each owner decides what its own return re-reads: returning from a top-up page on the Account settings page or the quota notice re-reads profile, balance, and unnotified bonus, while the onboarding recharge return re-reads profile and balance only. Superseding a page, releasing a request, plugin unload, and leaving usage read nothing, and a release arriving after a newer request or a dismissal clears nothing. Back restores focus before any deferred Modal takes it. While a page requested through that shared channel is showing, the native view covers the document, so the entry renders neither Modal nor Toast. A quota failure that arrives while a Settings-opened page is already showing is not retained: it stays subject to newest-notice replacement, and the Modal appears after the viewer returns while that notice is still current. That Modal reports the failure of the original request rather than the account's current balance: the top-up re-read is a separate read, and returning neither proves a successful payment nor dismisses the notice by itself. The notice's own Top up is the retained case: it retains the notice with `keepOpen` and requests the `top-up` page; `keepOpen` returns an identity-safe release, and the entry releases both the hold and its page request when it unmounts, so a claim cannot outlive the entry that took it. Opening the top-up page therefore keeps the notice and the page mounted through later quota failures, which are dropped rather than queued while their persistent failure rows still render. Dismissal or sign-out releases the hold and the page request, so the next live quota event publishes again. Chat's subscription to a Session binding's live events ends with that binding or with the plugin, whichever goes first. + +Credentials and billing URLs never enter Chat props or the Session log. Dismissing the notice does not retry the request; signing out closes an open account Modal or embedded page. + +## Alternatives considered + +**Derive eligibility entirely in the renderer.** Current endpoint, key, and login state may differ from the facts of a historical failed request. It would also couple Chat to credentials and provider configuration rather than keeping only a stable code at the presentation boundary. + +**Parse the provider error message in the UI.** Provider prose is not a stable contract, cannot distinguish API-key and account-token billing, and would duplicate adapter error classification. + +**Offer recharge for every quota failure.** This would send API-key and custom-gateway users to unrelated first-party billing. The generic notice remains useful without claiming a repair path. + +**Infer billing from global credentials.** A configured API key may belong to another account and may be unused by the failed request. The explicit provider route owns credential selection and quota classification. + +## Consequences + +The Session log distinguishes account balance failure from generic quota exhaustion while the transcript renders both with the same neutral copy. One notice serves the whole app, so it stays visible after the reporting Chat panel closes, and a newer notice supersedes an older one instead of stacking. Because the account package claims the notice through a chain child, Web and signed-out users see the neutral Toast and no billing affordance, and the account package never imports Chat. A notice retained by Top up keeps that entry's page mounted through later quota failures at the cost of dropping those notices; the persistent failure rows remain their record. One shared request channel serves both the Account settings page and the notice, so a newer request replaces the visible page while identity-checked releases keep a superseded owner from closing it. + +Provider tests cover routing with simultaneous credentials, HTTP 402 classification, and in-band SSE errors; presentation tests cover append-only publication, replacement, dismissal, Toast fallback, and embedded top-up navigation. diff --git a/.agents/notes/implemented/feature/2026-09-18-account-quota-top-up.zh.md b/.agents/notes/implemented/feature/2026-09-18-account-quota-top-up.zh.md new file mode 100644 index 0000000000..965e246ecb --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-18-account-quota-top-up.zh.md @@ -0,0 +1,35 @@ +# Agent Note: 账号欠费充值操作 + +Status: implemented + +[English](2026-09-18-account-quota-top-up.md) | 中文 + +## Problem + +提供方的额度错误可能表示第一方账号余额耗尽、API Key 账号问题,或自定义网关响应。所有情况都需要清晰提示,但只有第一种情况适合打开已登录用户的内嵌 DeepSeek 充值页。若根据提供方文案或当前 UI 配置推断,会导致历史错误随当前状态变化,并可能展示无关的充值操作。 + +## Decision + +`llm-deepseek-account` 插件为本路由分类额度错误:它交给共享 Messages 传输的凭据回调只在配置的推理 origin 上释放账号 token,并把提供方中立的 `QUOTA` 错误改写为 `ACCOUNT_QUOTA`,同时覆盖 HTTP 402 响应与流内 SSE 错误。API Key 插件独立注册 `deepseek-official` 并保留 `QUOTA`;两条路由不会借用对方的凭据,单独配置的 API Key 也不影响账号路由的欠费操作。 + +额度错误分别到达消息记录和全应用提示这两条路径。持久化的终止错误记录保留请求时的错误码,并始终渲染同一段提供方中立的欠费文案,因此 Chat 消息记录、历史分页和 Session 日志都不依赖当前凭据。本 Client 已绑定并已物化的 Session 中新追加的 `QUOTA` 或 `ACCOUNT_QUOTA` 错误还会发布一条全应用提示;最新提示替换上一条,历史替换、分页以及从未打开的 Session 都不发布提示。 + +Chat 拥有提示宿主,并将其注册到全应用的 `shell.overlay` slot,因此提示的生命周期长于报告它的 Chat 面板。宿主把这条实时提示连同 `code`、`message`、`dismiss`、`keepOpen` 交给 `shell.quota-notice` chain 子 slot,没有 entry 认领该错误码时渲染通用警告 Toast。账号包只认领 `ACCOUNT_QUOTA`,显示带取消和去充值按钮的 Modal;缺少共享宿主条目,或快照报告未存储凭证、账号流失败且无快照时,由该条目自行渲染中立文案 Toast,而存在该宿主条目时它会等待首个账号快照,而不是渲染一个可能被自身计时器丢弃的 Toast。插件为 Desktop 宿主唯一的原生视图保留一个共享 `PlatformPages` 请求通道和一个 `shell.overlay` 宿主条目:Account 设置页、欠费提示与 Desktop 引导充值页都通过它申请页面,而不再各自挂载容器;最新请求会在新页面显示前退掉上一个持有者,而在更新请求或关闭之后到达的释放不会清除任何内容。共享宿主只关闭它接到的页面,每个持有者自行决定其返回时重读什么:Account 设置页或欠费提示的充值返回会重读资料、余额与未通知赠金,而引导充值返回只重读资料与余额。替换页面、释放请求、插件卸载与从用量页返回均不读取。返回时先恢复焦点,再由任何被延后的 Modal 接管。只要通过该共享请求通道请求的页面正在显示,该原生视图就会盖住本页,因此该条目既不渲染 Modal 也不渲染 Toast。在 Account 设置页已打开页面的情况下新到达的欠费不会被保持:它仍受最新提示替换规则约束,返回后若该提示仍是最新一条就显示 Modal。该 Modal 报告的是原始请求的失败而非账号当前余额:返回时的重读是一次独立读取,返回本身既不证明支付成功,也不会自动撤下该提示。提示自身的去充值属于被保持的情形:它用 `keepOpen` 保持住提示,并申请 `top-up` 页面;`keepOpen` 返回身份安全的释放函数,且该条目在卸载时同时释放保持与页面请求,因此声明不会比取得它的条目活得更久。打开充值页因此会让该提示与其页面在后续欠费期间保持挂载,这些欠费被丢弃而不排队,其持久化失败行仍然渲染。关闭或退出登录会释放保持与页面请求,使下一条实时欠费重新发布。Chat 对某个 Session binding 实时事件的订阅在 binding 或插件先结束的一侧终止。 + +凭据和计费 URL 不会进入 Chat props 或 Session 日志。关闭提示不会重试请求;退出登录会关闭已打开的账号 Modal 或内嵌页面。 + +## Alternatives considered + +**完全在 renderer 中推导资格。** 当前端点、密钥和登录状态可能已经不同于历史失败请求的事实;这也会让 Chat 依赖凭据和提供方配置,而不是在展示边界只接收稳定错误码。 + +**在 UI 中解析提供方错误文案。** 提供方文案不是稳定契约,无法区分 API Key 和账号 token 的计费,同时会重复 adapter 的错误分类。 + +**为所有额度错误提供充值。** 这会把 API Key 和自定义网关用户带到无关的第一方计费页面。普通提示已经足够,不应虚构修复路径。 + +**根据全局凭据推断计费。** 已配置的 API Key 可能属于其他账号,也可能未被失败请求使用。明确的 provider 路由负责凭据选择和欠费分类。 + +## Consequences + +Session 日志区分账号余额失败与普通额度耗尽,消息记录对两者渲染同一段中立文案。一条提示服务整个应用,因此在报告它的 Chat 面板关闭后仍然可见,且新提示取代旧提示而不是叠加。由于账号包通过 chain 子 slot 认领提示,Web 与未登录用户只看到中立 Toast,没有计费入口,账号包也无须导入 Chat。被去充值保持住的提示会让该条目的页面在后续欠费期间继续挂载,代价是丢弃这些提示;持久化失败行仍是它们唯一的记录。一个共享请求通道同时服务 Account 设置页与提示,因此更新的请求会替换可见页面,而身份校验过的释放使被取代的持有者无法关闭它。 + +提供方测试覆盖双凭据并存时的路由、HTTP 402 分类和流内 SSE 错误;展示测试覆盖仅追加发布、替换、关闭、Toast 回退和内嵌充值页跳转。 diff --git a/.agents/notes/implemented/feature/2026-09-18-session-pin-and-sidebar-archive.i18n.yaml b/.agents/notes/implemented/feature/2026-09-18-session-pin-and-sidebar-archive.i18n.yaml index 39b7b53e98..a74636286a 100644 --- a/.agents/notes/implemented/feature/2026-09-18-session-pin-and-sidebar-archive.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-18-session-pin-and-sidebar-archive.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-18-session-pin-and-sidebar-archive.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-18-session-pin-and-sidebar-archive.md -2026-09-18-session-pin-and-sidebar-archive.md: ac580979b9419e3f00af860e2dce2655fec51908 -2026-09-18-session-pin-and-sidebar-archive.zh.md: d4719fe75bb8aa1e2ebe9b89d4d80182a7597447 +/agent-note-session-pinning-and-the-sidebar-archived-filter: + en: f21362fdb86cdb6c + zh: b14889b8b7a717a3 +/agent-note-session-pinning-and-the-sidebar-archived-filter/problem: + en: 8a33826809d1dd8f + zh: b37aa33a8e2ed8d8 +/agent-note-session-pinning-and-the-sidebar-archived-filter/decision: + en: c483432158826f12 + zh: 2fc1e96f276420a7 +/agent-note-session-pinning-and-the-sidebar-archived-filter/decision/complete-session-order: + en: 321a47984818bbb9 + zh: a55d22a44e7b7155 +/agent-note-session-pinning-and-the-sidebar-archived-filter/decision/archive-restoration: + en: 0e16cb25af1f2bb1 + zh: 026fdf7bfa1c104c +/agent-note-session-pinning-and-the-sidebar-archived-filter/decision/archived-visibility-and-row-motion: + en: 83dd778a865f2cf5 + zh: 7636166749f63633 +/agent-note-session-pinning-and-the-sidebar-archived-filter/decision/persistence: + en: 4bcb0398b47334aa + zh: fa386724afa99a77 +/agent-note-session-pinning-and-the-sidebar-archived-filter/alternatives-considered: + en: 3bf6fc0c22b17377 + zh: 0fc64131ee8be859 +/agent-note-session-pinning-and-the-sidebar-archived-filter/consequences: + en: a487faf9af215726 + zh: a92cae8b15fba541 +/agent-note-session-pinning-and-the-sidebar-archived-filter/related: + en: 6c67f3a071f80c15 + zh: e0455cddc9c4bea9 diff --git a/.agents/notes/implemented/feature/2026-09-19-windows-acl-mandatory-integrity-confinement.i18n.yaml b/.agents/notes/implemented/feature/2026-09-19-windows-acl-mandatory-integrity-confinement.i18n.yaml index 4ab68b411e..5058cd26a1 100644 --- a/.agents/notes/implemented/feature/2026-09-19-windows-acl-mandatory-integrity-confinement.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-19-windows-acl-mandatory-integrity-confinement.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-windows-acl-mandatory-integrity-confinement.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-19-windows-acl-mandatory-integrity-confinement.md -2026-09-19-windows-acl-mandatory-integrity-confinement.md: f53765f34a7d6d9bcae8b06839c30731a054165d -2026-09-19-windows-acl-mandatory-integrity-confinement.zh.md: a963fd7f549ca2e995f74893c95f1620034664eb +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny: + en: 2255e36ca94e90fa + zh: 7bfa70db175ce842 +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny/problem: + en: adb85f1842b69545 + zh: 42a0ebb3b8015a74 +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny/decision: + en: 08406f9c720d66c1 + zh: b9c81901488d73b5 +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny/alternatives-considered: + en: 6119e2aff3b6be5a + zh: 4237c596c10e1ee9 +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny/alternatives-considered/why-not-make-the-label-revocable-per-session: + en: 198f33d224035c53 + zh: 63068271658034e7 +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny/alternatives-considered/why-not-untrusted-integrity-for-read-only-mode: + en: 5f53545a83ccd02c + zh: f8fd05c1f3440e41 +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny/alternatives-considered/why-not-deny-file-delete-child-with-oi-ci: + en: 78a36aa70395d214 + zh: 0dd32d8ca513cb43 +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny/alternatives-considered/why-not-drop-the-confinement-layer-and-document-the-escape: + en: 9ff963493255783c + zh: 41b5577792e977cd +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny/alternatives-considered/why-not-give-each-workspace-its-own-integrity-level: + en: c39c82f7b745d672 + zh: 7b38d3c4b889dac6 +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny/consequences: + en: 4930b2596686d377 + zh: 022a62051a58181e +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny/testing: + en: 6c1deeacdbff418d + zh: 4d7c546e19da5e53 +/agent-note-windows-sandbox-delete-confinement-mandatory-integrity-plus-an-ambient-delete-deny/related: + en: e4b631df90dd1efa + zh: abc66bfbf8ea2c52 diff --git a/.agents/notes/implemented/feature/2026-09-20-config-schema-dump-validation-policy.i18n.yaml b/.agents/notes/implemented/feature/2026-09-20-config-schema-dump-validation-policy.i18n.yaml index c93f11edb2..9575bd914d 100644 --- a/.agents/notes/implemented/feature/2026-09-20-config-schema-dump-validation-policy.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-20-config-schema-dump-validation-policy.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-20-config-schema-dump-validation-policy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-20-config-schema-dump-validation-policy.md -2026-09-20-config-schema-dump-validation-policy.md: a0f15b6aad1f534f80db15185a9a70d5c22bc7c2 -2026-09-20-config-schema-dump-validation-policy.zh.md: d94f040057e0a221057a8410523e1e154a8ae166 +/agent-note-config-schema-dump-validation-policy: + en: 3934f170891561da + zh: 3f54f8a830b766ee +/agent-note-config-schema-dump-validation-policy/problem: + en: c0baf581702ed4e8 + zh: eb9ab134045c2e18 +/agent-note-config-schema-dump-validation-policy/decision: + en: 047d67040b39f999 + zh: f7eccdb59e9e72bd +/agent-note-config-schema-dump-validation-policy/alternatives-considered: + en: be0e67675b0a6bf3 + zh: 361c7fd4eb482f3a +/agent-note-config-schema-dump-validation-policy/consequences: + en: 5df3531b64f09edd + zh: 03e1a9f15248b171 diff --git a/.agents/notes/implemented/feature/2026-09-20-default-workspace.i18n.yaml b/.agents/notes/implemented/feature/2026-09-20-default-workspace.i18n.yaml index 89b4d5dabf..bfc8acd582 100644 --- a/.agents/notes/implemented/feature/2026-09-20-default-workspace.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-20-default-workspace.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-20-default-workspace.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-20-default-workspace.md -2026-09-20-default-workspace.md: 1674079403b17fb1bd984052a85975609179cad0 -2026-09-20-default-workspace.zh.md: 81a7c96efa3d8b8d4673b684b59babe339706f29 +/agent-note-first-use-default-workspace: + en: cf68fedc85ef73ad + zh: a48dfa96ac11585a +/agent-note-first-use-default-workspace/problem: + en: 952ca70e83872f88 + zh: 471b4e39dba2039a +/agent-note-first-use-default-workspace/decision: + en: 5f70a77db26ed9e2 + zh: 8f6bfb84385315d4 +/agent-note-first-use-default-workspace/alternatives-considered: + en: 58523eb415e53e2a + zh: 714ddd81ef7d3262 +/agent-note-first-use-default-workspace/consequences: + en: ab39d4e9302a2641 + zh: 8921bb8451ef2d0e diff --git a/.agents/notes/implemented/feature/2026-09-20-default-workspace.md b/.agents/notes/implemented/feature/2026-09-20-default-workspace.md index 1674079403..b358cba3ad 100644 --- a/.agents/notes/implemented/feature/2026-09-20-default-workspace.md +++ b/.agents/notes/implemented/feature/2026-09-20-default-workspace.md @@ -14,7 +14,9 @@ Startup waits for complete Workspace and Session baselines. When both lists are The [Workspace registry](../../../../packages/workspace/workspace/README.md#first-use-workspace) owns eligibility and directory preparation. All live Sessions, persisted headers, and archived identities count, including entries absent from the sidebar. The operation shares the registry mutation queue and rechecks Session history after directory preparation because Sessions can start independently. -The Client resolves the initial directory name and title from its language at startup. The Host controller resolves the Documents location; the registry receives a directory resolver with no locale dependency. The resolver runs inside the mutation queue only for eligible creation, so repeated requests reuse the durable Workspace without another OS lookup. A durable Workspace id records successful initialization independently of that name. Renaming, changing language, restarting, or deleting the registration cannot initialize another default. The marker commits with the registration, so a failed registration can retry. Directory contents remain subject to the existing [metadata-only deletion policy](2026-07-27-workspace-registration-deletion.md). +The Host controller resolves the Documents location; the registry receives a directory resolver with no locale dependency. The resolver runs inside the mutation queue only for eligible creation, so repeated requests reuse the durable Workspace without another OS lookup. A durable Workspace id records successful initialization independently of that name. Renaming, changing language, restarting, or deleting the registration cannot initialize another default. The marker commits with the registration, so a failed registration can retry. Directory contents remain subject to the existing [metadata-only deletion policy](2026-07-27-workspace-registration-deletion.md). + +The naming half of this decision is superseded: [language-neutral default Workspace naming](2026-09-23-language-neutral-default-workspace-naming.md) fixes the directory name and stored title and localizes only the on-screen label. Ineligible first use returns no Workspace without a failure dialog. Preparation failure offers the existing folder picker; startup does not retry on later list notifications. A successful registration survives Session creation or prompt failure. Selecting either the default or a manually picked Workspace never submits a message. @@ -23,7 +25,7 @@ Ineligible first use returns no Workspace without a failure dialog. Preparation - Creating only when sending avoids unused directories but requires a separate local draft, transfer into a Session, and coordination of the first submission. Startup creation accepts the early filesystem effect and uses ordinary Session input throughout. - Falling back to `/Documents` when system lookup is unavailable would choose an unverified Documents location; deployments that need another directory use the explicit Host override. - Inferring first use from visible sidebar rows would ignore archived, hidden, and cwd-less Sessions. -- Using the localized path as the initialization marker would allow language changes or deletion to create another default. +- Using the initialization directory's path as the initialization marker would allow renaming, relocation, or deletion to create another default. - Changing a Session's cwd after creation would change the meaning of its recorded tools and attachments. ## Consequences diff --git a/.agents/notes/implemented/feature/2026-09-20-default-workspace.zh.md b/.agents/notes/implemented/feature/2026-09-20-default-workspace.zh.md index 81a7c96efa..e9a8bd6d57 100644 --- a/.agents/notes/implemented/feature/2026-09-20-default-workspace.zh.md +++ b/.agents/notes/implemented/feature/2026-09-20-default-workspace.zh.md @@ -14,7 +14,9 @@ Status: implemented [Workspace registry](../../../../packages/workspace/workspace/README.zh.md#first-use-workspace)负责资格判断和目录准备。所有 live Session、持久化 header 和已归档身份都计入判断,包括侧栏中不可见的条目。操作共用 registry 修改队列,并在目录准备后重新检查 Session 历史,因为 Session 可以独立启动。 -Client 在启动时按其语言解析初始目录名和标题。Host 控制器解析 Documents 位置;注册表接收不依赖 locale 的目录解析器。解析器仅在允许创建时于变更队列内运行,因此重复请求直接复用持久化的 Workspace,无需再次查询操作系统目录。持久化 Workspace id 独立于名称记录初始化成功。改名、切换语言、重启或删除登记均不能再次初始化默认工作区。标记与登记一起提交,因此登记失败可以重试。目录内容仍遵循已有的[仅删除元数据策略](2026-07-27-workspace-registration-deletion.zh.md)。 +Host 控制器解析 Documents 位置;注册表接收不依赖 locale 的目录解析器。解析器仅在允许创建时于变更队列内运行,因此重复请求直接复用持久化的 Workspace,无需再次查询操作系统目录。持久化 Workspace id 独立于名称记录初始化成功。改名、切换语言、重启或删除登记均不能再次初始化默认工作区。标记与登记一起提交,因此登记失败可以重试。目录内容仍遵循已有的[仅删除元数据策略](2026-07-27-workspace-registration-deletion.zh.md)。 + +本决策中与命名相关的部分已被取代:[语言中立的默认工作区命名](2026-09-23-language-neutral-default-workspace-naming.zh.md)固定目录名与存储标题,只本地化屏幕上的标签。 不符合首次使用条件时不返回 Workspace,也不显示失败弹窗。准备失败时提供现有文件夹选择器;后续列表通知不会触发启动流程重试。成功的登记会在 Session 创建或提示词发送失败后保留。选中默认或手动选择的 Workspace 均不会提交消息。 @@ -23,7 +25,7 @@ Client 在启动时按其语言解析初始目录名和标题。Host 控制器 - 仅在发送时创建可以避免未使用的目录,但需要独立的本地草稿、向 Session 转移草稿及首次提交协调逻辑。启动时创建接受提前写入文件系统的副作用,始终使用普通 Session 输入。 - 系统查询不可用时回退到 `/Documents`,会选择未经确认的 Documents 位置;需要其他目录的部署使用显式 Host 覆盖配置。 - 根据侧栏可见行推断首次使用,会忽略已归档、隐藏和无 cwd 的 Session。 -- 将本地化路径作为初始化标记,会允许切换语言或删除后再次创建默认工作区。 +- 将初始化目录的路径作为初始化标记,会允许改名、迁移或删除后再次创建默认工作区。 - 在 Session 创建后更改 cwd,会改变其已记录工具和附件的含义。 ## Consequences diff --git a/.agents/notes/implemented/feature/2026-09-20-desktop-browser-webview.i18n.yaml b/.agents/notes/implemented/feature/2026-09-20-desktop-browser-webview.i18n.yaml index 254189ee9f..b30c8e7897 100644 --- a/.agents/notes/implemented/feature/2026-09-20-desktop-browser-webview.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-20-desktop-browser-webview.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-20-desktop-browser-webview.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-20-desktop-browser-webview.md -2026-09-20-desktop-browser-webview.md: e69114a90f50d51542e9b6a0d40daef05a93001f -2026-09-20-desktop-browser-webview.zh.md: b0ab8b1a7058ae9cbb1258977cb4c4e2d8c40614 +/agent-note-retained-desktop-browser-webviews: + en: 59456b799c9d5d5e + zh: 19a88c553986b463 +/agent-note-retained-desktop-browser-webviews/problem: + en: c6abffbd4077e427 + zh: a7a0a2c2a99cc70b +/agent-note-retained-desktop-browser-webviews/decision: + en: f4970f18902b8974 + zh: 2b1a5fa3fc05f256 +/agent-note-retained-desktop-browser-webviews/decision/storage-ownership: + en: fac51097030c3670 + zh: 86868bc1b9a6d8cf +/agent-note-retained-desktop-browser-webviews/decision/initial-guest-policy: + en: 21ab346f9a98863c + zh: efa115f530d22de3 +/agent-note-retained-desktop-browser-webviews/alternatives-considered: + en: 884daa089df32dcc + zh: 7e16d740897555c9 +/agent-note-retained-desktop-browser-webviews/consequences: + en: 01d4a2e6f638d5e9 + zh: 9804b00edea2b03c diff --git a/.agents/notes/implemented/feature/2026-09-20-developer-tools-default-on.i18n.yaml b/.agents/notes/implemented/feature/2026-09-20-developer-tools-default-on.i18n.yaml index aa7199eff4..7467604771 100644 --- a/.agents/notes/implemented/feature/2026-09-20-developer-tools-default-on.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-20-developer-tools-default-on.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-20-developer-tools-default-on.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-20-developer-tools-default-on.md -2026-09-20-developer-tools-default-on.md: 42c89faed11b966ac8ea0882236af9bf13557702 -2026-09-20-developer-tools-default-on.zh.md: a684844f5ba53a0bebdd1c3a3a3ade1ed150cc31 +/agent-note-developer-tools-default-on-after-preference-resolution: + en: 9e6062c94dd70c14 + zh: 3c04f278da2016a5 +/agent-note-developer-tools-default-on-after-preference-resolution/problem: + en: 81d08fb192b8e83b + zh: 90a841219f86bc12 +/agent-note-developer-tools-default-on-after-preference-resolution/decision: + en: 8a3fbb5281d1b313 + zh: 320b845842676375 +/agent-note-developer-tools-default-on-after-preference-resolution/alternatives-considered: + en: 7d9ecd04554103c4 + zh: 2706bb78fcc6072d +/agent-note-developer-tools-default-on-after-preference-resolution/consequences: + en: 54622ff5338afba9 + zh: 494d55213b2751a0 diff --git a/.agents/notes/implemented/feature/2026-09-20-focus-ring-brand-primary.i18n.yaml b/.agents/notes/implemented/feature/2026-09-20-focus-ring-brand-primary.i18n.yaml new file mode 100644 index 0000000000..0e8511d871 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-20-focus-ring-brand-primary.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-20-focus-ring-brand-primary.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-20-focus-ring-brand-primary.md +/agent-note-one-keyboard-focus-colour-for-every-control: + en: 967e19daff3df9bc + zh: 81e1a21d4204eb8a +/agent-note-one-keyboard-focus-colour-for-every-control/problem: + en: 2f3f77b1de539959 + zh: a4fa146b1d9ddecf +/agent-note-one-keyboard-focus-colour-for-every-control/decision: + en: 613ec184df6bf5d5 + zh: e4b3f95f4d33a54c +/agent-note-one-keyboard-focus-colour-for-every-control/alternatives-considered: + en: 392968102d520d1d + zh: e7b7b68f145cf3d3 +/agent-note-one-keyboard-focus-colour-for-every-control/consequences: + en: 25b9933c3d43ad76 + zh: 75d374ce3b7ec2eb diff --git a/.agents/notes/implemented/feature/2026-09-20-focus-ring-brand-primary.md b/.agents/notes/implemented/feature/2026-09-20-focus-ring-brand-primary.md new file mode 100644 index 0000000000..8212eaf529 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-20-focus-ring-brand-primary.md @@ -0,0 +1,43 @@ +# Agent Note: One keyboard-focus colour for every control + +Status: implemented + +English | [中文](2026-09-20-focus-ring-brand-primary.zh.md) + +## Problem + +Different explicit focus colours and browser-default outlines do not provide a consistent keyboard-focus cue. Browser defaults can also depend on the operating-system accent. + +Focus feedback has separate interaction and geometry constraints. A browser's `:focus-visible` heuristic can reveal a pointer-focused button after a key that does not move focus, while editable text controls need focus feedback on click. Containers that clip their contents can hide an outer ring. + +## Decision + +[The theme's focus stylesheet](../../../../packages/client/ui-theme/src/styles/focus.css) owns the shared ring colour and standard width. [Input modality](../../../../packages/client/ui-primitives/README.md#input-modality) distinguishes tooltip input from keyboard focus navigation. + +**One colour.** Global and component `:focus-visible` outlines and focus-ring shadows read `--dsw-focus-ring-color`, falling back to `--dsw-alias-state-business-primary`. The global fallback names the colour and the standard width but never the style, so it cannot create an outline where the component disables one. Naming the width is what keeps a control with no ring of its own at the standard geometry instead of Chromium's `auto 1px`. + +**Context-owned geometry.** `--dsw-focus-ring-width` carries the standard 2px width. Dense tables and toolbars may keep 1px so the ring does not dominate compact content. Components own their offsets and use an inset ring where an outer ring would be clipped. + +**Pointer focus does not imply keyboard navigation.** In pointer modality, `:focus-visible:not(:read-write)` controls use a transparent ring colour. Descendant and pseudo-element rings inherit it. Only focus-ring paint is suppressed: selected-state borders and elevation shadows remain, and editable text controls keep their own focus feedback on click. DOM focus stays on the control. + +Tooltips follow the last input and treat any key as keyboard input. Rings instead resume keyboard styling on non-composing navigation keys, or on focus reaching a different control after a non-composing key. Refocusing the same control is not navigation; pointer input, composition keys, and window blur clear the pending key. + +## Alternatives considered + +**Rewrite only the component declarations.** Explicit rings would agree, but controls using a browser-default outline would retain its colour. Requiring every control to declare its own ring would also leave new controls inconsistent until their authors add that rule. + +**Unify width and offset globally.** Positive offsets can be clipped by a scrolling ancestor, while a uniform thick ring can overwhelm dense content. Neither colour consistency nor input modality requires identical geometry. + +**Suppress by moving focus instead of by style.** Calling `blur()` on a pointer-focused button would hide its ring but also remove the target for subsequent Enter or Space activation. + +**Clear all shadows on pointer focus.** A `box-shadow` can contain elevation or selected-state paint as well as a focus ring. Suppressing its ring colour preserves those independent cues; exempting `:read-write` preserves text-entry feedback. + +**Replace every `outline: none` with a shared ring.** Some controls use an inset shadow or container-level focus treatment instead; some containers deliberately show no ring. Replacing those declarations would change their focus treatment, not merely its colour. + +**Give tooltips and rings the same modality rule.** A key can justify a tooltip on subsequent programmatic focus without justifying a ring on the same pointer-focused button. Keeping separate answers preserves both behaviours. + +## Consequences + +Focus rings share a theme colour while components retain their geometry and non-focus state cues. Ring visibility changes without changing the keyboard's active target. These rules do not guarantee identical browser rendering or eliminate component-specific clipping. + +[Stylesheet-order checks](../../../../packages/client/ui-theme/tests/client-styles.client.spec.ts), [focus-style checks](../../../../packages/client/ui-theme/tests/focus-ring-styles.client.spec.ts), and [input-modality tests](../../../../packages/client/ui-primitives/tests/input-modality.client.spec.ts) cover stylesheet declarations and modality transitions. Static declarations and synthetic events do not establish rendered ring visibility or cross-platform behaviour. diff --git a/.agents/notes/implemented/feature/2026-09-20-focus-ring-brand-primary.zh.md b/.agents/notes/implemented/feature/2026-09-20-focus-ring-brand-primary.zh.md new file mode 100644 index 0000000000..479e2d0efd --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-20-focus-ring-brand-primary.zh.md @@ -0,0 +1,43 @@ +# Agent Note:所有控件共用一个键盘焦点颜色 + +Status: implemented + +[English](2026-09-20-focus-ring-brand-primary.md) | 中文 + +## 问题 + +不同的显式焦点颜色与浏览器默认轮廓无法提供一致的键盘焦点提示。浏览器默认值还可能取决于操作系统强调色。 + +焦点反馈另有交互与几何约束。浏览器的 `:focus-visible` 启发式可能在不移动焦点的按键之后显出指针聚焦按钮的环,而可编辑文本控件在点击时需要焦点反馈。裁切内容的容器可能隐藏外扩环。 + +## 决策 + +[主题焦点样式表](../../../../packages/client/ui-theme/src/styles/focus.css) 拥有共享焦点环颜色与标准宽度。[输入模态](../../../../packages/client/ui-primitives/README.zh.md#input-modality) 区分 tooltip 输入与键盘焦点导航。 + +**一个颜色。** 全局与组件的 `:focus-visible` 轮廓和焦点环阴影读取 `--dsw-focus-ring-color`,回退到 `--dsw-alias-state-business-primary`。全局兜底声明颜色与标准宽度、但不声明样式,因此组件禁用轮廓时它不会创建轮廓。声明宽度可让没有自有焦点环的控件保持标准几何,而不是落到 Chromium 的 `auto 1px`。 + +**场景决定几何。** `--dsw-focus-ring-width` 提供标准的 2px 宽度。密集表格与工具栏可以保留 1px,避免焦点环压过紧凑内容。组件拥有自己的 offset,并在外扩环会被裁切时使用内嵌环。 + +**指针焦点不等于键盘导航。** 指针模态下,`:focus-visible:not(:read-write)` 控件使用透明的焦点环颜色。后代与伪元素上的环继承该值。只抑制焦点环绘制:选中态边框与 elevation 阴影保留,可编辑文本控件在点击时保留自身焦点反馈。DOM 焦点仍留在控件上。 + +Tooltip 跟随最近一次输入,将任意按键视为键盘输入。焦点环则在非组合输入的导航键到达时,或非组合输入按键之后焦点到达不同控件时,恢复键盘样式。重新聚焦同一控件不算导航;指针输入、组合输入按键和 window blur 会清除待处理按键。 + +## 考虑过的其他做法 + +**只重写组件声明。** 显式焦点环会一致,但使用浏览器默认轮廓的控件仍会保留其颜色。要求每个控件自行声明焦点环,也会让新控件在作者补上规则之前保持不一致。 + +**全局统一宽度与 offset。** 正 offset 可能被滚动祖先裁切,统一的粗环则可能压过密集内容。颜色一致性和输入模态都不要求相同的几何。 + +**用移动焦点取代样式抑制。** 对指针聚焦的按钮调用 `blur()` 可以隐藏焦点环,但也会移除后续 Enter 或 Space 激活的目标。 + +**指针聚焦时清除所有阴影。** 一个 `box-shadow` 除了焦点环,还可能包含 elevation 或选中态绘制。抑制其焦点环颜色可保留这些独立提示;豁免 `:read-write` 可保留文本输入反馈。 + +**把所有 `outline: none` 改为共享焦点环。** 一些控件改用内嵌阴影或容器级焦点处理;一些容器则刻意不显示焦点环。替换这些声明会改变焦点处理方式,而不只是颜色。 + +**让 tooltip 与焦点环共用同一条模态规则。** 按键可以让后续程序化聚焦显示 tooltip,却不一定需要在同一个指针聚焦按钮上显示焦点环。分别记录两个答案可保留两种行为。 + +## 影响 + +焦点环共享主题颜色,组件保留自己的几何与非焦点状态提示。焦点环可见性的变化不改变键盘的活动目标。这些规则不保证浏览器渲染完全相同,也不会消除组件特有的裁切。 + +[样式表顺序检查](../../../../packages/client/ui-theme/tests/client-styles.client.spec.ts)、[焦点样式检查](../../../../packages/client/ui-theme/tests/focus-ring-styles.client.spec.ts)与[输入模态测试](../../../../packages/client/ui-primitives/tests/input-modality.client.spec.ts)覆盖样式声明和模态转换。静态声明与合成事件不能确认焦点环的实际渲染可见性或跨平台行为。 diff --git a/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.i18n.yaml b/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.i18n.yaml index d6f9f2b719..bf652c02d6 100644 --- a/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-21-archive-stops-running-session-work.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.md -2026-09-21-archive-stops-running-session-work.md: 2df18c00e6a561e3d85820cbf472bacf5acd9b1d -2026-09-21-archive-stops-running-session-work.zh.md: 423a01bd2feab61c62fa0f4b4b4296674e6b24e4 +/agent-note-archiving-a-session-with-running-work: + en: 0fbbf70c0c7c2bfa + zh: 5d3119ee84af3796 +/agent-note-archiving-a-session-with-running-work/problem: + en: 7926983089aebab2 + zh: 366e32db00674a83 +/agent-note-archiving-a-session-with-running-work/decision: + en: 23adfbe72d671d6c + zh: 6fec976acfa54720 +/agent-note-archiving-a-session-with-running-work/alternatives-considered: + en: 708268e1fe4b4b75 + zh: 64a8f6d6f333e090 +/agent-note-archiving-a-session-with-running-work/consequences: + en: cb3fdefd60483d62 + zh: 87d3cead6dc8c37c diff --git a/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.md b/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.md index 2df18c00e6..4bc3bab644 100644 --- a/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.md +++ b/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.md @@ -14,7 +14,7 @@ Archive never hides running work. The registry owns the rule and declares one ca - **Refuse by default.** `archiveSession(sessionId)` rejects a non-empty activity answer with `WorkspaceActiveSessionError`; the API maps it to `workspace/session-active`, whose details carry the families with item ids and labels. A caller that did not ask to stop work never hides it, whichever client or SDK it is. - **Stop on request, after the write.** `archiveSession(sessionId, { stopActivity: true })` skips the activity check, writes the archive, and then dispatches the stop event: the durable archive set is what the pre-step gate reads, so every wake a stop induces — a cancelled child's settlement, a queued follow-up — is already blocked. The stops are issued and never awaited to settlement, so the Remote returns once every provider's request is out and the user's row hides at once; a stop that fails is a logged warning, not a reason to undo the archive. -- **The stop is the user's stop.** The Agent registry cancels the turn with `agent.cancel({ kind: 'user' })` — the stop button's path, so the aborted tool call settles as a `tool/result` and the turn ends as `aborted`, but without the button's `keepInbox`, so queued input is discarded with a logged inbox splice. The job registry seam kills the owned jobs, installed by its constructor for every implementation through the abstract `list` and `kill`. The Subagent runtime cancels running subagent descendants (durable lineage, subagent origin, any depth, never a fork) as their parent would. Each request is contained on its own, so one child or job that throws does not keep the others running. The Schedule plugin deletes every active reminder as a management delete in its transaction queue — the same durable change the `schedule_delete` tool records, between the same two persistence barriers — answering from its owned runtime's fold of the live log rather than from the projection registry, which is a Client view. Each provider owns exactly the vocabulary it already has: the Agent registry knows turns, the job seam knows jobs, the Subagent runtime knows children, the Schedule plugin knows reminders; the API Session Controller keeps only the archived-lineage step gate. No new event type and no write inside another owner's turn, so a restored Session continues from a regularly ended log and unarchive brings nothing back that was stopped. +- **The stop is the user's stop.** The Agent registry cancels the turn with `agent.cancel({ kind: 'user' })` — the stop button's path, so the aborted tool call settles as a `tool/result` and the turn ends as `aborted`, but without the button's `keepInbox`, so queued input is discarded with a logged inbox splice. The job registry seam kills the owned jobs, installed by its constructor for every implementation through the abstract `list` and `kill`. The Subagent runtime cancels running subagent descendants (durable lineage, subagent origin, any depth, never a fork) as their parent would. Each request is contained on its own, so one child or job that throws does not keep the others running. The Schedule plugin deletes every active Host task stored for the Session ([archive admission reads the stored tasks](2026-09-22-archive-admission-reads-stored-tasks.md)) inside one slot of the same serialized queue the tools use. It reads the stored rows rather than a runtime fold of the Session log, because a Host task outlives its Session's Agent and is the only place a due reminder can be seen. Each provider owns exactly the vocabulary it already has: the Agent registry knows turns, the job seam knows jobs, the Subagent runtime knows children, the Schedule plugin knows reminders; the API Session Controller keeps only the archived-lineage step gate. No new event type and no write inside another owner's turn, so a restored Session continues from a regularly ended log and unarchive brings nothing back that was stopped. - **Archived means no model step.** The API Session Controller's `agent/pre-step` listener rejects a step proposed for an archived Session or for a subagent descendant of one, which the loop ends as `blocked` without a request. This closes the window in which a late waking delivery — a subagent settlement, a queued follow-up, a turn started between the activity answer and the write — would run a hidden turn, and keeps a child whose cancel was ignored from working for a parent nobody can see; unarchiving lifts the gate for the lineage. - **The refusal is the confirmation.** The sidebar sends the plain archive first; a quiet Session archives without a dialog as before. The `workspace/session-active` refusal opens the stop-and-archive dialog, whose list comes from the Host's answer rather than a client-side mirror of running state, so the dialog names exactly what the Host will stop. Confirming resends with `stopActivity`; the notice offers undo, which restores the Session without resuming the stopped work. @@ -32,10 +32,10 @@ Archive never hides running work. The registry owns the rule and declares one ca **Report the families from the API Session Controller.** The controller sees every live Agent, the job registry, and the lineage fields on Session headers, so it could enumerate turns, children, and jobs itself — but then it would know each owner's vocabulary (descriptors and labels, the parent-cause cancel, job ownership). The Agent registry, the job seam, and the Subagent runtime already own that vocabulary, so each family lives with its owner; the controller keeps only the lineage step gate, which reads the archive set and header fields alone. The gate cannot move into `dsh-workspace` in turn: the owners now depend on its types, so the workspace package cannot depend on the Agent event vocabulary without a cycle. -**Refuse cold Sessions with active reminders.** A cold reminder fires only after a resume; an archived Session cannot be opened from the sidebar, and a resume through another operation meets the pre-step gate, so nothing runs hidden; only live Sessions report the `schedule` family. +**Report the `schedule` family from live Sessions only.** The stored tasks are authoritative and outlive their Session's Agent, so consulting liveness would let a cold Session with armed rows archive silently, and its due row then dispatches into a turn the gate ends as `blocked`, consuming the occurrence without a model step ([archive admission reads the stored tasks](2026-09-22-archive-admission-reads-stored-tasks.md)). ## Consequences -An archived Session is guaranteed idle: it either was quiet, or its work was stopped the way the user stops it, and no step runs for it until it is restored. The pin-and-archive decision's "archive needs no confirmation" holds for quiet Sessions only; the running case asks. Stop settlement is best effort: a job that ignores kill or a child that ignores cancel is logged, and the pre-step gate keeps the Session from spending model requests meanwhile. The activity check and the archive write are two steps, so a turn starting between them is hidden, and every step whose pre-step precedes the write still runs with its tool calls, until the first step after the write is blocked. Two residues follow from the write-first order and the gate. A crash between the archive write and the Schedule plugin's delete barrier leaves an archived Session whose reminders are still recorded; unarchiving shows them again, as if the stop had never been requested. A cold archived Session reports no reminders, and an operation that resumes its Agent — rename, model, or queue edits address a Session without unarchiving it — re-arms them: a due one-shot then dispatches its follow-up into a turn the gate ends as `blocked`, so that occurrence is consumed without a model step and is not replayed after unarchive. +An archived Session is guaranteed idle: it either was quiet, or its work was stopped the way the user stops it, and no step runs for it until it is restored. The pin-and-archive decision's "archive needs no confirmation" holds for quiet Sessions only; the running case asks. Stop settlement is best effort: a job that ignores kill or a child that ignores cancel is logged, and the pre-step gate keeps the Session from spending model requests meanwhile. The activity check and the archive write are two steps, so a turn starting between them is hidden, and every step whose pre-step precedes the write still runs with its tool calls, until the first step after the write is blocked. Two residues follow from the write-first order and the gate. A crash between the archive write and the Schedule plugin's stop leaves an archived Session whose stored tasks are still armed; unarchiving shows them again, as if the stop had never been requested, and when such a row's target passes the Schedule runtime selects it on its own timer and resolves the Session's Agent itself, so a one-shot dispatches its follow-up into a turn the gate ends as `blocked` and that occurrence is consumed without a model step and is not replayed after unarchive. Admission itself reports the stored tasks of a Session without a live Agent, so such a Session is refused before that residue can start. Peer products surveyed for this choice: Codex and Kimi Code stop then archive; Claude Code stops by starving the remote session of writes; Reasonix and MiniMax refuse a busy Session, MiniMax after a bounded cancel; Pi has no archive but aborts before every session switch; OpenCode neither refuses nor stops. Every product that stops does so through its ordinary cancel path so the log ends regularly. diff --git a/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.zh.md b/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.zh.md index 423a01bd2f..c7a912fa65 100644 --- a/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.zh.md +++ b/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.zh.md @@ -14,7 +14,7 @@ - **默认拒绝。** `archiveSession(sessionId)` 对非空的活动答案以 `WorkspaceActiveSessionError` 拒绝;API 把它映射为 `workspace/session-active`,details 携带各族及各项的 id 与名称。没有要求停止工作的调用方绝不会把工作藏起来,无论它是哪个客户端或 SDK。 - **按请求停止,先写后停。** `archiveSession(sessionId, { stopActivity: true })` 跳过活动检查,先写入归档,再派发停止事件:pre-step 门禁读取的正是持久化的归档集合,因此停止所引发的每一次唤醒——被取消子代理的结算、排队的 follow-up——都已被拦下。停止请求只发出、从不等待收敛,因此 Remote 在每个提供方的请求发出后即返回,用户的行随即隐藏;停止失败只是一条 warn 日志,不是撤销归档的理由。 -- **停止即用户的停止。** Agent 注册表用 `agent.cancel({ kind: 'user' })` 取消回合——与停止按钮同一条路径,因此被打断的工具调用以 `tool/result` 收口、回合以 `aborted` 结束,但不带按钮的 `keepInbox`,因此排队输入被丢弃并记录一次收件箱拼接。任务注册表接缝 kill 所属任务,由其构造函数只通过抽象的 `list` 与 `kill` 为每个实现安装。Subagent runtime 以父身份取消运行中的子代理子孙(持久化血缘、subagent 来源、任意深度、从不包括 fork)。每个请求各自兜住,一个抛错的子代理或任务不会让其余的继续跑。Schedule 插件把每条活动提醒作为其事务队列中的管理删除来删除——与 `schedule_delete` 工具相同的持久化变更,处于同样的两道持久化屏障之间——答案来自其归属 runtime 对活日志的 fold,而不是投影注册表这个 Client 视图。每个提供方只拥有它本来就有的词汇:Agent 注册表认识回合,任务接缝认识任务,Subagent runtime 认识子代理,Schedule 插件认识提醒;API Session Controller 只保留已归档血缘的步骤门禁。没有新事件类型,也不在别的所有者的回合内写入,因此恢复后的 Session 从一份正常收尾的日志继续,取消归档不会带回任何被停止的东西。 +- **停止即用户的停止。** Agent 注册表用 `agent.cancel({ kind: 'user' })` 取消回合——与停止按钮同一条路径,因此被打断的工具调用以 `tool/result` 收口、回合以 `aborted` 结束,但不带按钮的 `keepInbox`,因此排队输入被丢弃并记录一次收件箱拼接。任务注册表接缝 kill 所属任务,由其构造函数只通过抽象的 `list` 与 `kill` 为每个实现安装。Subagent runtime 以父身份取消运行中的子代理子孙(持久化血缘、subagent 来源、任意深度、从不包括 fork)。每个请求各自兜住,一个抛错的子代理或任务不会让其余的继续跑。Schedule 插件在与工具相同的串行队列的一个槽位里删除该 Session 已存储的全部活动宿主任务([归档准入读取已存储的任务](2026-09-22-archive-admission-reads-stored-tasks.zh.md))。它读已存储的行,而不是对会话日志做 runtime fold,因为宿主任务比其 Session 的 Agent 活得更久,是到期提醒唯一能被看见的地方。每个提供方只拥有它本来就有的词汇:Agent 注册表认识回合,任务接缝认识任务,Subagent runtime 认识子代理,Schedule 插件认识提醒;API Session Controller 只保留已归档血缘的步骤门禁。没有新事件类型,也不在别的所有者的回合内写入,因此恢复后的 Session 从一份正常收尾的日志继续,取消归档不会带回任何被停止的东西。 - **已归档即不跑模型步。** API Session Controller 的 `agent/pre-step` 监听器拒绝为已归档 Session 或其子代理子孙提出的步骤,loop 以 `blocked` 收口且不发请求。这封住了迟到的唤醒投递——子代理结算、排队的 follow-up、在活动作答与写入之间开始的回合——跑出隐藏回合的窗口,也让无视 cancel 的子代理无法替一个谁也看不见的父级干活;取消归档即为整条血缘解除门禁。 - **拒绝即确认。** 侧栏先发普通归档;静止的 Session 一如既往无对话框直接归档。`workspace/session-active` 拒绝会打开"停止并归档"对话框,其清单来自宿主的答案而非客户端对运行状态的镜像,因此对话框列出的正是宿主将要停止的内容。确认后带 `stopActivity` 重发;提示提供撤销,撤销只恢复 Session,不会让被停止的工作继续。 @@ -32,10 +32,10 @@ **由 API Session Controller 报告各族。** 控制器看得到每个活 Agent、任务注册表和 Session header 上的血缘字段,本可以自己枚举回合、子代理和任务——但那样它就得认识每个 owner 的词汇(描述符与名称、父级原因的取消、任务归属)。Agent 注册表、任务接缝与 Subagent runtime 本来就拥有这些词汇,所以每一族都跟着自己的 owner;控制器只保留只读归档集合与 header 字段的血缘步骤门禁。门禁也不能反过来搬进 `dsh-workspace`:各 owner 现在依赖它的类型,workspace 包再依赖 Agent 的事件词汇就会成环。 -**拒绝带活动提醒的冷 Session。** 冷提醒只在 resume 后才触发;已归档的 Session 无法从侧栏打开,经其他操作 resume 也会撞上 pre-step 门禁,所以没有东西在隐藏运行;只有活 Session 报告 `schedule` 族。 +**只由活着的 Session 报告 `schedule` 族。** 已存储的任务才是权威,且比其 Session 的 Agent 活得更久,因此以存活为条件会让存储行被武装的冷 Session 静默归档,其到期行随后投递进一个被门禁以 `blocked` 收口的回合,在没有模型步的情况下消耗掉这次触发([归档准入读取已存储的任务](2026-09-22-archive-admission-reads-stored-tasks.zh.md))。 ## 后果 -已归档的 Session 保证空闲:它要么本来就静止,要么其工作已按用户停止的方式停止,且在恢复之前不会为它跑任何一步。置顶与归档决策里的"归档无需确认"仅对静止 Session 成立;运行中的情形会先询问。停止的收敛是尽力而为:无视 kill 的任务或无视 cancel 的子代理会被记录,pre-step 门禁在此期间阻止该 Session 消耗模型请求。活动检查与归档写入是两步,其间开始的回合会被隐藏,pre-step 先于该写入的每一步连同其工具调用照常执行,直到写入之后的第一步被阻断。先写后停与门禁留下两处残余。在归档写入与 Schedule 插件的删除屏障之间崩溃,会留下一个提醒仍被记录的已归档 Session;取消归档时它们再次出现,与从未请求过停止时一样。冷的已归档 Session 不报告提醒,而恢复其 Agent 的操作——重命名、模型、队列编辑都按 Session 寻址而不取消归档——会重新武装它们:到期的一次性提醒把 follow-up 投递进一个被门禁以 `blocked` 收口的回合,该次触发因此在没有模型步的情况下被消耗,取消归档后也不会重放。 +已归档的 Session 保证空闲:它要么本来就静止,要么其工作已按用户停止的方式停止,且在恢复之前不会为它跑任何一步。置顶与归档决策里的"归档无需确认"仅对静止 Session 成立;运行中的情形会先询问。停止的收敛是尽力而为:无视 kill 的任务或无视 cancel 的子代理会被记录,pre-step 门禁在此期间阻止该 Session 消耗模型请求。活动检查与归档写入是两步,其间开始的回合会被隐藏,pre-step 先于该写入的每一步连同其工具调用照常执行,直到写入之后的第一步被阻断。先写后停与门禁留下两处残余。在归档写入与 Schedule 插件的停止之间崩溃,会留下一个已存储任务仍被武装的已归档 Session;取消归档时它们再次出现,与从未请求过停止时一样;当这类行的目标时刻过去,Schedule runtime 会按自己的定时器选中它并自行 resolve 该 Session 的 Agent,一次性提醒于是把 follow-up 投递进一个被门禁以 `blocked` 收口的回合,该次触发因此在没有模型步的情况下被消耗,取消归档后也不会重放。准入本身会报告没有活 Agent 的 Session 的已存储任务,因此这类 Session 在残余发生之前就被拒绝。 为此决策调研的同行产品:Codex 与 Kimi Code 先停止再归档;Claude Code 通过让远端会话无法写入来停止;Reasonix 与 MiniMax 拒绝忙碌的 Session,MiniMax 在有界取消之后才拒绝;Pi 没有归档但在每次切换会话前 abort;OpenCode 既不拒绝也不停止。每一个会停止的产品都走自己的常规取消路径,以便日志正常收尾。 diff --git a/.agents/notes/implemented/feature/2026-09-22-archive-admission-reads-stored-tasks.i18n.yaml b/.agents/notes/implemented/feature/2026-09-22-archive-admission-reads-stored-tasks.i18n.yaml new file mode 100644 index 0000000000..cc02859b0e --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-22-archive-admission-reads-stored-tasks.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-22-archive-admission-reads-stored-tasks.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-22-archive-admission-reads-stored-tasks.md +/agent-note-archive-admission-reads-the-stored-tasks: + en: 8be4b1d210d5d8bf + zh: e9124b48467818b3 +/agent-note-archive-admission-reads-the-stored-tasks/problem: + en: 093de39b40f7cc97 + zh: 50c712bde174bc96 +/agent-note-archive-admission-reads-the-stored-tasks/decision: + en: afbf818442c0794a + zh: 4749e63d9757bbbb +/agent-note-archive-admission-reads-the-stored-tasks/alternatives-considered: + en: 099360f2c97a50ea + zh: eac4746c4602f152 +/agent-note-archive-admission-reads-the-stored-tasks/consequences: + en: cb2883b34c2c73fa + zh: 9bb1489c9711cf99 diff --git a/.agents/notes/implemented/feature/2026-09-22-archive-admission-reads-stored-tasks.md b/.agents/notes/implemented/feature/2026-09-22-archive-admission-reads-stored-tasks.md new file mode 100644 index 0000000000..2073ae420d --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-22-archive-admission-reads-stored-tasks.md @@ -0,0 +1,27 @@ +# Agent Note: Archive admission reads the stored tasks + +Status: implemented + +English | [中文](2026-09-22-archive-admission-reads-stored-tasks.zh.md) + +## Problem + +Archive admission asks every provider what still runs for a Session before the archive is written, and a stop-archive then asks those providers to end it ([archiving a Session with running work](2026-09-21-archive-stops-running-session-work.md)). The Schedule provider answered from its owned runtime's fold of the live Session log, so only a Session with a live Agent reported the `schedule` family, and the stop deleted through the management `delete` path. + +Host tasks are stored in the Schedule domain document and outlive their Session's Agent ([the storage decision](../architecture/2026-09-16-host-schedule-storage.md)), so that fold no longer exists: `ScheduleRuntime.activeRecords()` is gone, and the stored task table is the only place a due reminder can be seen. A cold Session whose stored rows were still armed therefore reported nothing, archived without the confirmation dialog the running case asks for, and nobody was told which reminder the Host would keep. + +## Decision + +The Schedule provider answers archive admission from the stored Host task rows, and a stop deletes them. `workspace/session-activity` reads `list({ sessionId })` — the stored rows whose binding is that Session and whose status is active — reports them as the `schedule` family, one item per task with its stored id and title, and prepends that family to `next()` so every other provider keeps its entries. `workspace/session-stop` removes those rows directly inside one slot of the same serialized queue the tools use, so a stop is ordered behind a create whose write is still in flight and cannot miss the row that create is about to commit; it attempts every row, because a row left armed would still fire, and it notifies observers for the rows that landed before the first failure reaches the caller. Session liveness is never consulted: an idle or cold Session whose stored rows are armed refuses the archive, and the confirmation dialog names exactly those reminders. Both listeners are registered in one effect named `schedule.archiveAdmission()`, so unloading the plugin withdraws them together. + +## Alternatives considered + +**Report the `schedule` family from live Sessions only.** The stored tasks are authoritative and outlive their Session's Agent, so consulting liveness would let a cold Session with armed rows archive silently, and its due row then dispatches into a turn the gate ends as `blocked`, consuming the occurrence without a model step. The admission answer costs one table read either way. + +**Delete each row through the public management `delete` path.** Re-entering the serialized queue from inside the slot that already holds it deadlocks, so the stop removes the rows itself: the same durable change, with one notification and one timer re-drive per stop instead of one per row. + +**Keep a runtime-side mirror of the Session's active tasks.** A mirror duplicates the authoritative document, drifts after a restart, and disappears with the Agent — the exact case admission must still answer for. + +## Consequences + +Admission costs one stored-table read, and a Session with no live Agent can refuse the archive: a Session that looks quiet may now ask for confirmation because its stored reminders are armed. A stop deletes rows one at a time — the domain table offers no batch delete — so a failure partway leaves the earlier deletes committed; observers hear about those, every row was attempted, and the first failure still reaches the caller. One residue follows. A crash between the archive write and the stop leaves stored rows armed in an archived Session: unarchiving shows them again, and when such a row's target passes the Schedule runtime selects it on its own timer and resolves the Session's Agent itself — that resolution is ungated, and only `agent/pre-step` refuses the model step — so a one-shot dispatches a follow-up into a turn the gate ends as `blocked` and that occurrence is consumed without a model step. The seam itself is unchanged: the workspace package still knows no Schedule vocabulary, and this provider owns only reminders. diff --git a/.agents/notes/implemented/feature/2026-09-22-archive-admission-reads-stored-tasks.zh.md b/.agents/notes/implemented/feature/2026-09-22-archive-admission-reads-stored-tasks.zh.md new file mode 100644 index 0000000000..c95fb280c3 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-22-archive-admission-reads-stored-tasks.zh.md @@ -0,0 +1,27 @@ +# Agent Note:归档准入读取已存储的任务 + +状态:implemented + +[English](2026-09-22-archive-admission-reads-stored-tasks.md) | 中文 + +## 问题 + +归档准入在写入归档前询问每个提供方:该 Session 还有什么在跑;随后「停止并归档」再要求它们结束这些工作([归档仍有工作在跑的 Session](2026-09-21-archive-stops-running-session-work.zh.md))。Schedule 提供方原先回答的是其归属 runtime 对活会话日志的 fold,因此只有带活 Agent 的 Session 才报告 `schedule` 族,停止也走管理 `delete` 路径。 + +宿主任务存储在 Schedule 领域文档中,且比其 Session 的 Agent 活得更久([存储决策](../architecture/2026-09-16-host-schedule-storage.zh.md)),因此那个 fold 已不存在:`ScheduleRuntime.activeRecords()` 已经移除,已存储的任务表是到期提醒唯一能被看见的地方。存储行仍被武装的冷 Session 因此什么也不报告,归档时不会弹出运行态才会弹出的确认对话框,也没有人被告知宿主会继续保留哪条提醒。 + +## 决策 + +Schedule 提供方从已存储的宿主任务行回答归档准入,并由停止删除这些行。`workspace/session-activity` 读取 `list({ sessionId })`——绑定到该 Session 且状态为活动的已存储行——把它们作为 `schedule` 族报告,每条任务一项、携带其已存储 id 与 title,并把该族前插到 `next()` 的结果之前,使其他提供方保留各自条目。`workspace/session-stop` 在与工具相同的串行队列的一个槽位里直接删除这些行,因此停止会排在写入尚未完成的创建之后,不会漏掉那个创建即将提交的行;它会尝试每一行,因为留下的行仍会触发;对已经落地的行先通知观察者,再把首个失败交给调用方。是否存活从不参与判断:存储行仍被武装的空闲或冷 Session 会拒绝归档,确认对话框会准确列出这些提醒。两个监听器注册在同一个名为 `schedule.archiveAdmission()` 的 effect 中,卸载插件即一并撤回。 + +## 已考虑的备选 + +**只由活着的 Session 报告 `schedule` 族。** 已存储的任务才是权威,且比其 Session 的 Agent 活得更久,因此以存活为条件会让存储行被武装的冷 Session 静默归档,其到期行随后投递进一个被门禁以 `blocked` 收口的回合,在没有模型步的情况下消耗掉这次触发。两种做法在准入上都只需一次读表。 + +**每行都走公开的管理 `delete` 路径删除。** 在已经持有该槽位的串行队列内部再次进入队列会自锁,因此停止自己删行:同样的持久化变更,每次停止一次通知、一次计时器重算,而不是每行各一次。 + +**在 runtime 侧保留该 Session 活动任务的镜像。** 镜像会重复权威文档、在重启后漂移、并随 Agent 一起消失——而这正是准入必须仍能回答的情形。 + +## 后果 + +准入的代价是一次读已存储的表,而没有活 Agent 的 Session 也能拒绝归档:看起来安静的 Session 现在可能因为其已存储提醒仍被武装而要求确认。停止逐行删除——领域表不提供批量删除——因此删到一半失败时,先前删除已提交;观察者会被告知这些,每一行都已被尝试,首个失败仍交给调用方。由此剩下一处残余:在归档写入与停止之间崩溃,会在已归档的 Session 里留下仍被武装的已存储行;取消归档时它们再次出现;当这类行的目标时刻过去,Schedule runtime 会按自己的定时器选中它并自行 resolve 该 Session 的 Agent——这一步没有门禁,只有 `agent/pre-step` 拒绝模型步——一次性提醒于是把 follow-up 投递进一个被门禁以 `blocked` 收口的回合,该次触发在没有模型步的情况下被消耗。接缝本身未变:workspace 包仍然不认识 Schedule 词汇,而这个提供方只拥有提醒。 diff --git a/.agents/notes/implemented/feature/2026-09-22-unbounded-completion-wakes-by-default.i18n.yaml b/.agents/notes/implemented/feature/2026-09-22-unbounded-completion-wakes-by-default.i18n.yaml index 24ad5190da..a107523e07 100644 --- a/.agents/notes/implemented/feature/2026-09-22-unbounded-completion-wakes-by-default.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-22-unbounded-completion-wakes-by-default.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-22-unbounded-completion-wakes-by-default.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-22-unbounded-completion-wakes-by-default.md -2026-09-22-unbounded-completion-wakes-by-default.md: 8760154054de423240e16d93e3db5ae01521820a -2026-09-22-unbounded-completion-wakes-by-default.zh.md: e5560bc7ced5a8ca9ab55ea56ba309676d78b568 +/agent-note-background-job-completion-wakes-are-unbounded-by-default: + en: 5c8e5c0ff2d19ab9 + zh: a046e3297aba3904 +/agent-note-background-job-completion-wakes-are-unbounded-by-default/problem: + en: 32fdd5fa938fc279 + zh: f8f97f806157eea1 +/agent-note-background-job-completion-wakes-are-unbounded-by-default/decision: + en: 7e4ee951808e1860 + zh: 8dad4884d259cdc3 +/agent-note-background-job-completion-wakes-are-unbounded-by-default/alternatives-considered: + en: 62630b7ec477bf7b + zh: 0640a01ac9d22722 +/agent-note-background-job-completion-wakes-are-unbounded-by-default/consequences: + en: ba000076db02ccb7 + zh: 1aa1e7d45d6512fe diff --git a/.agents/notes/implemented/feature/2026-09-23-language-neutral-default-workspace-naming.i18n.yaml b/.agents/notes/implemented/feature/2026-09-23-language-neutral-default-workspace-naming.i18n.yaml new file mode 100644 index 0000000000..3a51c979a3 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-23-language-neutral-default-workspace-naming.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-23-language-neutral-default-workspace-naming.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-23-language-neutral-default-workspace-naming.md +/agent-note-language-neutral-default-workspace-naming: + en: f9065db27c1cd7f9 + zh: 3dd1a223a6fcc6c6 +/agent-note-language-neutral-default-workspace-naming/problem: + en: 35967bed9e895460 + zh: 9cf4da88466ff37c +/agent-note-language-neutral-default-workspace-naming/decision: + en: 72fd5b65bbee5434 + zh: 08a4967a1530e686 +/agent-note-language-neutral-default-workspace-naming/alternatives-considered: + en: 556df0ed81444162 + zh: 5eee5029659419c3 +/agent-note-language-neutral-default-workspace-naming/consequences: + en: 5f710ca9cf60d514 + zh: 9ea7bdaf8925fd44 diff --git a/.agents/notes/implemented/feature/2026-09-23-language-neutral-default-workspace-naming.md b/.agents/notes/implemented/feature/2026-09-23-language-neutral-default-workspace-naming.md new file mode 100644 index 0000000000..7d96f91aef --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-23-language-neutral-default-workspace-naming.md @@ -0,0 +1,36 @@ +# Agent Note: Language-neutral default Workspace naming + +Status: implemented + +English | [中文](2026-09-23-language-neutral-default-workspace-naming.zh.md) + +## Problem + +[First-use default Workspace](2026-09-20-default-workspace.md) let the Client pick both the directory name and the stored title from its startup language: Chinese installations created `默认工作区`, English ones `Default workspace`, everything else `default-workspace`. The name a reader sees and the name written to disk were the same string, so one product decision carried two incompatible requirements. A path is addressed by shell commands, tool arguments, `@path` references, session logs, and backups, and must not depend on which language happened to be active when the installation started. A label is read, and should be in the reader's language. Switching language afterwards satisfied neither: the path was already fixed, and so was the label derived from it. + +## Decision + +The directory name and the stored title are one fixed, language-neutral string; only the on-screen label follows the reader's language. + +`DEFAULT_WORKSPACE_DIRECTORY` (`default-workspace`) is owned by the [Workspace controller](../../../../packages/api/workspace-controller/README.md#first-use-workspace) and published from its own `./default-workspace` subpath — a pure fold with no imports, so client bundles inline it rather than requesting a module-table row the package does not publish. The Host joins it under `/deepseek-harness`, and the registry titles the Workspace after the canonical directory's final segment, so the automatic title *is* that same name with no second source to keep in step. + +`workspace.initializeDefault` therefore takes no request at all; `WorkspaceInitializeDefaultRequest` and its name validation are deleted, and the registry's resolver returns a path instead of a path and title. No language reaches the Host, so nothing there can disagree with the Client about naming. + +Browser consumers label one Workspace through `workspaceDisplayTitle(title, localizedDefault)`: a title still equal to the automatic one reads as the localized default name, and every other title reads verbatim. The name lives in the `common` locale namespace (`workspace.defaultName`) because two packages show it — the Workspace browser resolves it once at the store read so rows, hover card, search meta, and the rename and delete dialogs all inherit it, and the Conversation workspace chip resolves it for the hero. + +A rename is what stops a row following the language, and needs no stored flag: the dialog is seeded with the label on screen while the *stored* title decides whether confirming saves. The two differ for a Workspace still carrying its automatic title, so confirming the untouched prefill is a real rename that pins that name. Self-exclusion in the duplicate check moved to Workspace identity for the same reason — the seeded label equals the row's own displayed title without being a conflict with itself. + +## Alternatives considered + +- Marking the never-renamed state on `WorkspaceView` (a boolean the Host derives from `defaultWorkspaceId` plus the automatic title) removes the false positive below, but widens a shared transport type to carry presentation state the Host has no other use for. Comparing the stored title is the same test with no wire surface. +- Localizing the title inside the Client Workspace store would cover every consumer at one point, but a store that returns product copy owes the locale revision a re-projection and puts copy outside the `t` seat the i18n gate checks. +- Keeping the localized directory name and adding a separate stored title preserves the old path spellings, but leaves every installation's path decided by its first language — the defect this note exists to remove. +- Renaming an existing localized directory on language change would break recorded session `cwd`s, tool arguments, and `@path` references for a cosmetic gain. + +## Consequences + +Installations created before this change keep their existing localized directory and title. Nothing renames or relocates them; their titles no longer match the automatic name, so they read verbatim — which is what a user who never renamed a Chinese installation already saw. + +A Workspace whose stored title is exactly `default-workspace` is labeled as the default even when it is not the registry's default — a folder of that name adopted from the picker, or a rename to that literal. Nothing but the label depends on the distinction. The Workspace browser's client-side duplicate-title check compares localized titles, so it reports a conflict for a second Workspace named the localized default while the Host, comparing stored titles, would allow it; refusing two rows that read identically is the better answer, and the Host still owns the authoritative uniqueness check. + +Two *Session* labels derived from a working directory keep showing the raw path segment, because they name a directory rather than a Workspace: the Session Controller's `displayTitleOf` falls back to the cwd basename for a Session with no durable title, and the sidebar's search-result metadata falls back the same way for a Session with no owning Workspace. Both read `default-workspace` where they previously read the localized name. Routing them through `workspaceDisplayTitle` would spread the automatic-title test into Session naming for a case the Session title generator almost always fills in first. diff --git a/.agents/notes/implemented/feature/2026-09-23-language-neutral-default-workspace-naming.zh.md b/.agents/notes/implemented/feature/2026-09-23-language-neutral-default-workspace-naming.zh.md new file mode 100644 index 0000000000..4095ccf7ac --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-23-language-neutral-default-workspace-naming.zh.md @@ -0,0 +1,36 @@ +# Agent Note: 语言中立的默认工作区命名 + +Status: implemented + +[English](2026-09-23-language-neutral-default-workspace-naming.md) | 中文 + +## Problem + +[首次使用默认工作区](2026-09-20-default-workspace.zh.md)让 Client 按启动语言同时决定目录名和存储标题:中文安装环境创建 `默认工作区`,英文创建 `Default workspace`,其他语言创建 `default-workspace`。读者看到的名称与写入磁盘的名称是同一个字符串,因此一个产品决策承担了两项互不兼容的要求。路径会被 shell 命令、工具参数、`@path` 引用、会话日志和备份寻址,不应取决于安装环境启动时恰好使用哪种语言。标签是给人读的,应当使用读者的语言。事后切换语言两者都无法满足:路径已经固定,由它派生的标签也已固定。 + +## Decision + +目录名与存储标题是同一个固定的、语言中立的字符串;只有屏幕上的标签跟随读者语言。 + +`DEFAULT_WORKSPACE_DIRECTORY`(`default-workspace`)由 [Workspace 控制器](../../../../packages/api/workspace-controller/README.zh.md#first-use-workspace)拥有,并通过其独立的 `./default-workspace` 子路径导出——它是一个没有任何 import 的纯折叠函数,因此 Client 包会内联它,而不是去请求本包并未发布的模块表条目。Host 将它拼接在 `/deepseek-harness` 下,注册表则以规范目录的最后一段作为工作区标题,因此自动标题*就是*同一个名称,不存在需要同步的第二个来源。 + +因此 `workspace.initializeDefault` 完全不接受请求参数;`WorkspaceInitializeDefaultRequest` 及其名称校验被删除,注册表的解析器返回路径而不是路径加标题。语言不会传到 Host,因此那里不可能与 Client 在命名上产生分歧。 + +浏览器消费方通过 `workspaceDisplayTitle(title, localizedDefault)` 为单个工作区加标签:标题仍等于自动标题时显示为本地化的默认名称,其他标题一律原样显示。该名称放在 `common` 语言命名空间(`workspace.defaultName`),因为有两个包展示它——Workspace 浏览区在读取 store 时解析一次,行、悬浮卡片、搜索结果元信息以及重命名与删除对话框都继承该结果;Conversation 的工作区 chip 则为 hero 自行解析。 + +让某一行不再跟随语言的动作就是重命名,无需额外存储标记:对话框以屏幕上的标签作为初值,而判断确认是否需要保存用的是*存储*标题。对于仍保留自动标题的工作区两者不同,因此直接确认未改动的初值就是一次真实的重命名,会把该名称固定下来。重名检查中排除自身也因此改为按工作区身份判断——初值标签与该行自己显示的标题相同,但这并不构成与自身的冲突。 + +## Alternatives considered + +- 在 `WorkspaceView` 上标记"从未重命名"状态(由 Host 依据 `defaultWorkspaceId` 与自动标题推导的布尔值)可以消除下述误判,但会让一个共享的传输类型多承载一项 Host 本身别无用途的展示状态。比较存储标题是同一项判断,且不增加 wire 表面。 +- 在 Client Workspace store 内部本地化标题可以一处覆盖所有消费方,但返回产品文案的 store 需要在语言修订变化时重新投影,而且会把文案放到 i18n 门禁检查的 `t` 座位之外。 +- 保留本地化目录名并另存一个标题可以保住旧路径拼写,但每个安装环境的路径仍由其首个语言决定——正是本笔记要消除的缺陷。 +- 在语言切换时重命名已有的本地化目录,会为了外观收益破坏已记录的会话 `cwd`、工具参数和 `@path` 引用。 + +## Consequences + +本次改动之前创建的安装环境保留其既有的本地化目录和标题。不会有任何重命名或迁移;它们的标题不再与自动名称相同,因此原样显示——这与从未重命名过中文安装环境的用户已经看到的结果一致。 + +存储标题恰好为 `default-workspace` 的工作区会按默认工作区显示,即使它并非注册表的默认工作区——例如从选择器采用的同名文件夹,或被重命名为该字面值。除标签之外没有其他行为依赖该判断。Workspace 浏览区在 Client 侧的重名检查比较的是本地化标题,因此当第二个工作区被命名为本地化默认名称时它会报冲突,而按存储标题比较的 Host 会允许;拒绝两行显示完全相同的名称是更好的答案,权威的唯一性检查仍由 Host 拥有。 + +有两处由工作目录派生的 *Session* 标签仍显示原始路径片段,因为它们命名的是目录而非工作区:Session Controller 的 `displayTitleOf` 在 Session 没有持久标题时回退到 cwd 最后一段,侧栏搜索结果的元信息在 Session 没有所属工作区时同样回退。两处此前显示本地化名称,现在显示 `default-workspace`。把它们接入 `workspaceDisplayTitle` 会把自动标题判断扩散进 Session 命名,而这种情形几乎总会先被 Session 标题生成填上。 diff --git a/.agents/notes/implemented/feature/2026-09-24-auto-review-user-approval-fallback.i18n.yaml b/.agents/notes/implemented/feature/2026-09-24-auto-review-user-approval-fallback.i18n.yaml new file mode 100644 index 0000000000..21a2a83f53 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-24-auto-review-user-approval-fallback.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-24-auto-review-user-approval-fallback.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-24-auto-review-user-approval-fallback.md +/agent-note-auto-review-asks-the-user-after-a-denial: + en: 5591f8e34bda222a + zh: 7d433ca541e6988f +/agent-note-auto-review-asks-the-user-after-a-denial/problem: + en: ed725dff16cd2339 + zh: 555d4ba70af96790 +/agent-note-auto-review-asks-the-user-after-a-denial/decision: + en: 4782a7609717bac3 + zh: f3ebb3581b807f3f +/agent-note-auto-review-asks-the-user-after-a-denial/alternatives-considered: + en: 01f71dd10849f925 + zh: 8b79a7e149a9a60c +/agent-note-auto-review-asks-the-user-after-a-denial/consequences: + en: 822a4241ddf39448 + zh: dd05997932eed142 diff --git a/.agents/notes/implemented/feature/2026-09-24-auto-review-user-approval-fallback.md b/.agents/notes/implemented/feature/2026-09-24-auto-review-user-approval-fallback.md new file mode 100644 index 0000000000..c9d4cda11b --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-24-auto-review-user-approval-fallback.md @@ -0,0 +1,33 @@ +# Agent Note: Auto review asks the user after a denial + +Status: implemented + +English | [中文](2026-09-24-auto-review-user-approval-fallback.zh.md) + +## Problem + +[Auto review](2026-08-28-auto-review.md) made every reviewer denial final and reported every reviewer failure as that same denial. A person watching the Session had no way to let a denied call run, even when the reviewer misjudged an action the person wanted, so the only recovery was to switch the whole Session to Full access. A malformed reviewer response, a provider error, or a missing Session fact reached the model and the user as `Auto review rejected tool ""`, so neither could tell a policy decision from a technical failure or act on the cause. + +## Decision + +A reviewer denial returns the tools pipeline's existing `ask` decision when the Session's approval policy is `ask`. `ToolRuntime` sends it through the approval service with the reason `Auto review denied tool ""`, followed by `: ` when the reviewer gave one. `allowed-once` executes the call; `rejected`, `cancelled`, and `unavailable` deny it through the approval service's ordinary messages, and the body does not run. The listener asks only after later `tools/pre-execute` listeners allow the call, so a downstream denial or cancellation wins without prompting. + +Selecting Auto writes `danger-full-access` with the `ask` approval policy. A recorded Auto selection also matches the `never` policy. A [delegated in-process child pins `never`](2026-08-10-subagent-approval-pinned-never.md), so a child Auto keeps the final `AutoReviewDeniedError` denial and its reason, and a Session recorded under the earlier `never` bundle still resolves to Auto instead of Full access. Selecting Auto again writes `ask`. + +A reviewer failure denies the call with `Auto review of tool "" failed; its body was not executed: ` and no structured error info. A provider failure's message carries the finish kind, failure code, and provider message, so the model and the generic tool card show the actual cause. + +## Alternatives considered + +**Ask the user after every reviewer failure too.** A failure says nothing about the action's risk; asking would present a technical error as a policy question and would hide a broken reviewer route behind repeated prompts. + +**Always return `ask` and let the `never` policy reject it.** The approval service reports that rejection as `the user rejected tool ""`, which is false for a child, and it drops the reviewer's reason. + +**Keep Auto on `never` and let the reviewer bypass the approval policy.** The approval service enforces `never` before any answerer so no listener can bypass it; the model-context policy text would also tell the main agent that no approval can happen. + +## Consequences + +- An interactive Auto Session can pause on an approval prompt, so Auto no longer guarantees unattended progress. +- The raw reviewer reason is visible to the user in the approval prompt and the approval audit events; the main model sees only the approval outcome. +- A reviewer failure's text, including provider messages, becomes model-visible tool error content. +- Switching between Auto and Full access now also changes the approval policy, so the live-agent switch path queues the approval-policy change notice. +- Unit tests cover the approval outcomes, the downstream-denial ordering, the child `never` path, and the specific failure messages; the shipped Web composition test covers a user rejection after a real reviewer denial. diff --git a/.agents/notes/implemented/feature/2026-09-24-auto-review-user-approval-fallback.zh.md b/.agents/notes/implemented/feature/2026-09-24-auto-review-user-approval-fallback.zh.md new file mode 100644 index 0000000000..7d901b75fb --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-24-auto-review-user-approval-fallback.zh.md @@ -0,0 +1,33 @@ +# Agent Note: Auto review 拒绝后请求用户审批 + +Status: implemented + +[English](2026-09-24-auto-review-user-approval-fallback.md) | 中文 + +## Problem + +[Auto review](2026-08-28-auto-review.zh.md) 把每次 reviewer 拒绝都当作最终结果,并把每次 reviewer 失败也报告为同样的拒绝。旁观 Session 的人无法让被拒绝的调用继续执行,即使 reviewer 误判了此人想要的动作;唯一的补救是把整个 Session 切换到 Full access。Reviewer 响应不合法、provider 出错或 Session 事实缺失时,模型与用户看到的都是 `Auto review rejected tool ""`,因此两者都无法区分策略决定与技术失败,也无法针对原因采取行动。 + +## Decision + +当 Session 的审批策略为 `ask` 时,reviewer 拒绝返回 tools 流水线既有的 `ask` 决定。`ToolRuntime` 通过审批服务发送该请求,理由为 `Auto review denied tool ""`;reviewer 给出理由时再追加 `: `。`allowed-once` 执行调用;`rejected`、`cancelled` 与 `unavailable` 通过审批服务的普通消息拒绝调用,body 不执行。只有后续 `tools/pre-execute` listener 放行调用后,listener 才请求审批,因此下游拒绝或取消优先且不弹出审批。 + +选择 Auto 会写入 `danger-full-access` 与 `ask` 审批策略。已记录的 Auto 选择也匹配 `never` 策略。[进程内委派 child 固定 `never`](2026-08-10-subagent-approval-pinned-never.zh.md),因此 child 的 Auto 保留最终的 `AutoReviewDeniedError` 拒绝及其理由;按先前 `never` 组合记录的 Session 仍解析为 Auto,而不是 Full access。再次选择 Auto 会写入 `ask`。 + +Reviewer 失败以 `Auto review of tool "" failed; its body was not executed: ` 拒绝调用,不带结构化错误信息。Provider 失败消息包含 finish 类型、失败代码与 provider 消息,因此模型与通用工具卡片显示实际原因。 + +## Alternatives considered + +**Reviewer 失败后也请求用户审批。** 失败不说明动作风险;请求审批会把技术错误呈现为策略问题,并用反复弹出的审批掩盖损坏的 reviewer 路由。 + +**始终返回 `ask`,由 `never` 策略拒绝。** 审批服务把该拒绝报告为 `the user rejected tool ""`,这对 child 不成立,而且会丢失 reviewer 理由。 + +**Auto 保持 `never`,由 reviewer 绕过审批策略。** 审批服务在任何应答者之前执行 `never`,因此没有 listener 能绕过它;模型上下文中的策略文本也会告诉主 agent 不可能发生审批。 + +## Consequences + +- 交互式 Auto Session 可能停在审批提示上,因此 Auto 不再保证无人值守地推进。 +- 用户可以在审批提示与审批审计事件中看到原始 reviewer 理由;主模型只看到审批结果。 +- Reviewer 失败文本(包括 provider 消息)成为模型可见的工具错误内容。 +- 在 Auto 与 Full access 之间切换现在也会改变审批策略,因此存活 agent 的切换路径会排入审批策略变更通知。 +- 单元测试覆盖各审批结果、下游拒绝的先后顺序、child 的 `never` 路径以及具体失败消息;shipped Web 组合测试覆盖真实 reviewer 拒绝之后的用户拒绝。 diff --git a/.agents/notes/implemented/feature/2026-09-24-fixed-rate-floor-one-minute.i18n.yaml b/.agents/notes/implemented/feature/2026-09-24-fixed-rate-floor-one-minute.i18n.yaml new file mode 100644 index 0000000000..7ed8eaaa55 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-24-fixed-rate-floor-one-minute.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-24-fixed-rate-floor-one-minute.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-24-fixed-rate-floor-one-minute.md +/agent-note-one-minute-fixed-rate-floor: + en: d74434992e0ca252 + zh: cae88d61368d5555 +/agent-note-one-minute-fixed-rate-floor/problem: + en: a16373df16ee9126 + zh: 10e86f4cfe0e9a11 +/agent-note-one-minute-fixed-rate-floor/decision: + en: fb49d104c6539934 + zh: 04655695ccbb58c6 +/agent-note-one-minute-fixed-rate-floor/alternatives-considered: + en: 080ae22387dd35b7 + zh: 8247747dc444d7a4 +/agent-note-one-minute-fixed-rate-floor/consequences: + en: c11eac4968a2a707 + zh: c4a02ddeef3a5dff diff --git a/.agents/notes/implemented/feature/2026-09-24-fixed-rate-floor-one-minute.md b/.agents/notes/implemented/feature/2026-09-24-fixed-rate-floor-one-minute.md new file mode 100644 index 0000000000..77fffc7813 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-24-fixed-rate-floor-one-minute.md @@ -0,0 +1,29 @@ +# Agent Note: One-minute fixed-rate floor + +Status: implemented + +English | [中文](2026-09-24-fixed-rate-floor-one-minute.zh.md) + +## Problem + +`every_seconds` refused every interval below 300 seconds, and the Web client restated that bound as its own per-unit floors of 1 hour, 5 minutes, or 300 seconds. The same product already offered a `cron` selector whose finest granularity is one minute, so two selectors that both describe a repeating cadence disagreed about the shortest one a person could ask for: a reminder that repeats every minute was expressible as `cron` and rejected as `every_seconds`. The floor also made a shipped default Web surface awkward to try, because the first repeating reminder anyone creates cannot come back in under five minutes. + +## Decision + +`MIN_EVERY_INTERVAL_SECONDS` in `packages/schedule/schedule/src/domain.ts` is 60. The Host decoder, the create and update validation, the `every_seconds` tool parameter description, and its refusal message all read that constant, so one change moves the bound everywhere the Host states it. + +The client keeps its own `MIN_INTERVAL_SECONDS = 60`, which the Run time card uses for the seconds row and to derive the per-unit floors: 1 hour, 1 minute, or 60 seconds. The localized hint and refusal copy states 1 minute and 60 seconds for those rows. + +One minute is the shortest cadence that does not need a new protocol decision: it matches the cron selector's granularity, and every accepted value remains a whole-second interval the durable record already stores. A stored record keeps whatever the Host accepted when it was created; a record written under the old bound (300 seconds or more) stays valid and replayable, and no migration runs because the previous bound rejected anything below it. + +## Alternatives considered + +**Keep the 300-second floor.** The two selectors would keep disagreeing about the shortest repeating cadence, and a person could still reach a one-minute cadence only through `cron`. + +**Lower the bound to one second.** Sub-minute intervals multiply durable follow-up messages and timer re-anchoring per reminder without a request behind them; the minute granularity already covers the shortest cadence the product names elsewhere. + +## Consequences + +- A fixed-rate reminder may now repeat every minute; the smallest accepted value is model-visible in the `every_seconds` description and in the client's hint copy. +- Delivery behavior, batching, catch-up, and the interval arithmetic are unchanged: an accepted interval still anchors to creation or to the accepted save, and each overdue record still contributes only its latest occurrence. +- A deployment cannot raise the floor through configuration; the bound is a protocol constant, so a deployment that needs a longer minimum enforces it in the interface that creates tasks. diff --git a/.agents/notes/implemented/feature/2026-09-24-fixed-rate-floor-one-minute.zh.md b/.agents/notes/implemented/feature/2026-09-24-fixed-rate-floor-one-minute.zh.md new file mode 100644 index 0000000000..6d103be09b --- /dev/null +++ b/.agents/notes/implemented/feature/2026-09-24-fixed-rate-floor-one-minute.zh.md @@ -0,0 +1,29 @@ +# Agent Note: 固定速率下限改为 1 分钟 + +Status: implemented + +[English](2026-09-24-fixed-rate-floor-one-minute.md) | 中文 + +## Problem + +`every_seconds` 会拒绝所有低于 300 秒的间隔,Web 客户端也把该下限复述为自己按单位计算的下限:1 小时、5 分钟或 300 秒。同一产品已经提供粒度为 1 分钟的 `cron` 选择器,于是两个都在描述重复节奏的选择器对「最短能填多少」给出了不同答案:每分钟重复一次的提醒用 `cron` 可以表达,用 `every_seconds` 会被拒绝。该下限也让默认发布 Schedule 的 Web 界面难以试用——任何人创建的第一条重复提醒都不可能在五分钟内回到。 + +## Decision + +`packages/schedule/schedule/src/domain.ts` 的 `MIN_EVERY_INTERVAL_SECONDS` 为 60。宿主解码器、创建与更新校验、`every_seconds` 工具参数描述及其拒绝消息都读取该常量,因此一处改动即可移动宿主陈述该下限的所有位置。 + +客户端保留自己的 `MIN_INTERVAL_SECONDS = 60`,「运行时间」卡片用它校验秒数行,并据此推导各单位的数量下限:1 小时、1 分钟或 60 秒。对应行的本地化提示与拒绝文案改为 1 分钟与 60 秒。 + +1 分钟是无需新增协议决策的最短节奏:它与 cron 选择器的粒度一致,且每个被接受的值仍是以整秒表示的间隔,持久记录本来就以整秒存储。已存储的记录保留宿主当初接受的值:按旧下限(300 秒及以上)写入的记录仍然有效、仍可回放;由于旧下限拒绝了低于它的值,因此不存在需要迁移的数据。 + +## Alternatives considered + +**保留下限 300 秒。** 两个选择器会继续对最短重复节奏给出不同答案,而每分钟一次的节奏仍只能通过 `cron` 达到。 + +**把下限降到 1 秒。** 低于分钟级的间隔会让每条提醒产生更多持久 follow-up 消息与 timer 重新对齐,而背后没有这样的需求;分钟粒度已经覆盖产品在别处命名的最短节奏。 + +## Consequences + +- 固定速率提醒现在可以每分钟重复一次;最小可接受值对模型可见,出现在 `every_seconds` 的描述与客户端的提示文案中。 +- 投递行为、批处理、补跑与间隔运算法则不变:被接受的间隔仍以创建时刻或接受保存的时刻为起算点,每条逾期记录仍只贡献最新一次发生时点。 +- 部署无法通过配置提高该下限;它是协议常量,需要更长最小间隔的部署应在创建任务的界面上自行约束。 diff --git a/.agents/notes/implemented/process/2026-06-11-quality-gates.i18n.yaml b/.agents/notes/implemented/process/2026-06-11-quality-gates.i18n.yaml index 5dedd0a1fb..515c9508fd 100644 --- a/.agents/notes/implemented/process/2026-06-11-quality-gates.i18n.yaml +++ b/.agents/notes/implemented/process/2026-06-11-quality-gates.i18n.yaml @@ -1,6 +1,16 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-11-quality-gates.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-06-11-quality-gates.md -2026-06-11-quality-gates.md: b4bcbcbb6e47ccbb3ed193300c4a8b2daa3901c0 -2026-06-11-quality-gates.zh.md: 64179fd7b13bf5de3d82bf9bf8819f6230b46238 +/agent-note-mechanical-quality-gates-over-prose-guidelines: + en: ee219fd65689e5ea + zh: a5eb719557f02ad6 +/agent-note-mechanical-quality-gates-over-prose-guidelines/problem: + en: 526b060333ea2457 + zh: 182f46699589aff5 +/agent-note-mechanical-quality-gates-over-prose-guidelines/decision: + en: c6d1551e56d22b99 + zh: 6b7efc184274b7ac +/agent-note-mechanical-quality-gates-over-prose-guidelines/consequences: + en: 7bf0c081f242501e + zh: 30f892fbd982f1b2 diff --git a/.agents/notes/implemented/process/2026-06-16-pnpm-over-yarn.i18n.yaml b/.agents/notes/implemented/process/2026-06-16-pnpm-over-yarn.i18n.yaml index 2a7d105492..d4354efa31 100644 --- a/.agents/notes/implemented/process/2026-06-16-pnpm-over-yarn.i18n.yaml +++ b/.agents/notes/implemented/process/2026-06-16-pnpm-over-yarn.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-16-pnpm-over-yarn.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-06-16-pnpm-over-yarn.md -2026-06-16-pnpm-over-yarn.md: 4a8560a0216e614f4ea06c0a1aac3a553abcaf8d -2026-06-16-pnpm-over-yarn.zh.md: 4955cf88834a56d89ba1c4c1866c72cf647ccbd3 +/agent-note-pnpm-as-the-package-manager-instead-of-yarn-4: + en: 2c8be5b7d3dae8c7 + zh: e6d4d5dc41455f52 +/agent-note-pnpm-as-the-package-manager-instead-of-yarn-4/problem: + en: a397e5f0a83c3306 + zh: 5ced99f94dae9e30 +/agent-note-pnpm-as-the-package-manager-instead-of-yarn-4/decision: + en: cadbbd8b1bab85ef + zh: 31fcb11ddbcb79c3 +/agent-note-pnpm-as-the-package-manager-instead-of-yarn-4/alternatives-considered: + en: 20e2ebed65f92625 + zh: f1717d69d271fb43 +/agent-note-pnpm-as-the-package-manager-instead-of-yarn-4/consequences: + en: 024fefe88e8bbc95 + zh: 018dc287c07d6483 diff --git a/.agents/notes/implemented/process/2026-06-17-ts-build-config.i18n.yaml b/.agents/notes/implemented/process/2026-06-17-ts-build-config.i18n.yaml index 6ee41d8ba1..3d3e5e065d 100644 --- a/.agents/notes/implemented/process/2026-06-17-ts-build-config.i18n.yaml +++ b/.agents/notes/implemented/process/2026-06-17-ts-build-config.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-17-ts-build-config.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-06-17-ts-build-config.md -2026-06-17-ts-build-config.md: 05b70cb836491e8a3e6c66deb38773b5351e69e8 -2026-06-17-ts-build-config.zh.md: d42d9b7abe6368b3ed8e0f32605e866e214f1e7c +/agent-note-tsc-first-build-and-one-compiler-ownership: + en: 98c341593a211f00 + zh: 5c051e3aaff4847e +/agent-note-tsc-first-build-and-one-compiler-ownership/problem: + en: 62307ddfb9e110cb + zh: 236bdad7df92a028 +/agent-note-tsc-first-build-and-one-compiler-ownership/decision: + en: e2b61f1e0549117d + zh: 596ca8cf8207f2b5 +/agent-note-tsc-first-build-and-one-compiler-ownership/alternatives-considered: + en: 9b143ba610f06e2f + zh: 7832be7816aec7e6 +/agent-note-tsc-first-build-and-one-compiler-ownership/consequences: + en: 05b0f4a3a96e9435 + zh: 2903da5edbaf3cb7 diff --git a/.agents/notes/implemented/process/2026-06-17-ts-build-config.md b/.agents/notes/implemented/process/2026-06-17-ts-build-config.md index 05b70cb836..5b40ba01a0 100644 --- a/.agents/notes/implemented/process/2026-06-17-ts-build-config.md +++ b/.agents/notes/implemented/process/2026-06-17-ts-build-config.md @@ -48,6 +48,7 @@ The command orchestration shape is: pnpm run build: tsc -b tsconfig.host.json tsdown --env.DSH_BUILD_FACE host +pnpm --filter @deepseek-ai/dsh-desktop run bundle tsc -b tsconfig.client.json tsdown --env.DSH_BUILD_FACE client pnpm run build:web diff --git a/.agents/notes/implemented/process/2026-06-17-ts-build-config.zh.md b/.agents/notes/implemented/process/2026-06-17-ts-build-config.zh.md index d42d9b7abe..c250cdd831 100644 --- a/.agents/notes/implemented/process/2026-06-17-ts-build-config.zh.md +++ b/.agents/notes/implemented/process/2026-06-17-ts-build-config.zh.md @@ -48,6 +48,7 @@ Status: implemented pnpm run build: tsc -b tsconfig.host.json tsdown --env.DSH_BUILD_FACE host +pnpm --filter @deepseek-ai/dsh-desktop run bundle tsc -b tsconfig.client.json tsdown --env.DSH_BUILD_FACE client pnpm run build:web diff --git a/.agents/notes/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml b/.agents/notes/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml index 213fa7b96a..59b17b44ff 100644 --- a/.agents/notes/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-02-bilingual-docs-and-pairing-gate.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.md -2026-07-02-bilingual-docs-and-pairing-gate.md: 9448c9dcd75cae0ab39fd62b418fd3aa3b5e4484 -2026-07-02-bilingual-docs-and-pairing-gate.zh.md: b843de91e2fb92d05c81387f49853c4ca413228f +/agent-note-bilingual-documentation-via-paired-sibling-files-and-a-pairing-gate: + en: 04529b9cc16be36d + zh: 5fb4377453231503 +/agent-note-bilingual-documentation-via-paired-sibling-files-and-a-pairing-gate/problem: + en: 0ca5c6556229e3ee + zh: 6dacd60a7dc4bff4 +/agent-note-bilingual-documentation-via-paired-sibling-files-and-a-pairing-gate/decision: + en: 46b0ca2b0f45eb6c + zh: 3ddcd36e9ef8d134 +/agent-note-bilingual-documentation-via-paired-sibling-files-and-a-pairing-gate/verification: + en: 8fbf681b863a831c + zh: e5ba11a549a92612 +/agent-note-bilingual-documentation-via-paired-sibling-files-and-a-pairing-gate/alternatives-considered: + en: 995a746c59ea7b6c + zh: 04a248329dc0d04b +/agent-note-bilingual-documentation-via-paired-sibling-files-and-a-pairing-gate/industry-precedent: + en: 6b5d62086bfd3868 + zh: 219dad72943f590a +/agent-note-bilingual-documentation-via-paired-sibling-files-and-a-pairing-gate/consequences: + en: 65f9f024d99d438f + zh: ff624c8be88c5830 diff --git a/.agents/notes/implemented/process/2026-07-04-doc-tiers-and-budgets.i18n.yaml b/.agents/notes/implemented/process/2026-07-04-doc-tiers-and-budgets.i18n.yaml index 06f10621ec..e72a4d0af7 100644 --- a/.agents/notes/implemented/process/2026-07-04-doc-tiers-and-budgets.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-04-doc-tiers-and-budgets.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-04-doc-tiers-and-budgets.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-04-doc-tiers-and-budgets.md -2026-07-04-doc-tiers-and-budgets.md: 209504218d18e97ae6da65bed9a22da40d2a7681 -2026-07-04-doc-tiers-and-budgets.zh.md: 9c866424d84b4fefa5ffe95efa21a3cf7d3c321a +/agent-note-documentation-structure-tiers-and-budgets: + en: f2add84f6fdb18d0 + zh: 7f97fab8f9234bb9 +/agent-note-documentation-structure-tiers-and-budgets/problem: + en: 6ecec6cc312745dd + zh: ac1244b6113b89da +/agent-note-documentation-structure-tiers-and-budgets/decision: + en: 8a3a2e086af59a6c + zh: d1d45a4a108031a2 +/agent-note-documentation-structure-tiers-and-budgets/alternatives-considered: + en: 8275e8f6ffe18def + zh: 06a5af3e5581f45b +/agent-note-documentation-structure-tiers-and-budgets/consequences: + en: 76c254b56618cef6 + zh: 1f1264d6879df20c diff --git a/.agents/notes/implemented/process/2026-07-05-uniform-agent-note-format.i18n.yaml b/.agents/notes/implemented/process/2026-07-05-uniform-agent-note-format.i18n.yaml index 95a5b0ee27..c860b4f1d3 100644 --- a/.agents/notes/implemented/process/2026-07-05-uniform-agent-note-format.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-05-uniform-agent-note-format.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-05-uniform-agent-note-format.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-05-uniform-agent-note-format.md -2026-07-05-uniform-agent-note-format.md: c05d81c700b81f0d619173a261f405b1cc039df1 -2026-07-05-uniform-agent-note-format.zh.md: 13991632e70cfab1c65170ba5f2350f47ad1acd0 +/agent-note-one-gated-in-file-format-for-agent-notes: + en: 1d02708a467f4a07 + zh: 3c924198ec72c881 +/agent-note-one-gated-in-file-format-for-agent-notes/problem: + en: 71bd2d16e40c3ed7 + zh: 485862218afcdc00 +/agent-note-one-gated-in-file-format-for-agent-notes/decision: + en: 246ec96b0c1da90d + zh: 12a06608ffdf28f8 +/agent-note-one-gated-in-file-format-for-agent-notes/alternatives-considered: + en: 330044b841da3ab9 + zh: e909207cbcbc5edb +/agent-note-one-gated-in-file-format-for-agent-notes/consequences: + en: 345e6318b76b1a06 + zh: 63cef25e59d91654 diff --git a/.agents/notes/implemented/process/2026-07-06-node-engine-floor.i18n.yaml b/.agents/notes/implemented/process/2026-07-06-node-engine-floor.i18n.yaml index 5687bcd853..18ab194298 100644 --- a/.agents/notes/implemented/process/2026-07-06-node-engine-floor.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-06-node-engine-floor.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-06-node-engine-floor.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-06-node-engine-floor.md -2026-07-06-node-engine-floor.md: e2fe7661f43b77f544de2c3a555e5d756f260ea2 -2026-07-06-node-engine-floor.zh.md: e7d41e81281aa1d335780cf4edd65749ccb1db84 +/agent-note-raise-the-node-lts-engine-floor-to-22-19: + en: 01f43f2b4c6bd4fa + zh: 7f34e5b3c1c55419 +/agent-note-raise-the-node-lts-engine-floor-to-22-19/problem: + en: d7bf1b1699ce0dc8 + zh: f10dfd0e4787bb44 +/agent-note-raise-the-node-lts-engine-floor-to-22-19/decision: + en: 0051c0d8c1948f63 + zh: cbab7aa0f53f7200 +/agent-note-raise-the-node-lts-engine-floor-to-22-19/consequences: + en: 0b9fbe932d9a8b1f + zh: 642e19d06caecef2 +/agent-note-raise-the-node-lts-engine-floor-to-22-19/alternatives-considered: + en: c433389b2064eaf9 + zh: 57de2af812def1c4 diff --git a/.agents/notes/implemented/process/2026-07-06-parallel-pre-push-gates.i18n.yaml b/.agents/notes/implemented/process/2026-07-06-parallel-pre-push-gates.i18n.yaml index 482b7bc689..60dff04b5b 100644 --- a/.agents/notes/implemented/process/2026-07-06-parallel-pre-push-gates.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-06-parallel-pre-push-gates.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-06-parallel-pre-push-gates.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-06-parallel-pre-push-gates.md -2026-07-06-parallel-pre-push-gates.md: 9773a86428545608d184112ec4ab95136d4690d0 -2026-07-06-parallel-pre-push-gates.zh.md: 4d0e15a3389d276ea4b1c51224c96b864b0958a0 +/agent-note-parallel-pre-push-gates: + en: d5ee83ee15159e15 + zh: 07a6599af21d98a9 +/agent-note-parallel-pre-push-gates/problem: + en: 896ffdae7d51cc19 + zh: eed0d7e80456bd8e +/agent-note-parallel-pre-push-gates/decision: + en: c95d213689164ad6 + zh: da85165d13b26d58 +/agent-note-parallel-pre-push-gates/verification: + en: c7124c68afb12a8e + zh: 0a0269476ae353f3 +/agent-note-parallel-pre-push-gates/alternatives-considered: + en: d54f4ed806116b2e + zh: 38725684130bb843 +/agent-note-parallel-pre-push-gates/consequences: + en: 5d22505a7c041e41 + zh: ba1010f18d3e8302 diff --git a/.agents/notes/implemented/process/2026-07-12-package-model-experience-contract.i18n.yaml b/.agents/notes/implemented/process/2026-07-12-package-model-experience-contract.i18n.yaml index 1d988cd081..0496ff4408 100644 --- a/.agents/notes/implemented/process/2026-07-12-package-model-experience-contract.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-12-package-model-experience-contract.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-12-package-model-experience-contract.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-12-package-model-experience-contract.md -2026-07-12-package-model-experience-contract.md: 8462cc20e8de43927cd04b73cfdb11a0c3d77336 -2026-07-12-package-model-experience-contract.zh.md: 040412f3afe4f5854d1945a6e638d6a517464f7f +/agent-note-package-model-experience-contract: + en: c14f97f66251831b + zh: a7ef93d593a72215 +/agent-note-package-model-experience-contract/problem: + en: 69034b9a9ba40d49 + zh: 016b64cb54c4c873 +/agent-note-package-model-experience-contract/decision: + en: f67c13ad41004520 + zh: 28cf10f7d217f626 +/agent-note-package-model-experience-contract/alternatives-considered: + en: 206bc943c04313b1 + zh: 6d295d9da6675854 +/agent-note-package-model-experience-contract/consequences: + en: dc6057b8836bb3fc + zh: 6e41a27a99ae0339 diff --git a/.agents/notes/implemented/process/2026-07-19-remove-generated-agent-note-index.i18n.yaml b/.agents/notes/implemented/process/2026-07-19-remove-generated-agent-note-index.i18n.yaml index 7b91c29627..42524fde30 100644 --- a/.agents/notes/implemented/process/2026-07-19-remove-generated-agent-note-index.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-19-remove-generated-agent-note-index.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-remove-generated-agent-note-index.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-19-remove-generated-agent-note-index.md -2026-07-19-remove-generated-agent-note-index.md: 60dba14064ffe294228968cdb111920696fe7d63 -2026-07-19-remove-generated-agent-note-index.zh.md: 912aea133068a727856475df21516a28b2d27876 +/agent-note-keep-agent-notes-discoverable-without-a-generated-index: + en: aedcead60a29472a + zh: 0b17ad37acb4a92e +/agent-note-keep-agent-notes-discoverable-without-a-generated-index/problem: + en: 8a66ca1096aab8f4 + zh: f9774f5f3e7d0a31 +/agent-note-keep-agent-notes-discoverable-without-a-generated-index/decision: + en: 2b02e79f20d9be1b + zh: 5dec073afcee9c2e +/agent-note-keep-agent-notes-discoverable-without-a-generated-index/alternatives-considered: + en: 0317d3d10b97f004 + zh: 9315c31a17f7057a +/agent-note-keep-agent-notes-discoverable-without-a-generated-index/consequences: + en: 631728aa0d482555 + zh: 910a749ae88d4c83 diff --git a/.agents/notes/implemented/process/2026-07-19-web-styling-system.i18n.yaml b/.agents/notes/implemented/process/2026-07-19-web-styling-system.i18n.yaml index f9fe8dd6ff..7889068a5c 100644 --- a/.agents/notes/implemented/process/2026-07-19-web-styling-system.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-19-web-styling-system.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-web-styling-system.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-19-web-styling-system.md -2026-07-19-web-styling-system.md: b4d647924ab6ab172cd7a7e2531a10a2a7e62981 -2026-07-19-web-styling-system.zh.md: e7384575cf69099c8a95610f61c85b5bcb80d300 +/agent-note-web-styling-system-the-token-framework-and-engineering-constraints: + en: 60e793c38185c08c + zh: 8f4d4644e3502c31 +/agent-note-web-styling-system-the-token-framework-and-engineering-constraints/problem: + en: aa546850f8c51cd1 + zh: bba14f66aaf1e06a +/agent-note-web-styling-system-the-token-framework-and-engineering-constraints/decision: + en: 72a1d3545d1ebd6d + zh: f2fdc9006468aa72 +/agent-note-web-styling-system-the-token-framework-and-engineering-constraints/engineering-constraints: + en: 39f1984d96e609ed + zh: 14eda6caf43c5514 +/agent-note-web-styling-system-the-token-framework-and-engineering-constraints/the-execution-shape-for-agents: + en: 10342491b9dcc1a7 + zh: cd23d8c2f8ef3d26 +/agent-note-web-styling-system-the-token-framework-and-engineering-constraints/division-of-labor-with-web-styling-md: + en: 91e06333e11b1417 + zh: c743f392dbd9391f +/agent-note-web-styling-system-the-token-framework-and-engineering-constraints/consequences: + en: 128333a6495cbfa0 + zh: f165ef2f3d76f216 +/agent-note-web-styling-system-the-token-framework-and-engineering-constraints/alternatives-considered: + en: 6579ca659b112618 + zh: f1a650f4af1b8cc2 diff --git a/.agents/notes/implemented/process/2026-07-20-gui-testing-system.i18n.yaml b/.agents/notes/implemented/process/2026-07-20-gui-testing-system.i18n.yaml index 8d3f060672..d91e7a4590 100644 --- a/.agents/notes/implemented/process/2026-07-20-gui-testing-system.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-20-gui-testing-system.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-20-gui-testing-system.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-20-gui-testing-system.md -2026-07-20-gui-testing-system.md: 3fdb9a596dd18861ea8b765da129656942778f96 -2026-07-20-gui-testing-system.zh.md: e49d5a2f848e7f4847c7761ee0a487ce6fd3220e +/agent-note-gui-testing-system-the-three-tier-structure: + en: 66959d1c7c3cad28 + zh: 1e29f27d36c45909 +/agent-note-gui-testing-system-the-three-tier-structure/problem: + en: 1c54e58ea993ef6a + zh: 73108687fa58a6f2 +/agent-note-gui-testing-system-the-three-tier-structure/decision: + en: 4c6e52549113c2c7 + zh: 586175edee8b128c +/agent-note-gui-testing-system-the-three-tier-structure/lane-map: + en: 81d53390f31e540e + zh: 272a2b2b93269c45 +/agent-note-gui-testing-system-the-three-tier-structure/anti-regression-discipline: + en: 80fe1589a6236740 + zh: 30e1911d37865c49 +/agent-note-gui-testing-system-the-three-tier-structure/consequences: + en: 22f2475a438c639c + zh: aafab5ff60b7c644 +/agent-note-gui-testing-system-the-three-tier-structure/alternatives-considered: + en: 19e29023b70018b0 + zh: d47ff8e62a0befb6 diff --git a/.agents/notes/implemented/process/2026-07-21-serial-cross-platform-ci-reference.i18n.yaml b/.agents/notes/implemented/process/2026-07-21-serial-cross-platform-ci-reference.i18n.yaml index 2ce7922815..42a4a26dc0 100644 --- a/.agents/notes/implemented/process/2026-07-21-serial-cross-platform-ci-reference.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-21-serial-cross-platform-ci-reference.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-21-serial-cross-platform-ci-reference.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-21-serial-cross-platform-ci-reference.md -2026-07-21-serial-cross-platform-ci-reference.md: 24022fea271d677a4588bd5dc9c7cb5b417ca8b7 -2026-07-21-serial-cross-platform-ci-reference.zh.md: c9fbc84d8ff91803acc6bcd008607fc03136b832 +/agent-note-serial-cross-platform-ci-reference: + en: 4dd700fefdda5d17 + zh: 3a6a9bc2a28b3f39 +/agent-note-serial-cross-platform-ci-reference/problem: + en: 4fb1c27a631b32d3 + zh: 9dbe9a4b9aadfca9 +/agent-note-serial-cross-platform-ci-reference/decision: + en: f547014d316c1385 + zh: f13b09a4a778adaa +/agent-note-serial-cross-platform-ci-reference/alternatives-considered: + en: bc72a1e194e3b0e2 + zh: 9a92cbac88adc7a7 +/agent-note-serial-cross-platform-ci-reference/consequences: + en: 7042125ce6a209d4 + zh: ef2be4fa8a4d6320 diff --git a/.agents/notes/implemented/process/2026-07-26-ci-failover-runbook.i18n.yaml b/.agents/notes/implemented/process/2026-07-26-ci-failover-runbook.i18n.yaml index 1be4833f09..14ae915151 100644 --- a/.agents/notes/implemented/process/2026-07-26-ci-failover-runbook.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-26-ci-failover-runbook.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-26-ci-failover-runbook.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-26-ci-failover-runbook.md -2026-07-26-ci-failover-runbook.md: d46f9d140860580011e06aa3b51bb8618a23a114 -2026-07-26-ci-failover-runbook.zh.md: a229d46f16d959356e9108842edd557420e699ae +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool: + en: 677b522817e84e2f + zh: f8518a7033b0fd54 +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool/problem: + en: 317fafe666a76953 + zh: c886a5a4bccceda0 +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool/decision: + en: 2520d6c0d2bfe1a6 + zh: 616c70b8b1026109 +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool/decision/release-rehearsals-share-the-linux-switch: + en: 7fdad4f7d060d659 + zh: 6773db9b7d62cd0a +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool/decision/what-the-in-house-pool-is: + en: 00d8934ed30e838c + zh: bdb5584fbaf27c7d +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool/decision/what-the-in-house-pool-is/windows-pool: + en: f395af725d1deaf1 + zh: 896cedbb36c13758 +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool/decision/switch-any-repository-writer-1-minute-no-merge: + en: 2e3829fd72d6b1b0 + zh: 563f0abade7974f9 +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool/capacity-during-failover: + en: 4095da1b492d7484 + zh: 0c0bb9c97e4af977 +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool/capacity-during-failover/switch-back: + en: 63cf911019db8d2f + zh: 5eb3903b0ceb30db +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool/capacity-during-failover/trust-boundary: + en: c05bc0ceba304ff0 + zh: 19ae9a2d70f25d33 +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool/alternatives-considered: + en: e68b70d7caca52f1 + zh: e6f0be792105a9e6 +/agent-note-ci-failover-runbook-hosted-pools-in-house-pool/consequences: + en: f66e0aa401136799 + zh: 657188692959955e diff --git a/.agents/notes/implemented/process/2026-07-26-dependencies-over-hand-rolling.i18n.yaml b/.agents/notes/implemented/process/2026-07-26-dependencies-over-hand-rolling.i18n.yaml index edc74a719e..5d93d0272b 100644 --- a/.agents/notes/implemented/process/2026-07-26-dependencies-over-hand-rolling.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-26-dependencies-over-hand-rolling.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-26-dependencies-over-hand-rolling.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-26-dependencies-over-hand-rolling.md -2026-07-26-dependencies-over-hand-rolling.md: 53336e5a2dc8970422dcf8a161a31eb01f8155e4 -2026-07-26-dependencies-over-hand-rolling.zh.md: deec00d87f2c514dbf16cac0e96cdf00ec055958 +/agent-note-prefer-maintained-dependencies-over-hand-rolling: + en: 5cf63576459c1942 + zh: c3f2dbc5e4656693 +/agent-note-prefer-maintained-dependencies-over-hand-rolling/problem: + en: 5c13c4dd8707db61 + zh: b788b35b54bec861 +/agent-note-prefer-maintained-dependencies-over-hand-rolling/decision: + en: 2b8c6ea6c61732cd + zh: 946b2ef6142eaca3 +/agent-note-prefer-maintained-dependencies-over-hand-rolling/alternatives-considered: + en: c3575c5c8b4a6e51 + zh: f20aa07eefed8a3b +/agent-note-prefer-maintained-dependencies-over-hand-rolling/consequences: + en: abac778b1b57b62a + zh: 7cd7b253d637726b diff --git a/.agents/notes/implemented/process/2026-07-26-frozen-agent-note-archive.i18n.yaml b/.agents/notes/implemented/process/2026-07-26-frozen-agent-note-archive.i18n.yaml index c8bfb9d43c..1b44f40971 100644 --- a/.agents/notes/implemented/process/2026-07-26-frozen-agent-note-archive.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-26-frozen-agent-note-archive.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-26-frozen-agent-note-archive.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-26-frozen-agent-note-archive.md -2026-07-26-frozen-agent-note-archive.md: e9ecfa78f53a5912608201654e2c56e399defccd -2026-07-26-frozen-agent-note-archive.zh.md: 9a3ce2e6e21864f2754f627be6f7576bfc1f9076 +/agent-note-freeze-low-future-value-agent-notes-outside-the-active-corpus: + en: f6883e4627411644 + zh: e034e9b350dfd622 +/agent-note-freeze-low-future-value-agent-notes-outside-the-active-corpus/problem: + en: cef0f05fd8dfd6a1 + zh: 228107eb6c00a91a +/agent-note-freeze-low-future-value-agent-notes-outside-the-active-corpus/decision: + en: 453cf66046816477 + zh: af5bb77e849416a1 +/agent-note-freeze-low-future-value-agent-notes-outside-the-active-corpus/alternatives-considered: + en: 7637deef67f3ec14 + zh: 7f43606e487fab67 +/agent-note-freeze-low-future-value-agent-notes-outside-the-active-corpus/consequences: + en: 679af41e64d0dd15 + zh: ebbead84f8b8e1df diff --git a/.agents/notes/implemented/process/2026-07-27-worktree-local-lefthook.i18n.yaml b/.agents/notes/implemented/process/2026-07-27-worktree-local-lefthook.i18n.yaml index 5bb1f929e1..5d29f39a16 100644 --- a/.agents/notes/implemented/process/2026-07-27-worktree-local-lefthook.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-27-worktree-local-lefthook.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-27-worktree-local-lefthook.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-27-worktree-local-lefthook.md -2026-07-27-worktree-local-lefthook.md: 42adc1ed1d60d1462a3fb6600b22b7d77b6ae28e -2026-07-27-worktree-local-lefthook.zh.md: b4b905967861606154a4bf63f4dbb6b4eb469e92 +/agent-note-make-lefthook-installation-worktree-local: + en: 2a11ec534041e270 + zh: 9cbd4adbaecd1b32 +/agent-note-make-lefthook-installation-worktree-local/problem: + en: b3ec2245644b46e6 + zh: 83de1cb620f9ddcf +/agent-note-make-lefthook-installation-worktree-local/decision: + en: 577d90ff7e03ebaf + zh: dc680155c0c3a2a1 +/agent-note-make-lefthook-installation-worktree-local/alternatives-considered: + en: d7100b0d2c95a3f9 + zh: 070c38c4d0d1331a +/agent-note-make-lefthook-installation-worktree-local/consequences: + en: ea991f7a0d5c0bf2 + zh: e7f7b3c9215213ba diff --git a/.agents/notes/implemented/process/2026-07-30-generated-third-party-notices.i18n.yaml b/.agents/notes/implemented/process/2026-07-30-generated-third-party-notices.i18n.yaml index c92bdd5546..91cb4b1f67 100644 --- a/.agents/notes/implemented/process/2026-07-30-generated-third-party-notices.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-30-generated-third-party-notices.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-30-generated-third-party-notices.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-30-generated-third-party-notices.md -2026-07-30-generated-third-party-notices.md: 71f1fd0a5b650d53c5ef21438e17e0a6e162bdf5 -2026-07-30-generated-third-party-notices.zh.md: e3adb43e4b407945a8cca88105de689407b5908b +/agent-note-generated-third-party-notices: + en: 762fe10c2750eb0a + zh: 24f5efdf4cc1755e +/agent-note-generated-third-party-notices/problem: + en: e6929494e60041a2 + zh: 15bec8e8baabcab2 +/agent-note-generated-third-party-notices/decision: + en: 4d9ab23559067da3 + zh: 8de95de194393187 +/agent-note-generated-third-party-notices/testing: + en: 194f87f780991068 + zh: 58096d2339576d20 +/agent-note-generated-third-party-notices/alternatives-considered: + en: 093ddc027e296bf0 + zh: 6b9e64d99dcefa11 +/agent-note-generated-third-party-notices/consequences: + en: 860b806c5d393c98 + zh: 51b4ca11e2d3802a diff --git a/.agents/notes/implemented/process/2026-08-02-native-github-stacks-and-optional-rebases.i18n.yaml b/.agents/notes/implemented/process/2026-08-02-native-github-stacks-and-optional-rebases.i18n.yaml index 360c8ca687..88fc7212bb 100644 --- a/.agents/notes/implemented/process/2026-08-02-native-github-stacks-and-optional-rebases.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-02-native-github-stacks-and-optional-rebases.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-02-native-github-stacks-and-optional-rebases.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-02-native-github-stacks-and-optional-rebases.md -2026-08-02-native-github-stacks-and-optional-rebases.md: 394f0d7b4557bd306ae020d3edb5339fbcd2f068 -2026-08-02-native-github-stacks-and-optional-rebases.zh.md: 6266619fa1b2e58b50377b2ddb268632bb6cce08 +/agent-note-native-github-stacks-and-optional-pr-rebases: + en: 9427ca53db68d50b + zh: 9e72b34deee3bb9f +/agent-note-native-github-stacks-and-optional-pr-rebases/problem: + en: 21312af191207fa6 + zh: 86306b4c6dd08a0c +/agent-note-native-github-stacks-and-optional-pr-rebases/decision: + en: 893a172d6f0fc764 + zh: 5fdeca6898882bb2 +/agent-note-native-github-stacks-and-optional-pr-rebases/verification: + en: eac5830cd3dd385e + zh: 8e272a5cf2e54519 +/agent-note-native-github-stacks-and-optional-pr-rebases/alternatives-considered: + en: 9c601bc6dee773f1 + zh: 72fb6396e76ba2a5 +/agent-note-native-github-stacks-and-optional-pr-rebases/consequences: + en: 7cb31f6445970432 + zh: 0da95a9f9b521bea diff --git a/.agents/notes/implemented/process/2026-08-03-package-anchored-subsystem-pages.i18n.yaml b/.agents/notes/implemented/process/2026-08-03-package-anchored-subsystem-pages.i18n.yaml index 1e3b097d4c..b427a1cc50 100644 --- a/.agents/notes/implemented/process/2026-08-03-package-anchored-subsystem-pages.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-03-package-anchored-subsystem-pages.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-03-package-anchored-subsystem-pages.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-03-package-anchored-subsystem-pages.md -2026-08-03-package-anchored-subsystem-pages.md: ea98bae0c54b45351712a75b5c2387c5f57fae71 -2026-08-03-package-anchored-subsystem-pages.zh.md: 4da4211f4e29eff0d30bd3da5d5035ad2a928ee5 +/agent-note-package-anchored-subsystem-pages-and-thin-group-readmes: + en: 48a39166064d9f0d + zh: c23ba48570aab506 +/agent-note-package-anchored-subsystem-pages-and-thin-group-readmes/problem: + en: 244099e9da9c15ce + zh: 72b5dd59abe0133a +/agent-note-package-anchored-subsystem-pages-and-thin-group-readmes/decision: + en: b8c1668317997b2c + zh: 62d0ef605bfa3d3c +/agent-note-package-anchored-subsystem-pages-and-thin-group-readmes/alternatives-considered: + en: 07b4fc9048074b31 + zh: d14c862196f545fa +/agent-note-package-anchored-subsystem-pages-and-thin-group-readmes/consequences: + en: 9a6d02787410d14d + zh: e63d7023f49d5750 diff --git a/.agents/notes/implemented/process/2026-08-08-automatic-translation-pairing-merges.i18n.yaml b/.agents/notes/implemented/process/2026-08-08-automatic-translation-pairing-merges.i18n.yaml deleted file mode 100644 index 5e46e610a1..0000000000 --- a/.agents/notes/implemented/process/2026-08-08-automatic-translation-pairing-merges.i18n.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# 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 .agents/notes/implemented/process/2026-08-08-automatic-translation-pairing-merges.md -2026-08-08-automatic-translation-pairing-merges.md: ac4e0c11290abfd48d0f3caf037062aa2fe36c4d -2026-08-08-automatic-translation-pairing-merges.zh.md: 820ebdbe8c20988c4e917704db2f1994ae830fad diff --git a/.agents/notes/implemented/process/2026-08-08-browser-gif-evidence-chain.i18n.yaml b/.agents/notes/implemented/process/2026-08-08-browser-gif-evidence-chain.i18n.yaml index e09c768aba..402eb36c98 100644 --- a/.agents/notes/implemented/process/2026-08-08-browser-gif-evidence-chain.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-08-browser-gif-evidence-chain.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-08-browser-gif-evidence-chain.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-08-browser-gif-evidence-chain.md -2026-08-08-browser-gif-evidence-chain.md: 8a7c28792bbab178cac6ba6743628882a15fdf6e -2026-08-08-browser-gif-evidence-chain.zh.md: ff9b6cc729c23dd9f3ba170752fa05fe65c7fb53 +/agent-note-browser-gifs-preserve-one-evidence-chain: + en: acd1abc5215025db + zh: 13d04f81ebb47d18 +/agent-note-browser-gifs-preserve-one-evidence-chain/problem: + en: 427edb924ca3106e + zh: 2115278719f9fd25 +/agent-note-browser-gifs-preserve-one-evidence-chain/decision: + en: 1a098893e7e55ff8 + zh: c2912855cfc4a2bb +/agent-note-browser-gifs-preserve-one-evidence-chain/alternatives-considered: + en: 7c8b16109ffaf01a + zh: d978945c49912639 +/agent-note-browser-gifs-preserve-one-evidence-chain/consequences: + en: 18e112842a2a0ac8 + zh: bb562ffcbd660b83 diff --git a/.agents/notes/implemented/process/2026-08-08-native-windows-pull-request-ci.i18n.yaml b/.agents/notes/implemented/process/2026-08-08-native-windows-pull-request-ci.i18n.yaml index 7ad3923251..8a421fe006 100644 --- a/.agents/notes/implemented/process/2026-08-08-native-windows-pull-request-ci.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-08-native-windows-pull-request-ci.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-08-native-windows-pull-request-ci.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-08-native-windows-pull-request-ci.md -2026-08-08-native-windows-pull-request-ci.md: 64c4366ee8d60dd0137e6e4eb5473c0450204efe -2026-08-08-native-windows-pull-request-ci.zh.md: 48725cdc58ab7b8db22461da64236c6de3bb3027 +/agent-note-wine-and-native-windows-ci: + en: 9c96424c10b83c6b + zh: b2adf0c650fbf529 +/agent-note-wine-and-native-windows-ci/problem: + en: 3e229ecf646af866 + zh: d358507b1e1d381f +/agent-note-wine-and-native-windows-ci/decision: + en: f557cb00e1b457c1 + zh: eeaec8412ddb315a +/agent-note-wine-and-native-windows-ci/alternatives-considered: + en: f6c5e77fe3f05739 + zh: 8de640d12d3a38c4 +/agent-note-wine-and-native-windows-ci/consequences: + en: 58069228d4e904c6 + zh: 2601a48b82400903 diff --git a/.agents/notes/implemented/process/2026-08-08-unified-github-label-taxonomy.i18n.yaml b/.agents/notes/implemented/process/2026-08-08-unified-github-label-taxonomy.i18n.yaml index 8c6982cd71..3abc0c9d28 100644 --- a/.agents/notes/implemented/process/2026-08-08-unified-github-label-taxonomy.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-08-unified-github-label-taxonomy.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-08-unified-github-label-taxonomy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-08-unified-github-label-taxonomy.md -2026-08-08-unified-github-label-taxonomy.md: 1748f9b77ed2922035c5e75ac4a2eee047f413d3 -2026-08-08-unified-github-label-taxonomy.zh.md: 3b221a5f3db43597656f46dfc505cdfda38c75db +/agent-note-unified-github-label-taxonomy: + en: 59560a685380483f + zh: 1bf2324f05c8968a +/agent-note-unified-github-label-taxonomy/problem: + en: 8c0c360d500f22f0 + zh: 97c815076ee9b53b +/agent-note-unified-github-label-taxonomy/decision: + en: 398fb26c5da12e42 + zh: 02c16ca5058283bc +/agent-note-unified-github-label-taxonomy/decision/kinds: + en: 04e51bc9313727a0 + zh: 443388bc0472c368 +/agent-note-unified-github-label-taxonomy/decision/areas: + en: b8d485a8222d0938 + zh: 8fbb27557db98023 +/agent-note-unified-github-label-taxonomy/decision/issues-and-migrations: + en: 6d720c37cf806ae6 + zh: c16c420482d02067 +/agent-note-unified-github-label-taxonomy/alternatives-considered: + en: 57740baaeda04f6d + zh: 8da0aabac6b06424 +/agent-note-unified-github-label-taxonomy/consequences: + en: 41169a21b2ac9801 + zh: 5506bf106f95163d diff --git a/.agents/notes/implemented/process/2026-08-09-committed-artifact-citations.i18n.yaml b/.agents/notes/implemented/process/2026-08-09-committed-artifact-citations.i18n.yaml index febe070830..e8b85c04de 100644 --- a/.agents/notes/implemented/process/2026-08-09-committed-artifact-citations.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-09-committed-artifact-citations.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-09-committed-artifact-citations.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-09-committed-artifact-citations.md -2026-08-09-committed-artifact-citations.md: 66dec38755fbe366385349e65da3dbc0ff632769 -2026-08-09-committed-artifact-citations.zh.md: ebc4541e56c4481005700cf16aa03881c9fb005d +/agent-note-cite-committed-artifacts-never-design-session-ordinals: + en: c97b89961652ab9f + zh: a2ecdc61c29652a6 +/agent-note-cite-committed-artifacts-never-design-session-ordinals/problem: + en: 79dc8b3d2c600d91 + zh: e7b16c9e276e565f +/agent-note-cite-committed-artifacts-never-design-session-ordinals/decision: + en: 83f88200cfa66c98 + zh: 3db6822a92701d64 +/agent-note-cite-committed-artifacts-never-design-session-ordinals/alternatives-considered: + en: cdf3ce2ccd530449 + zh: f24bb73190b4b22b +/agent-note-cite-committed-artifacts-never-design-session-ordinals/verification: + en: fb9ce345704f7da4 + zh: 3148c6bbf67ad87f +/agent-note-cite-committed-artifacts-never-design-session-ordinals/consequences: + en: 53fe33cd40aa7133 + zh: 4eaf89d5dea43c62 diff --git a/.agents/notes/implemented/process/2026-08-09-concrete-prose-names-actors-and-recorded-facts.i18n.yaml b/.agents/notes/implemented/process/2026-08-09-concrete-prose-names-actors-and-recorded-facts.i18n.yaml index 4326e893cf..eb5e443f1b 100644 --- a/.agents/notes/implemented/process/2026-08-09-concrete-prose-names-actors-and-recorded-facts.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-09-concrete-prose-names-actors-and-recorded-facts.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-09-concrete-prose-names-actors-and-recorded-facts.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-09-concrete-prose-names-actors-and-recorded-facts.md -2026-08-09-concrete-prose-names-actors-and-recorded-facts.md: 91f7913ff0cabafdd1c089e618d7864b9a085147 -2026-08-09-concrete-prose-names-actors-and-recorded-facts.zh.md: 315850711adb234fa2bd9a92d9bd69fea5077230 +/agent-note-concrete-prose-names-actors-and-recorded-facts: + en: fbfbd92c8f73d34c + zh: fc48118b80f5dbb9 +/agent-note-concrete-prose-names-actors-and-recorded-facts/problem: + en: f0228c15ff233209 + zh: b6183fdc8dd705a0 +/agent-note-concrete-prose-names-actors-and-recorded-facts/decision: + en: 833658027dc8e2d7 + zh: a360c4aa7b4dde7f +/agent-note-concrete-prose-names-actors-and-recorded-facts/alternatives-considered: + en: 08a988b00edf03b2 + zh: 8614c5edbc46ca36 +/agent-note-concrete-prose-names-actors-and-recorded-facts/consequences: + en: 18e6d0b597186220 + zh: 744ed1b795929bba diff --git a/.agents/notes/implemented/process/2026-08-10-event-directed-pr-review-status.i18n.yaml b/.agents/notes/implemented/process/2026-08-10-event-directed-pr-review-status.i18n.yaml index 4d9e3fafc1..6d96599459 100644 --- a/.agents/notes/implemented/process/2026-08-10-event-directed-pr-review-status.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-10-event-directed-pr-review-status.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-10-event-directed-pr-review-status.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-10-event-directed-pr-review-status.md -2026-08-10-event-directed-pr-review-status.md: 37b8086a081145e8c16ceb29d489fbc38a7f0d43 -2026-08-10-event-directed-pr-review-status.zh.md: cc0dad8554f869d51965c30d2648937c54dc2b75 +/agent-note-event-directed-pr-review-status-commands: + en: 936b85c184551acf + zh: faf32b3209539114 +/agent-note-event-directed-pr-review-status-commands/problem: + en: 3e00a9cb6c0e53ec + zh: 1bd27ceea8a424ce +/agent-note-event-directed-pr-review-status-commands/decision: + en: 3b661de4e6fbf401 + zh: 2fb7f7adb4f846e4 +/agent-note-event-directed-pr-review-status-commands/verification: + en: 46301d11d2f1c8df + zh: daa44a617912c315 +/agent-note-event-directed-pr-review-status-commands/alternatives-considered: + en: 8b5ec4d7fc09a9ab + zh: d72ebe462bb2e9d2 +/agent-note-event-directed-pr-review-status-commands/consequences: + en: e3d39dca9122531b + zh: 262098573f196b93 diff --git a/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.i18n.yaml b/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.i18n.yaml index bd7e432b63..40e0e18b71 100644 --- a/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.i18n.yaml @@ -1,6 +1,52 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-10-npm-release-sequences.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-10-npm-release-sequences.md -2026-08-10-npm-release-sequences.md: 6a4f9d1ec23d1fd1c7b74630e106974b680fe41a -2026-08-10-npm-release-sequences.zh.md: d33d48e4458a62951aa957e694dd70eedcf2a6c8 +/agent-note-private-npm-publication-as-three-independent-sequences: + en: 176f873a6b094838 + zh: 9baeba69cbaea9cf +/agent-note-private-npm-publication-as-three-independent-sequences/problem: + en: b94462e04e350571 + zh: 07cef78e4cf7a9ac +/agent-note-private-npm-publication-as-three-independent-sequences/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-private-npm-publication-as-three-independent-sequences/decision/three-independent-sequences: + en: 6cd23b2407935500 + zh: 6d50f5f4fb867342 +/agent-note-private-npm-publication-as-three-independent-sequences/decision/versions-land-in-the-repository-from-a-local-command-ci-only-checks-and-uploads: + en: 71d4cda384013bfb + zh: 909d853c18496925 +/agent-note-private-npm-publication-as-three-independent-sequences/decision/vendor-publish-what-changed-and-let-tags-be-the-ledger: + en: 7f578bb18f7f8693 + zh: 49f25210f7c1a61f +/agent-note-private-npm-publication-as-three-independent-sequences/decision/publication-runs-only-on-github-and-the-registry-decides-what-goes-out: + en: 4f399390f58d7a34 + zh: 9df67248acfc61c8 +/agent-note-private-npm-publication-as-three-independent-sequences/decision/workspace-internal-references-use-the-workspace-protocol: + en: 6cff087e7e2d0ac7 + zh: 5d45a3abdd960d9c +/agent-note-private-npm-publication-as-three-independent-sequences/decision/published-dependency-faces-use-an-explicit-policy: + en: 30a64e0e919a27c0 + zh: 19729d7ebee35439 +/agent-note-private-npm-publication-as-three-independent-sequences/decision/an-optional-dependency-is-never-loaded-at-module-scope: + en: d83f6cf38529c5b5 + zh: 4df5659b2154d3b7 +/agent-note-private-npm-publication-as-three-independent-sequences/decision/release-family-objects: + en: e8bb80d936e2cbbd + zh: bc4ae297e98a5446 +/agent-note-private-npm-publication-as-three-independent-sequences/decision/workflow-shape-pack-on-pr-push-publish-from-a-manual-dispatch-workflow: + en: ea0acc6409da4d5c + zh: ac0bd2fe41f4fe67 +/agent-note-private-npm-publication-as-three-independent-sequences/decision/repository-changes-this-carried: + en: c505237cad2c4128 + zh: 55364ba462536680 +/agent-note-private-npm-publication-as-three-independent-sequences/decision/relationship-to-the-earlier-proposal: + en: 298382a27013dcfb + zh: ab89cf392232f9bb +/agent-note-private-npm-publication-as-three-independent-sequences/alternatives-considered: + en: 11877d09e5a84f6e + zh: ea372c779254be93 +/agent-note-private-npm-publication-as-three-independent-sequences/consequences: + en: f961ebb927e30b5c + zh: 019f1628fb1f2c56 diff --git a/.agents/notes/implemented/process/2026-08-18-in-job-partitioned-coverage.i18n.yaml b/.agents/notes/implemented/process/2026-08-18-in-job-partitioned-coverage.i18n.yaml index b11aba495c..47454c2346 100644 --- a/.agents/notes/implemented/process/2026-08-18-in-job-partitioned-coverage.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-18-in-job-partitioned-coverage.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-18-in-job-partitioned-coverage.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-18-in-job-partitioned-coverage.md -2026-08-18-in-job-partitioned-coverage.md: 3eafecc02f45b470e13ca426ad005f053a852472 -2026-08-18-in-job-partitioned-coverage.zh.md: 457e352992519b1845b0a592cc9d5a235d29df9d +/agent-note-in-job-partitioned-coverage: + en: eb25ff049a1ecc31 + zh: d7430b14ccea5707 +/agent-note-in-job-partitioned-coverage/problem: + en: ab6dcac4ca2bbfb3 + zh: c754cc8077671b25 +/agent-note-in-job-partitioned-coverage/decision: + en: ae23ea86587c23e8 + zh: b9868c5c76238d9a +/agent-note-in-job-partitioned-coverage/failure-and-output-semantics: + en: c73ddbc65107e34e + zh: dbc7649637f8d1c0 +/agent-note-in-job-partitioned-coverage/verification: + en: 81dcaebd4b96229c + zh: 76b3332b183f6c44 +/agent-note-in-job-partitioned-coverage/alternatives-considered: + en: 82f314bd434b0059 + zh: 7b64e90b74f428e5 +/agent-note-in-job-partitioned-coverage/consequences: + en: 146e997017ee6e47 + zh: cd5e5d2d9b0b47b9 diff --git a/.agents/notes/implemented/process/2026-08-19-remove-knip.i18n.yaml b/.agents/notes/implemented/process/2026-08-19-remove-knip.i18n.yaml index aee415539b..1d76a326bd 100644 --- a/.agents/notes/implemented/process/2026-08-19-remove-knip.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-19-remove-knip.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-19-remove-knip.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-19-remove-knip.md -2026-08-19-remove-knip.md: 5e7e898e05a7e6a6e087b8784f7f49e71cf8fc37 -2026-08-19-remove-knip.zh.md: f6bca8661648efd565dc0bbec86ca2c76738ea85 +/agent-note-remove-knip-from-repository-gates: + en: adba00071ebc35c8 + zh: 44f778106e0b9965 +/agent-note-remove-knip-from-repository-gates/problem: + en: 5b2ece5e6f3775e0 + zh: 4fbc60619afdb7e2 +/agent-note-remove-knip-from-repository-gates/decision: + en: c5d7ae84ed863e29 + zh: 409dca40c2a63940 +/agent-note-remove-knip-from-repository-gates/alternatives-considered: + en: 95363dbc293712f3 + zh: 9cbcb9937081f5f0 +/agent-note-remove-knip-from-repository-gates/consequences: + en: 7466ca9e99d0bb27 + zh: 2ac417bc23865e14 diff --git a/.agents/notes/implemented/process/2026-08-26-ban-ambiguous-origin-label.i18n.yaml b/.agents/notes/implemented/process/2026-08-26-ban-ambiguous-origin-label.i18n.yaml index c1d9874a82..064bf1cbf2 100644 --- a/.agents/notes/implemented/process/2026-08-26-ban-ambiguous-origin-label.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-26-ban-ambiguous-origin-label.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-26-ban-ambiguous-origin-label.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-26-ban-ambiguous-origin-label.md -2026-08-26-ban-ambiguous-origin-label.md: b4c161a8a963e0aebdb3dcf24b8aac028429f349 -2026-08-26-ban-ambiguous-origin-label.zh.md: 2d592f44429d8622b5a42c55c7f92eae6da96800 +/agent-note-ban-an-ambiguous-origin-label: + en: 98843ceb0ee72c06 + zh: e4963bfe0e1b1314 +/agent-note-ban-an-ambiguous-origin-label/problem: + en: e3c5b3a689f7a3cc + zh: 676620dfb5303bed +/agent-note-ban-an-ambiguous-origin-label/decision: + en: bb8507460f159ad1 + zh: 357b5e6065cf389c +/agent-note-ban-an-ambiguous-origin-label/alternatives-considered: + en: 50421d71ea80fef9 + zh: 512625bd4dac0734 +/agent-note-ban-an-ambiguous-origin-label/consequences: + en: 51a4f9c099f993f1 + zh: 655bcf2eda1835ff diff --git a/.agents/notes/implemented/process/2026-08-26-published-dependency-faces.i18n.yaml b/.agents/notes/implemented/process/2026-08-26-published-dependency-faces.i18n.yaml index 02670de7a5..19ca92d47b 100644 --- a/.agents/notes/implemented/process/2026-08-26-published-dependency-faces.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-26-published-dependency-faces.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-26-published-dependency-faces.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-26-published-dependency-faces.md -2026-08-26-published-dependency-faces.md: f188ccc0fc91b2899ccb618d3000a9b3cb94eb59 -2026-08-26-published-dependency-faces.zh.md: d59bb724ceb15f6eae65b509f8437a5dcfa05a23 +/agent-note-published-dependency-faces-and-bounded-peer-relays: + en: 553313933867d0f4 + zh: 11288efed41eea50 +/agent-note-published-dependency-faces-and-bounded-peer-relays/problem: + en: a8357e7e0735ad71 + zh: 5217d99a4ef921c7 +/agent-note-published-dependency-faces-and-bounded-peer-relays/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-published-dependency-faces-and-bounded-peer-relays/decision/package-selection: + en: 5ea13b09ae774437 + zh: ef9dbccada39107a +/agent-note-published-dependency-faces-and-bounded-peer-relays/decision/dependency-sections: + en: b1c3e9a87b8bb1ea + zh: 5cfd8b4db39805b7 +/agent-note-published-dependency-faces-and-bounded-peer-relays/decision/maintainer-workflow: + en: 5983475fa551ca90 + zh: a5519f4817f65e8c +/agent-note-published-dependency-faces-and-bounded-peer-relays/decision/performance-verification: + en: 4ef3cc92457794fd + zh: 16ac73ea9760223b +/agent-note-published-dependency-faces-and-bounded-peer-relays/alternatives-considered: + en: e1c6f1cebc9dc6d2 + zh: 8c4b1959cdd6b3f2 +/agent-note-published-dependency-faces-and-bounded-peer-relays/consequences: + en: 70e475315e0898e2 + zh: bcb54a35da49fc99 diff --git a/.agents/notes/implemented/process/2026-08-28-ci-node-compile-cache-data-disk.i18n.yaml b/.agents/notes/implemented/process/2026-08-28-ci-node-compile-cache-data-disk.i18n.yaml index 4fd1361ca9..9413c6b4fd 100644 --- a/.agents/notes/implemented/process/2026-08-28-ci-node-compile-cache-data-disk.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-28-ci-node-compile-cache-data-disk.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-28-ci-node-compile-cache-data-disk.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-28-ci-node-compile-cache-data-disk.md -2026-08-28-ci-node-compile-cache-data-disk.md: 3f5f7eb2f00a37b635b63093f60c66688b82316b -2026-08-28-ci-node-compile-cache-data-disk.zh.md: c55a6c73cf98f0dd0b31b50d64e7937ee9e14305 +/agent-note-redirect-the-node-compile-cache-to-the-data-volume-runner-temp: + en: 52bb1466b8f7f8fe + zh: fa7c282d3d207e53 +/agent-note-redirect-the-node-compile-cache-to-the-data-volume-runner-temp/problem: + en: 3efe58882ca81bf7 + zh: 14f802e97e26f03d +/agent-note-redirect-the-node-compile-cache-to-the-data-volume-runner-temp/decision: + en: cb66e6c4ad73b50b + zh: 43540cec116e342a +/agent-note-redirect-the-node-compile-cache-to-the-data-volume-runner-temp/verification: + en: e23de17356f97224 + zh: b28bcafb4d1a72ad +/agent-note-redirect-the-node-compile-cache-to-the-data-volume-runner-temp/alternatives-considered: + en: 6119e2aff3b6be5a + zh: e01a6c669a9ec6aa +/agent-note-redirect-the-node-compile-cache-to-the-data-volume-runner-temp/alternatives-considered/why-not-disable-the-compile-cache-entirely: + en: cee8de5b45031309 + zh: 6ce10a304e63bdbb +/agent-note-redirect-the-node-compile-cache-to-the-data-volume-runner-temp/alternatives-considered/why-not-add-node-compile-cache-to-the-dsh-residue-sweep: + en: 7e06d9c4df7a9f56 + zh: f3151fe2671fd91e +/agent-note-redirect-the-node-compile-cache-to-the-data-volume-runner-temp/alternatives-considered/why-not-job-level-env-or-gate-step-env-only: + en: 4ba6c9a14bafbc80 + zh: 410149f4a3e930e6 +/agent-note-redirect-the-node-compile-cache-to-the-data-volume-runner-temp/consequences: + en: 083e2665e1550111 + zh: 70560c09ca2b3750 diff --git a/.agents/notes/implemented/process/2026-09-02-project-local-issue-planning-fields.i18n.yaml b/.agents/notes/implemented/process/2026-09-02-project-local-issue-planning-fields.i18n.yaml index 305f975303..c092807a5a 100644 --- a/.agents/notes/implemented/process/2026-09-02-project-local-issue-planning-fields.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-02-project-local-issue-planning-fields.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-02-project-local-issue-planning-fields.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-02-project-local-issue-planning-fields.md -2026-09-02-project-local-issue-planning-fields.md: e44fe0f002c40309beaeb4af3ccdd975714777e6 -2026-09-02-project-local-issue-planning-fields.zh.md: 28308d48994dbb144f7e7934a1058cef35942c20 +/agent-note-project-local-issue-planning-fields: + en: 9791d03a5df4c38c + zh: 19cbbf884294402b +/agent-note-project-local-issue-planning-fields/problem: + en: d01d052a9f366f35 + zh: b18600b91aad9a7c +/agent-note-project-local-issue-planning-fields/decision: + en: 21db463121897497 + zh: fd0551038412fd17 +/agent-note-project-local-issue-planning-fields/verification: + en: 7d1ef3eb9aac465d + zh: 68280a4511bce360 +/agent-note-project-local-issue-planning-fields/alternatives-considered: + en: b51a8fbc92bb7b5f + zh: 9316e86ac82c0a1b +/agent-note-project-local-issue-planning-fields/consequences: + en: d3614b91a0a6523a + zh: 773a31194e293014 diff --git a/.agents/notes/implemented/process/2026-09-03-semantic-issue-templates-and-policy.i18n.yaml b/.agents/notes/implemented/process/2026-09-03-semantic-issue-templates-and-policy.i18n.yaml index 782e6472d4..68c4e68e70 100644 --- a/.agents/notes/implemented/process/2026-09-03-semantic-issue-templates-and-policy.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-03-semantic-issue-templates-and-policy.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-03-semantic-issue-templates-and-policy.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-03-semantic-issue-templates-and-policy.md -2026-09-03-semantic-issue-templates-and-policy.md: 96b1981b21e901841d88b09d68a0e7e31ca140a2 -2026-09-03-semantic-issue-templates-and-policy.zh.md: 706cd59047fe5121964183bbc27efc8961a493ed +/agent-note-semantic-issue-templates-and-presentation-neutral-policy: + en: e1e183193c798bf4 + zh: db76ac954cd3038f +/agent-note-semantic-issue-templates-and-presentation-neutral-policy/problem: + en: 5da7b92d65316469 + zh: 30bc615947b3a8aa +/agent-note-semantic-issue-templates-and-presentation-neutral-policy/decision: + en: a351c272ef520bb9 + zh: 98db942d18da7565 +/agent-note-semantic-issue-templates-and-presentation-neutral-policy/verification: + en: 90912d4c58b9e35d + zh: 811eaab5bdd54ab4 +/agent-note-semantic-issue-templates-and-presentation-neutral-policy/alternatives-considered: + en: 520ba80ce03e05b4 + zh: 50df33c59c4c837d +/agent-note-semantic-issue-templates-and-presentation-neutral-policy/consequences: + en: c762b95945320c61 + zh: 935f6e7290c06811 diff --git a/.agents/notes/implemented/process/2026-09-06-evidence-driven-performance-skill.i18n.yaml b/.agents/notes/implemented/process/2026-09-06-evidence-driven-performance-skill.i18n.yaml index 52ccc34d2c..a9cf40b2dc 100644 --- a/.agents/notes/implemented/process/2026-09-06-evidence-driven-performance-skill.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-06-evidence-driven-performance-skill.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-evidence-driven-performance-skill.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-06-evidence-driven-performance-skill.md -2026-09-06-evidence-driven-performance-skill.md: 221287ef03386f53d61458db7a280142dfde690a -2026-09-06-evidence-driven-performance-skill.zh.md: 90e2c1aa5778d23492bec4f2049ce158433e2363 +/agent-note-evidence-driven-performance-optimization-workflow: + en: 0a63ab9dc4847f40 + zh: f8ba9a608396c47c +/agent-note-evidence-driven-performance-optimization-workflow/problem: + en: 2e0cb63ef966a541 + zh: 1853e223e530708e +/agent-note-evidence-driven-performance-optimization-workflow/decision: + en: bd0e363221108421 + zh: fc83dc1020d53f4e +/agent-note-evidence-driven-performance-optimization-workflow/historical-evidence: + en: 2d913642c87e5a01 + zh: 45fce898640c87e8 +/agent-note-evidence-driven-performance-optimization-workflow/alternatives-considered: + en: 70d016cd8e541933 + zh: 2ebeb9cbeba8129e +/agent-note-evidence-driven-performance-optimization-workflow/consequences: + en: 961c634c37340937 + zh: 9a528567223f7bfa diff --git a/.agents/notes/implemented/process/2026-09-06-master-only-platform-ci.i18n.yaml b/.agents/notes/implemented/process/2026-09-06-master-only-platform-ci.i18n.yaml index a331c0727e..0397c20321 100644 --- a/.agents/notes/implemented/process/2026-09-06-master-only-platform-ci.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-06-master-only-platform-ci.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-master-only-platform-ci.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-06-master-only-platform-ci.md -2026-09-06-master-only-platform-ci.md: fcdc413d644c1129635a7f33fe80bdec1b4a0b7a -2026-09-06-master-only-platform-ci.zh.md: 4fb55d5e95f8fe75e6d1efb8b57295b8e8469e8d +/agent-note-master-only-platform-ci: + en: fed101c5775cbbcd + zh: b407efdb4c46cfe2 +/agent-note-master-only-platform-ci/problem: + en: 85cf39297a859208 + zh: c959bf7f94ebc50b +/agent-note-master-only-platform-ci/decision: + en: 98b8ecd3b4cfe5e5 + zh: 2c622950ea7afd42 +/agent-note-master-only-platform-ci/alternatives-considered: + en: 71ce7f8bb8a31323 + zh: 45f97b72eb9c6971 +/agent-note-master-only-platform-ci/consequences: + en: 523bbd6a59c120bf + zh: a9d834b5c32a911f diff --git a/.agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.i18n.yaml b/.agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.i18n.yaml index 93aad86a87..7cc692226f 100644 --- a/.agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-node-compatibility-selfhosted.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.md -2026-09-06-node-compatibility-selfhosted.md: 0ed422711426268efcb3b7cf37b6e19c52feba55 -2026-09-06-node-compatibility-selfhosted.zh.md: 2e58e3e7983b370050484bb8455cfa8554af494e +/agent-note-isolated-node-compatibility-jobs-on-self-hosted-linux: + en: 21c12c8bd0c44122 + zh: b07f0ffc18092f0d +/agent-note-isolated-node-compatibility-jobs-on-self-hosted-linux/problem: + en: 6bcedb8e3f0dce21 + zh: 83e88ed593259292 +/agent-note-isolated-node-compatibility-jobs-on-self-hosted-linux/decision: + en: 14f1348f993b9102 + zh: a94e1b802e6a8c39 +/agent-note-isolated-node-compatibility-jobs-on-self-hosted-linux/alternatives-considered: + en: 93217ca46c2cefb8 + zh: 77a167c69f59111c +/agent-note-isolated-node-compatibility-jobs-on-self-hosted-linux/consequences: + en: 116d255b8d1b846c + zh: 931754a68e4f75c6 +/agent-note-isolated-node-compatibility-jobs-on-self-hosted-linux/verification: + en: d0b1f1431fae737b + zh: 6cf4f4d654a9525d diff --git a/.agents/notes/implemented/process/2026-09-06-preview-hosted-runner-sizing.i18n.yaml b/.agents/notes/implemented/process/2026-09-06-preview-hosted-runner-sizing.i18n.yaml index 3156f6b0bd..6bd758533f 100644 --- a/.agents/notes/implemented/process/2026-09-06-preview-hosted-runner-sizing.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-06-preview-hosted-runner-sizing.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-preview-hosted-runner-sizing.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-06-preview-hosted-runner-sizing.md -2026-09-06-preview-hosted-runner-sizing.md: 414a17bf8a47f901e61ed271e9b2cf3dee3415b8 -2026-09-06-preview-hosted-runner-sizing.zh.md: 91a67b90b6617fea4dfa77672cb7e78412f462ee +/agent-note-measured-github-hosted-pr-preview-sizing: + en: 987e2592c644030d + zh: 55f306766247e4a4 +/agent-note-measured-github-hosted-pr-preview-sizing/problem: + en: bc382c3ef9c28709 + zh: 27e50735d80696a2 +/agent-note-measured-github-hosted-pr-preview-sizing/decision: + en: 9988e6268f8fc5b8 + zh: e92f3922b49b193d +/agent-note-measured-github-hosted-pr-preview-sizing/decision/measurements: + en: 768cd2ecf9d33c87 + zh: 693ea069a5275736 +/agent-note-measured-github-hosted-pr-preview-sizing/alternatives-considered: + en: 04f845ddb2a86e31 + zh: 993c6f82f5119f66 +/agent-note-measured-github-hosted-pr-preview-sizing/consequences: + en: ed9e8446f4579f5d + zh: c899cdd070e6befa diff --git a/.agents/notes/implemented/process/2026-09-06-python-runtime-windows-hosted.i18n.yaml b/.agents/notes/implemented/process/2026-09-06-python-runtime-windows-hosted.i18n.yaml index 4836b9f8c0..52e1d7fc30 100644 --- a/.agents/notes/implemented/process/2026-09-06-python-runtime-windows-hosted.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-06-python-runtime-windows-hosted.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-python-runtime-windows-hosted.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-06-python-runtime-windows-hosted.md -2026-09-06-python-runtime-windows-hosted.md: 95b762f2247c791536ae0902287ba40e20066258 -2026-09-06-python-runtime-windows-hosted.zh.md: e3f27788b0b620b4a7215b98bdc42b7d6957d5d7 +/agent-note-windows-python-runtime-ci-stays-on-github-hosted-windows: + en: d36b4627e3216a22 + zh: aabdaed56959936a +/agent-note-windows-python-runtime-ci-stays-on-github-hosted-windows/problem: + en: 81d36185575e6d77 + zh: 19003ab154d93394 +/agent-note-windows-python-runtime-ci-stays-on-github-hosted-windows/decision: + en: 1169dd58149ad6b4 + zh: aeebaf9ca8769de6 +/agent-note-windows-python-runtime-ci-stays-on-github-hosted-windows/alternatives-considered: + en: 817e77f011ea35c8 + zh: 2087bc653620a60f +/agent-note-windows-python-runtime-ci-stays-on-github-hosted-windows/consequences: + en: c31f88bace48ff9e + zh: 4698cd5ee3152e87 diff --git a/.agents/notes/implemented/process/2026-09-06-release-rehearsal-selfhosted.i18n.yaml b/.agents/notes/implemented/process/2026-09-06-release-rehearsal-selfhosted.i18n.yaml index a8ce01be68..9e35b7e987 100644 --- a/.agents/notes/implemented/process/2026-09-06-release-rehearsal-selfhosted.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-06-release-rehearsal-selfhosted.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-release-rehearsal-selfhosted.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-06-release-rehearsal-selfhosted.md -2026-09-06-release-rehearsal-selfhosted.md: 415ae4716e9bc0ae9b165afc807f6f41e8a57e04 -2026-09-06-release-rehearsal-selfhosted.zh.md: a6fa441d01e66cea998d77a9b1be588053ac60a5 +/agent-note-trusted-release-rehearsals-on-persistent-linux-runners: + en: 1bccf6bdafd4cc76 + zh: 28ce63be303697f1 +/agent-note-trusted-release-rehearsals-on-persistent-linux-runners/problem: + en: c458bf4244320194 + zh: fbd5f64cf8875725 +/agent-note-trusted-release-rehearsals-on-persistent-linux-runners/decision: + en: d51d35350d91f19b + zh: 65297576aff64e8a +/agent-note-trusted-release-rehearsals-on-persistent-linux-runners/alternatives-considered: + en: cd04297045b93d7b + zh: 9eacc1d9c6c10726 +/agent-note-trusted-release-rehearsals-on-persistent-linux-runners/consequences: + en: 90c50dda81822e7c + zh: 9c3ff4df4d2d9533 diff --git a/.agents/notes/implemented/process/2026-09-07-selective-issue-policy-evaluation.i18n.yaml b/.agents/notes/implemented/process/2026-09-07-selective-issue-policy-evaluation.i18n.yaml index 435048c1ba..b8002f1c9e 100644 --- a/.agents/notes/implemented/process/2026-09-07-selective-issue-policy-evaluation.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-07-selective-issue-policy-evaluation.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-selective-issue-policy-evaluation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-07-selective-issue-policy-evaluation.md -2026-09-07-selective-issue-policy-evaluation.md: 5e05bef320980b6069ede9edb0d40446ddd27b0f -2026-09-07-selective-issue-policy-evaluation.zh.md: 37c531e14e485499a3cb76d042d4c17438d413a0 +/agent-note-selective-issue-policy-evaluation: + en: b0f986e68a7b7d74 + zh: cffd2efae38626ef +/agent-note-selective-issue-policy-evaluation/problem: + en: 5af4901a5e9576fb + zh: eb089750b27129b1 +/agent-note-selective-issue-policy-evaluation/decision: + en: 99e6c76f04a4d49b + zh: 2631ff72b4db3bdf +/agent-note-selective-issue-policy-evaluation/alternatives-considered: + en: 89631c2a92ab079a + zh: 37b94f76ec6dc36a +/agent-note-selective-issue-policy-evaluation/consequences: + en: 6013a044827444e5 + zh: 69f767a1d534761a +/agent-note-selective-issue-policy-evaluation/verification: + en: b7fb4ebd009d7fd3 + zh: 6d682a4b7f41a4e0 diff --git a/.agents/notes/implemented/process/2026-09-08-browser-third-party-build-inputs.i18n.yaml b/.agents/notes/implemented/process/2026-09-08-browser-third-party-build-inputs.i18n.yaml index 7fc8e364f2..70e32ca967 100644 --- a/.agents/notes/implemented/process/2026-09-08-browser-third-party-build-inputs.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-08-browser-third-party-build-inputs.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-browser-third-party-build-inputs.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-08-browser-third-party-build-inputs.md -2026-09-08-browser-third-party-build-inputs.md: 97e61f3b99955cb402f9e622b2d40e3ee2953d79 -2026-09-08-browser-third-party-build-inputs.zh.md: e23c4e9d4615c7c5bc788beafcf6b94699f211ce +/agent-note-browser-third-party-libraries-as-build-inputs: + en: 907b99b05fcbce0e + zh: 57980cde5b585338 +/agent-note-browser-third-party-libraries-as-build-inputs/problem: + en: 55458dc0cd27341e + zh: ab23b350c17862be +/agent-note-browser-third-party-libraries-as-build-inputs/decision: + en: 2e9ff103342733eb + zh: d8be06fe18aab03a +/agent-note-browser-third-party-libraries-as-build-inputs/alternatives-considered: + en: 0247f31a86099d53 + zh: 445a6d35c03fc468 +/agent-note-browser-third-party-libraries-as-build-inputs/consequences: + en: ee331a2282a6884e + zh: de81b33db3fd6486 diff --git a/.agents/notes/implemented/process/2026-09-08-package-index-link-discovery.i18n.yaml b/.agents/notes/implemented/process/2026-09-08-package-index-link-discovery.i18n.yaml index a7a1903352..e57f7c6ecc 100644 --- a/.agents/notes/implemented/process/2026-09-08-package-index-link-discovery.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-08-package-index-link-discovery.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-package-index-link-discovery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-08-package-index-link-discovery.md -2026-09-08-package-index-link-discovery.md: be9084f72e468b914bd035ce62e95aa6a89983dc -2026-09-08-package-index-link-discovery.zh.md: 93d6c2163183b4fb6391b731e982002b1938a704 +/agent-note-include-package-indexes-in-markdown-link-discovery: + en: edf2fd5b97c0075a + zh: da6ca05db38ee998 +/agent-note-include-package-indexes-in-markdown-link-discovery/problem: + en: 74a87cccbf602fc4 + zh: 88d1116da4cc35fb +/agent-note-include-package-indexes-in-markdown-link-discovery/decision: + en: 350354f891182cbf + zh: 4607ef9c38ff7a68 +/agent-note-include-package-indexes-in-markdown-link-discovery/alternatives-considered: + en: e12999e567cd2cbd + zh: a502f11b11e86815 +/agent-note-include-package-indexes-in-markdown-link-discovery/consequences: + en: 0bd932bd7feb363b + zh: acce05659887e5e5 diff --git a/.agents/notes/implemented/process/2026-09-08-playwright-video-gif.i18n.yaml b/.agents/notes/implemented/process/2026-09-08-playwright-video-gif.i18n.yaml index bdf8870e5f..f8222bf89a 100644 --- a/.agents/notes/implemented/process/2026-09-08-playwright-video-gif.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-08-playwright-video-gif.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-playwright-video-gif.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-08-playwright-video-gif.md -2026-09-08-playwright-video-gif.md: 44db04814900d4813f1d39521e4e84e7d0b8d1b8 -2026-09-08-playwright-video-gif.zh.md: 4922d739f0ff760afe12fe1a624abc1d1c4cd81f +/agent-note-playwright-video-captures-continuous-browser-demos: + en: fcca6f069dc51b80 + zh: e9d171b6c84f92a7 +/agent-note-playwright-video-captures-continuous-browser-demos/problem: + en: 967fed211899587e + zh: 0062f7ca29211105 +/agent-note-playwright-video-captures-continuous-browser-demos/decision: + en: 5f9e88a564fd6b8a + zh: b78164f92167dada +/agent-note-playwright-video-captures-continuous-browser-demos/alternatives-considered: + en: 221e89bafcb152d4 + zh: b33816c680dc450f +/agent-note-playwright-video-captures-continuous-browser-demos/consequences: + en: e5c9eb6df05801ba + zh: 786cd7775bfceb9e diff --git a/.agents/notes/implemented/process/2026-09-09-blacksmith-failover-leg.i18n.yaml b/.agents/notes/implemented/process/2026-09-09-blacksmith-failover-leg.i18n.yaml index bfd50afb64..be7e6eb89c 100644 --- a/.agents/notes/implemented/process/2026-09-09-blacksmith-failover-leg.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-09-blacksmith-failover-leg.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-blacksmith-failover-leg.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-09-blacksmith-failover-leg.md -2026-09-09-blacksmith-failover-leg.md: 4fb4ed4ccb500887622200e01310230393b3de12 -2026-09-09-blacksmith-failover-leg.zh.md: c2c4ee76a3fcd8c9f16c635ac81bc987d40a04e2 +/agent-note-blacksmith-as-a-failover-leg-for-ci-pools: + en: 018c4f4b64ca6634 + zh: 949f97c78d0f0236 +/agent-note-blacksmith-as-a-failover-leg-for-ci-pools/problem: + en: 43ecfec1601f933e + zh: 3db5365403ffeac5 +/agent-note-blacksmith-as-a-failover-leg-for-ci-pools/decision: + en: fac195b5006faa2d + zh: 7c0ea86638c54e95 +/agent-note-blacksmith-as-a-failover-leg-for-ci-pools/alternatives-considered: + en: a605440fed0ccc2a + zh: 621b35ad2850ca1b +/agent-note-blacksmith-as-a-failover-leg-for-ci-pools/consequences: + en: 09db977b1472b797 + zh: c1b890aaca4e557e diff --git a/.agents/notes/implemented/process/2026-09-09-blocked-weighted-approvals-remain-pending.i18n.yaml b/.agents/notes/implemented/process/2026-09-09-blocked-weighted-approvals-remain-pending.i18n.yaml index 8817e9561a..3cf9104f6e 100644 --- a/.agents/notes/implemented/process/2026-09-09-blocked-weighted-approvals-remain-pending.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-09-blocked-weighted-approvals-remain-pending.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-blocked-weighted-approvals-remain-pending.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-09-blocked-weighted-approvals-remain-pending.md -2026-09-09-blocked-weighted-approvals-remain-pending.md: 50ab64dadc0d7ad14366950d24b4136d131f55ec -2026-09-09-blocked-weighted-approvals-remain-pending.zh.md: 58ab10b3acb3bee92c720b622d92170a1a8bcf03 +/agent-note-blocked-weighted-approvals-remain-pending: + en: 6a5da25eb874aece + zh: 654aa967a9222501 +/agent-note-blocked-weighted-approvals-remain-pending/problem: + en: 0afdda30d02b666b + zh: 6624aa9c8c58ea0a +/agent-note-blocked-weighted-approvals-remain-pending/decision: + en: cf7ac63f422b4cfb + zh: 250385e42d546d30 +/agent-note-blocked-weighted-approvals-remain-pending/verification: + en: af674f57088d303a + zh: b9c42f04beec9be5 +/agent-note-blocked-weighted-approvals-remain-pending/alternatives-considered: + en: 13d5f67070bd3396 + zh: c75db3746d31272e +/agent-note-blocked-weighted-approvals-remain-pending/consequences: + en: 284f19608b0d449f + zh: 1d9bd95239ba6ffa diff --git a/.agents/notes/implemented/process/2026-09-09-cancel-superseded-ci.i18n.yaml b/.agents/notes/implemented/process/2026-09-09-cancel-superseded-ci.i18n.yaml index 5ef13299ed..5dac131679 100644 --- a/.agents/notes/implemented/process/2026-09-09-cancel-superseded-ci.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-09-cancel-superseded-ci.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-cancel-superseded-ci.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-09-cancel-superseded-ci.md -2026-09-09-cancel-superseded-ci.md: 8de1f757870a2b18852a224ec2f1cc33d9f6a95e -2026-09-09-cancel-superseded-ci.zh.md: 3ae6ec6ad58b0dfc94e803a33ba92ded4e239485 +/agent-note-cancel-superseded-ci-validation: + en: 78c382bc45c48256 + zh: a6a93a2ef554c61c +/agent-note-cancel-superseded-ci-validation/problem: + en: b436e3c8a7ffe727 + zh: 80b9f77b5cb051de +/agent-note-cancel-superseded-ci-validation/decision: + en: a61d1bc387ed8436 + zh: 3162cdd8096a8a01 +/agent-note-cancel-superseded-ci-validation/alternatives-considered: + en: c7d012d6e43f35ec + zh: 6f3eaf1342319aeb +/agent-note-cancel-superseded-ci-validation/consequences: + en: c226f645a79d0060 + zh: 023071f83b9a126d +/agent-note-cancel-superseded-ci-validation/verification: + en: 015f312772637350 + zh: b703cdab8bd4f0ae diff --git a/.agents/notes/implemented/process/2026-09-09-parallel-macos-notarization.i18n.yaml b/.agents/notes/implemented/process/2026-09-09-parallel-macos-notarization.i18n.yaml index 43d5e94cad..2a23f8fdfb 100644 --- a/.agents/notes/implemented/process/2026-09-09-parallel-macos-notarization.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-09-parallel-macos-notarization.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-parallel-macos-notarization.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-09-parallel-macos-notarization.md -2026-09-09-parallel-macos-notarization.md: 18358444426575e27a21f0f56541e22e37fcdf2c -2026-09-09-parallel-macos-notarization.zh.md: a69d586eff1413debe096656a7572a53f0938e98 +/agent-note-parallel-macos-notarization-from-isolated-app-copies: + en: 610808eedf6e8fdd + zh: 2db10903004a3ebd +/agent-note-parallel-macos-notarization-from-isolated-app-copies/problem: + en: 12c2160b03bac5e0 + zh: 2222e4490505f728 +/agent-note-parallel-macos-notarization-from-isolated-app-copies/decision: + en: 9084607b8e5ecba2 + zh: 00d70d13629a7dd4 +/agent-note-parallel-macos-notarization-from-isolated-app-copies/alternatives-considered: + en: 0ec8e4f3902e17e6 + zh: 3df3091fc01ab600 +/agent-note-parallel-macos-notarization-from-isolated-app-copies/consequences: + en: 81b2cc070cc05152 + zh: 30c684868025f994 diff --git a/.agents/notes/implemented/process/2026-09-10-approval-review-workflow-identity.i18n.yaml b/.agents/notes/implemented/process/2026-09-10-approval-review-workflow-identity.i18n.yaml index 2cadc0e736..521e943a63 100644 --- a/.agents/notes/implemented/process/2026-09-10-approval-review-workflow-identity.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-10-approval-review-workflow-identity.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-approval-review-workflow-identity.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-10-approval-review-workflow-identity.md -2026-09-10-approval-review-workflow-identity.md: 77164134e826acdf647db352cf73df2480055505 -2026-09-10-approval-review-workflow-identity.zh.md: 736851d6f3612080fd67ed6b72e1b8b667948d73 +/agent-note-identify-approval-review-workflows-by-file-path: + en: 8a332b9d080f3d62 + zh: 29f1de05d7867a77 +/agent-note-identify-approval-review-workflows-by-file-path/problem: + en: 6b927a7545ac2c48 + zh: 0902f03aa478d5ee +/agent-note-identify-approval-review-workflows-by-file-path/decision: + en: 82802438f1b8d16c + zh: ffe8c1fcbcc39abe +/agent-note-identify-approval-review-workflows-by-file-path/alternatives-considered: + en: f8fdd869a03ac5ff + zh: c355eb36e9cba350 +/agent-note-identify-approval-review-workflows-by-file-path/consequences: + en: 9f31e023a04a7849 + zh: 66831c450af4c88f diff --git a/.agents/notes/implemented/process/2026-09-11-persistence-type-history.i18n.yaml b/.agents/notes/implemented/process/2026-09-11-persistence-type-history.i18n.yaml index 969ab3fd9e..126601f6e3 100644 --- a/.agents/notes/implemented/process/2026-09-11-persistence-type-history.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-11-persistence-type-history.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-persistence-type-history.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-11-persistence-type-history.md -2026-09-11-persistence-type-history.md: 87e87041dd44c4f671409a75c1b374312736342a -2026-09-11-persistence-type-history.zh.md: cfe5c4f7bd1998d4329dc422607cfe33273d1a5a +/agent-note-in-tree-persistence-type-history: + en: 27496d50584a4feb + zh: 1b241d60286a92f3 +/agent-note-in-tree-persistence-type-history/problem: + en: c8e926bfc65d7195 + zh: e0e007960b68fe80 +/agent-note-in-tree-persistence-type-history/decision: + en: 0d6257a57763ad48 + zh: 6ce3cb7228bba27a +/agent-note-in-tree-persistence-type-history/decision/finalized-checkpoints: + en: 7dd42139850de3bf + zh: 0783bff2f0084f71 +/agent-note-in-tree-persistence-type-history/alternatives-considered: + en: 5cdac1b3f15f89f6 + zh: 36cda3b92d31c916 +/agent-note-in-tree-persistence-type-history/consequences: + en: 672c8cb59d291dc2 + zh: cbec90fbca92320a diff --git a/.agents/notes/implemented/process/2026-09-11-production-blame-approval-weight.i18n.yaml b/.agents/notes/implemented/process/2026-09-11-production-blame-approval-weight.i18n.yaml index bbc5adb976..9272a63484 100644 --- a/.agents/notes/implemented/process/2026-09-11-production-blame-approval-weight.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-11-production-blame-approval-weight.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-production-blame-approval-weight.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-11-production-blame-approval-weight.md -2026-09-11-production-blame-approval-weight.md: d9a223c2f332cc110ddd8f6a3f592febe0072987 -2026-09-11-production-blame-approval-weight.zh.md: f4dfc9d4fc5cefcccadb2785f58893ec92043ba7 +/agent-note-weight-approvals-by-changed-production-line-ownership: + en: 40516dee2915ffc3 + zh: 3d58358bc7110df2 +/agent-note-weight-approvals-by-changed-production-line-ownership/problem: + en: 2dbd821b8d65b054 + zh: 9bef2993db51a00d +/agent-note-weight-approvals-by-changed-production-line-ownership/decision: + en: 7dc225f91538ace1 + zh: a22d05ffd8d32b6d +/agent-note-weight-approvals-by-changed-production-line-ownership/alternatives-considered: + en: 5e8af03e3ff6018a + zh: 6b518c8eee8c5172 +/agent-note-weight-approvals-by-changed-production-line-ownership/consequences: + en: 08495483b77771be + zh: a798d4af0eda55fe +/agent-note-weight-approvals-by-changed-production-line-ownership/verification: + en: cb604625373372b9 + zh: f9056d20ab612537 diff --git a/.agents/notes/implemented/process/2026-09-12-default-product-experimental-isolation.i18n.yaml b/.agents/notes/implemented/process/2026-09-12-default-product-experimental-isolation.i18n.yaml index 30118b2276..cf4ae928c6 100644 --- a/.agents/notes/implemented/process/2026-09-12-default-product-experimental-isolation.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-12-default-product-experimental-isolation.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-default-product-experimental-isolation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-12-default-product-experimental-isolation.md -2026-09-12-default-product-experimental-isolation.md: 5c2485e4f737b822088a680b0006f395a5479fa9 -2026-09-12-default-product-experimental-isolation.zh.md: 3a412a491ab8356a4e29d706fed55226dc0f6038 +/agent-note-keep-experimental-packages-outside-the-default-product: + en: 2d1751612781064c + zh: 8be0f776c4a37e11 +/agent-note-keep-experimental-packages-outside-the-default-product/problem: + en: 6938ed9a5ca419bb + zh: 6d2cd6bb912b9118 +/agent-note-keep-experimental-packages-outside-the-default-product/decision: + en: d471671fd6c06d03 + zh: 205586983a29eba4 +/agent-note-keep-experimental-packages-outside-the-default-product/alternatives-considered: + en: b8615d8d31f313d7 + zh: 556e3b96a90f6897 +/agent-note-keep-experimental-packages-outside-the-default-product/consequences: + en: 5ffd5e60d782a0bd + zh: 300665f42d70f049 diff --git a/.agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.i18n.yaml b/.agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.i18n.yaml index 9ec2270d40..0d6fed02a4 100644 --- a/.agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-experimental-publication-denylist.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-12-experimental-publication-denylist.md -2026-09-12-experimental-publication-denylist.md: f19faa1f391628574fd47e3064130e00c26c831a -2026-09-12-experimental-publication-denylist.zh.md: 92a1c6d5cd0f23615f89d4779f2b9a977b1a8438 +/agent-note-publish-experimental-packages-with-explicit-private-exceptions: + en: 20aed7271477745f + zh: 81b50a3ba89b7935 +/agent-note-publish-experimental-packages-with-explicit-private-exceptions/problem: + en: c267b50c3004619f + zh: 91830d04d2972d46 +/agent-note-publish-experimental-packages-with-explicit-private-exceptions/decision: + en: 3cf968834876a655 + zh: 7f7bad8b931a5ed2 +/agent-note-publish-experimental-packages-with-explicit-private-exceptions/alternatives-considered: + en: 61369830fb32e695 + zh: 445eb44e1ae3457a +/agent-note-publish-experimental-packages-with-explicit-private-exceptions/consequences: + en: 23f4d725196f1c2d + zh: ebd9455778d8a89f diff --git a/.agents/notes/implemented/process/2026-09-12-maintained-repository-references.i18n.yaml b/.agents/notes/implemented/process/2026-09-12-maintained-repository-references.i18n.yaml index ee236e6c0b..34379e6e6c 100644 --- a/.agents/notes/implemented/process/2026-09-12-maintained-repository-references.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-12-maintained-repository-references.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-maintained-repository-references.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-12-maintained-repository-references.md -2026-09-12-maintained-repository-references.md: b2bc750100e1aaf2ff63ffc773bbd54997fdf355 -2026-09-12-maintained-repository-references.zh.md: 99216e8105af9d159f6f371c9e31fec6d75a0e75 +/agent-note-maintained-repository-references: + en: 10750a69061b5dd0 + zh: ab4be61612ead1da +/agent-note-maintained-repository-references/problem: + en: 36ca11f2ef3d8b4e + zh: 6e6ca6ae00fab2f7 +/agent-note-maintained-repository-references/decision: + en: ec87568d74d5dc5f + zh: bc34159aeafa9fcd +/agent-note-maintained-repository-references/alternatives-considered: + en: de1c15bc0d404c41 + zh: a32a80be126d3d71 +/agent-note-maintained-repository-references/consequences: + en: 17e87405d1ab8efa + zh: d4dbc337733d9a2d diff --git a/.agents/notes/implemented/process/2026-09-12-publish-all-experimental-packages.i18n.yaml b/.agents/notes/implemented/process/2026-09-12-publish-all-experimental-packages.i18n.yaml index d3452d5d10..3568158aca 100644 --- a/.agents/notes/implemented/process/2026-09-12-publish-all-experimental-packages.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-12-publish-all-experimental-packages.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-publish-all-experimental-packages.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-12-publish-all-experimental-packages.md -2026-09-12-publish-all-experimental-packages.md: 8bef877297d096159fcce60e6b479e12461357f2 -2026-09-12-publish-all-experimental-packages.zh.md: 6163e6b4ac11c46dac3897361585d2fcc29ef746 +/agent-note-publish-every-current-experimental-package: + en: e08e7bc92478407d + zh: 45501f51a5f619ec +/agent-note-publish-every-current-experimental-package/problem: + en: 7db3c27e4b5c2d09 + zh: 0a770941ec41a50a +/agent-note-publish-every-current-experimental-package/decision: + en: cc702e2596b0bd73 + zh: 3815da9b56ae653b +/agent-note-publish-every-current-experimental-package/alternatives-considered: + en: e59c9f8484629e20 + zh: d6f64683af3d0460 +/agent-note-publish-every-current-experimental-package/consequences: + en: 2721ffbcf5341d3b + zh: be0b430b9d91d7c2 diff --git a/.agents/notes/implemented/process/2026-09-15-pr-approval-delegation.i18n.yaml b/.agents/notes/implemented/process/2026-09-15-pr-approval-delegation.i18n.yaml index 640bea7c7b..14bf4d7016 100644 --- a/.agents/notes/implemented/process/2026-09-15-pr-approval-delegation.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-15-pr-approval-delegation.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-pr-approval-delegation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-15-pr-approval-delegation.md -2026-09-15-pr-approval-delegation.md: 4dcf0e8a8d23d66da11381586e376fdf39d23635 -2026-09-15-pr-approval-delegation.zh.md: bf21724d672aaf534bfe94540b76878177eeb57e +/agent-note-pr-scoped-approval-delegation: + en: 3fa5881b5ca14a79 + zh: 99dbde5fae7cdd6a +/agent-note-pr-scoped-approval-delegation/problem: + en: 5fe2f3b3cb7ce046 + zh: ed27d4efc995b8b5 +/agent-note-pr-scoped-approval-delegation/decision: + en: 41c5c90b82d323c6 + zh: 55d5ed09d88bb821 +/agent-note-pr-scoped-approval-delegation/alternatives-considered: + en: a6006217cb29613a + zh: 83968328096f1d91 +/agent-note-pr-scoped-approval-delegation/consequences: + en: e761c382b4431212 + zh: 43bb475b646c85eb diff --git a/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.i18n.yaml b/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.i18n.yaml index 2c5a3f8554..f5e57341df 100644 --- a/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-shipped-optional-bundles.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.md -2026-09-15-shipped-optional-bundles.md: c9f560f5c07ec6fb18030b77a0d1f53bd27dc045 -2026-09-15-shipped-optional-bundles.zh.md: e91b6580e29cd7ae142c9c61ed6aac7e5e1476eb +/agent-note-ship-optional-bundles-with-the-installation: + en: a35c5daebeaa4b1e + zh: a74f44bb23f0571c +/agent-note-ship-optional-bundles-with-the-installation/problem: + en: dc43ba84345e1405 + zh: dbc03572ab7710d2 +/agent-note-ship-optional-bundles-with-the-installation/decision: + en: d64020c4ca4957e1 + zh: 241b3b851234b6f0 +/agent-note-ship-optional-bundles-with-the-installation/alternatives-considered: + en: 05c19f616009bee8 + zh: af318640481351f0 +/agent-note-ship-optional-bundles-with-the-installation/consequences: + en: 4a9d3a049a605150 + zh: 67b50bbc9f7f4bb0 diff --git a/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.md b/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.md index c9f560f5c0..059fe5bcce 100644 --- a/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.md +++ b/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.md @@ -14,7 +14,7 @@ The launcher names in `OPTIONAL_BUNDLES` (`packages/boot/app-boot/src/profile.ts Default-product isolation keeps its rules with one declared exception: an optional bundle's dependency graph is outside the default product. The static gate skips the `dependencies` edge from `@deepseek-ai/dsh` to a listed bundle and still rejects a runtime import, a shipped composition, a preset, or a default template that names it, an experimental dependency the list does not name, and a listed name that is not a runtime dependency or not a bundle. The workspace-constraints check accepts the same `dependencies` edges and no other runtime section, and the packed-install release check skips them from the installed entry package while requiring each listed bundle to be installed. -The [single-bundle decision](../architecture/2026-09-18-agent-teams-single-bundle.md) supersedes the two Agent Teams selections with one `@deepseek-ai/dsh-experimental-agent-team-profile` selection. This note retains the installation-owned optional-bundle policy. Auto review is a published experimental package the page's install guide names as its example, not an optional bundle. +The [single-bundle decision](../architecture/2026-09-18-agent-teams-single-bundle.md) supersedes the two Agent Teams selections with one `@deepseek-ai/dsh-experimental-agent-team-profile` selection. This note retains the installation-owned optional-bundle policy; the [optional-bundle decision for experimental capabilities](../architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md) names the current list and the display metadata each entry carries. ## Alternatives considered diff --git a/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.zh.md b/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.zh.md index e91b6580e2..9847095601 100644 --- a/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.zh.md +++ b/.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.zh.md @@ -14,7 +14,7 @@ Web 插件页只管理用户装进 profile 的组合包。像 Agent Teams 这样 默认产品隔离的规则保持不变,只声明一个例外:可选组合包的依赖图在默认产品之外。静态门禁跳过从 `@deepseek-ai/dsh` 到列表中组合包的 `dependencies` 边,仍然拒绝运行时 import、随附组合、preset 或默认模板对它的引用,拒绝列表没有点名的实验依赖,也拒绝不是运行时依赖或不是组合包的列表项。workspace 约束检查接受同样的 `dependencies` 边而不接受其他运行时依赖段;发布时的 packed-install 检查对已安装入口包跳过这些边,并要求列表中的每个组合包都已安装。 -[单组合包决策](../architecture/2026-09-18-agent-teams-single-bundle.zh.md)将两个 Agent Teams 选项替换为一个 `@deepseek-ai/dsh-experimental-agent-team-profile` 选项。本记录保留由安装方决定可选组合包的策略。Auto review 是一个已发布的实验包,插件页的安装引导拿它作示例,它不是可选组合包。 +[单组合包决策](../architecture/2026-09-18-agent-teams-single-bundle.zh.md)将两个 Agent Teams 选项替换为一个 `@deepseek-ai/dsh-experimental-agent-team-profile` 选项。本记录保留由安装方决定可选组合包的策略;[实验能力的可选 bundle 决策](../architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md)列出当前名单以及每一项携带的显示元数据。 ## 考虑过的替代方案 diff --git a/.agents/notes/implemented/process/2026-09-16-author-approval-credit.i18n.yaml b/.agents/notes/implemented/process/2026-09-16-author-approval-credit.i18n.yaml index b3f403e7b5..cfc6317172 100644 --- a/.agents/notes/implemented/process/2026-09-16-author-approval-credit.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-16-author-approval-credit.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-author-approval-credit.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-16-author-approval-credit.md -2026-09-16-author-approval-credit.md: ab7aba88801271c22a0f054d5b3888726b94e97a -2026-09-16-author-approval-credit.zh.md: 316a09ea5d82f78915a9550fde7f29bd55761e44 +/agent-note-author-approval-credit: + en: 58068bcf9dbf6d30 + zh: ad51b869c8f3e791 +/agent-note-author-approval-credit/problem: + en: 13def594e495779d + zh: d5ceaa0d156ba043 +/agent-note-author-approval-credit/decision: + en: 5670829131121899 + zh: 7df21c9b22c4978d +/agent-note-author-approval-credit/alternatives-considered: + en: 8ab9e11e49044029 + zh: c7930455d747ceb5 +/agent-note-author-approval-credit/consequences: + en: 70ad19025f7fe6d4 + zh: c73aa8be25724790 +/agent-note-author-approval-credit/verification: + en: 0617e23e217b0a67 + zh: 82576f05a59d8db7 diff --git a/.agents/notes/implemented/process/2026-09-16-desktop-release-version-derivation.i18n.yaml b/.agents/notes/implemented/process/2026-09-16-desktop-release-version-derivation.i18n.yaml index 1293c824d8..f25c473733 100644 --- a/.agents/notes/implemented/process/2026-09-16-desktop-release-version-derivation.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-16-desktop-release-version-derivation.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-desktop-release-version-derivation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-16-desktop-release-version-derivation.md -2026-09-16-desktop-release-version-derivation.md: 54a7b9d52c63268f15209ad0a84bcd8da035dcee -2026-09-16-desktop-release-version-derivation.zh.md: dddf4b773217965380c4487803971311b57e0863 +/agent-note-derive-desktop-test-versions-from-the-complete-dsh-version: + en: b4afaf99cba87722 + zh: bd6c3b76efebf932 +/agent-note-derive-desktop-test-versions-from-the-complete-dsh-version/problem: + en: 307dae6b4bdf80de + zh: 72c9045a2e42036f +/agent-note-derive-desktop-test-versions-from-the-complete-dsh-version/decision: + en: 1a3ef4e14511dc1f + zh: 1db763a1323d9c87 +/agent-note-derive-desktop-test-versions-from-the-complete-dsh-version/alternatives-considered: + en: cf86267e11a4e534 + zh: daa4fb017b2725a5 +/agent-note-derive-desktop-test-versions-from-the-complete-dsh-version/consequences: + en: ce62d7f641c0cd45 + zh: 08b05c154f38d816 diff --git a/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.i18n.yaml b/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.i18n.yaml index 45223d0f08..564858250c 100644 --- a/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-17-persistence-schema-review.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-persistence-schema-review.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-17-persistence-schema-review.md -2026-09-17-persistence-schema-review.md: 47308a5584b368c99ee849b6d550538ba1856a09 -2026-09-17-persistence-schema-review.zh.md: eaa3c17991b23612753634297993dd3b951259ab +/agent-note-persistence-schema-policy-and-review: + en: 354306d8acf2141b + zh: 01b9235a77121284 +/agent-note-persistence-schema-policy-and-review/problem: + en: 4dfc8768cd580993 + zh: ad78f2ff4c22b390 +/agent-note-persistence-schema-policy-and-review/decision: + en: ab2a881b58bb6e05 + zh: c6e7b7b9854a0f94 +/agent-note-persistence-schema-policy-and-review/alternatives-considered: + en: 4a73283af97bcd4b + zh: 952cf965d7615737 +/agent-note-persistence-schema-policy-and-review/consequences: + en: eeadd60710998de9 + zh: 5c48f512f1d53d2c diff --git a/.agents/notes/implemented/process/2026-09-17-windows-runtime-signature-cache.i18n.yaml b/.agents/notes/implemented/process/2026-09-17-windows-runtime-signature-cache.i18n.yaml index 0ace5db1f2..4bc132731b 100644 --- a/.agents/notes/implemented/process/2026-09-17-windows-runtime-signature-cache.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-17-windows-runtime-signature-cache.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-windows-runtime-signature-cache.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-17-windows-runtime-signature-cache.md -2026-09-17-windows-runtime-signature-cache.md: e9229e47929664984a92499e54f87bb2166bde9d -2026-09-17-windows-runtime-signature-cache.zh.md: 53b6182170d807843345fa90f962ee18807f2cf2 +/agent-note-windows-runtime-signature-cache: + en: 36e012be8a24f6d3 + zh: 6caabddc72c89c95 +/agent-note-windows-runtime-signature-cache/problem: + en: ee8762f64fbefe3f + zh: 8781828a4b19d862 +/agent-note-windows-runtime-signature-cache/decision: + en: 4c114a4e0c81a753 + zh: 3e05c0fcc9fe637b +/agent-note-windows-runtime-signature-cache/alternatives-considered: + en: f83b7439bb610dd4 + zh: 938ae28e9f269406 +/agent-note-windows-runtime-signature-cache/consequences: + en: 382899114280f46a + zh: c12090b052308163 +/agent-note-windows-runtime-signature-cache/risks: + en: 12b4df69b80bee3d + zh: 9cce7f8a26918f5d diff --git a/.agents/notes/implemented/process/2026-09-17-windows-signature-completion.i18n.yaml b/.agents/notes/implemented/process/2026-09-17-windows-signature-completion.i18n.yaml index c8a392f733..92b7cb3e69 100644 --- a/.agents/notes/implemented/process/2026-09-17-windows-signature-completion.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-17-windows-signature-completion.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-windows-signature-completion.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-17-windows-signature-completion.md -2026-09-17-windows-signature-completion.md: e9c81531633a41c87ea10c9e4af2999923aa4470 -2026-09-17-windows-signature-completion.zh.md: 3142749db309b638676c171d4b1da8bd34729fe4 +/agent-note-separate-windows-hardware-signing-from-timestamp-completion: + en: 1e28eec77c3e64c0 + zh: 59e5a5cd5b377949 +/agent-note-separate-windows-hardware-signing-from-timestamp-completion/problem: + en: 7fbde4e99b78b965 + zh: 9137ec46c0645b25 +/agent-note-separate-windows-hardware-signing-from-timestamp-completion/decision: + en: deb7b785a51ef40f + zh: 751965c28a9c303f +/agent-note-separate-windows-hardware-signing-from-timestamp-completion/alternatives-considered: + en: ee16de94898ac51e + zh: c6f1de465d8bb261 +/agent-note-separate-windows-hardware-signing-from-timestamp-completion/consequences: + en: 9e228d85054ce3e8 + zh: f5d6af6411bc3b13 diff --git a/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.i18n.yaml b/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.i18n.yaml index be42dfe317..e36a2aa1c1 100644 --- a/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-evidence-led-simplification-surveys.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.md -2026-09-19-evidence-led-simplification-surveys.md: c217f80239690ee2f7310ca8e97956ec06fb75c7 -2026-09-19-evidence-led-simplification-surveys.zh.md: 1b1a11731967c87ab54aa9eba82253f90bb2abde +/agent-note-evidence-led-simplification-surveys: + en: f0941223baf75c96 + zh: b3cc733f7f90509a +/agent-note-evidence-led-simplification-surveys/problem: + en: 528a0c462d456493 + zh: a2af4901a8f498a7 +/agent-note-evidence-led-simplification-surveys/decision: + en: 865cfb210f13b188 + zh: 777d8155216d98c6 +/agent-note-evidence-led-simplification-surveys/historical-evidence: + en: 53eea2f1d7560461 + zh: 3c55432d9cd3ebe3 +/agent-note-evidence-led-simplification-surveys/bounded-survey-evidence: + en: 3637438d2ed7f606 + zh: d78b39ae6b67a442 +/agent-note-evidence-led-simplification-surveys/alternatives-considered: + en: 9e0039e0ff82ba1b + zh: fa4b0a52bf3dcbdd +/agent-note-evidence-led-simplification-surveys/consequences: + en: 395acde9597898c5 + zh: 45ee94d13427862a diff --git a/.agents/notes/implemented/process/2026-09-19-no-unknown-casts.i18n.yaml b/.agents/notes/implemented/process/2026-09-19-no-unknown-casts.i18n.yaml index 29002959bc..d6f0972f92 100644 --- a/.agents/notes/implemented/process/2026-09-19-no-unknown-casts.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-19-no-unknown-casts.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-no-unknown-casts.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-19-no-unknown-casts.md -2026-09-19-no-unknown-casts.md: 2f90422d0980fddc2569951ef7f8dba34b488ce4 -2026-09-19-no-unknown-casts.zh.md: 3b66236e586a60a61cdcc1f93b1c0c14ce27eb15 +/agent-note-prohibit-new-assertions-to-unknown: + en: d05b7f323025e1b9 + zh: fa84da1b6dbbd40a +/agent-note-prohibit-new-assertions-to-unknown/problem: + en: de8fd99f06ce9378 + zh: 627e67ac20b16e56 +/agent-note-prohibit-new-assertions-to-unknown/decision: + en: 426df6b19b654021 + zh: f4d8c678f9760139 +/agent-note-prohibit-new-assertions-to-unknown/alternatives-considered: + en: 1080f8f62795b113 + zh: bee2b837e7ae0de4 +/agent-note-prohibit-new-assertions-to-unknown/consequences: + en: ab7350f789864067 + zh: 9867a9baaa1c6227 diff --git a/.agents/notes/implemented/process/2026-09-21-desktop-build-version-as-input.i18n.yaml b/.agents/notes/implemented/process/2026-09-21-desktop-build-version-as-input.i18n.yaml index a5fb8f7ea7..32be76bd93 100644 --- a/.agents/notes/implemented/process/2026-09-21-desktop-build-version-as-input.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-21-desktop-build-version-as-input.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-21-desktop-build-version-as-input.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-21-desktop-build-version-as-input.md -2026-09-21-desktop-build-version-as-input.md: 8653c1ed580ac360e0c2f5145781303f15fc29b2 -2026-09-21-desktop-build-version-as-input.zh.md: 0a995ab5740a73de00b2a417d07640b3c07e4690 +/agent-note-pass-the-desktop-build-version-as-an-argument-instead-of-rewriting-manifests: + en: 300e3ca5e8255a56 + zh: 59f948ca2440d33b +/agent-note-pass-the-desktop-build-version-as-an-argument-instead-of-rewriting-manifests/problem: + en: 9f373ce939732eb2 + zh: a021c3f432d10fbe +/agent-note-pass-the-desktop-build-version-as-an-argument-instead-of-rewriting-manifests/decision: + en: be9fa7f7e85134f1 + zh: 51796ebbdfffc063 +/agent-note-pass-the-desktop-build-version-as-an-argument-instead-of-rewriting-manifests/alternatives-considered: + en: b5025ea37e2908bc + zh: 6f2ebcaa138f1c62 +/agent-note-pass-the-desktop-build-version-as-an-argument-instead-of-rewriting-manifests/consequences: + en: 686a5979332c0964 + zh: 89cff9e1e04e0325 diff --git a/.agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.i18n.yaml b/.agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.i18n.yaml new file mode 100644 index 0000000000..0cd788f54a --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-22-desktop-main-bundle-after-workspace-tsdown.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.md +/agent-note-bundle-the-desktop-main-process-after-the-workspace-tsdown-pass: + en: 47f6a531ef05a7be + zh: 18dc33bcd916e2b5 +/agent-note-bundle-the-desktop-main-process-after-the-workspace-tsdown-pass/problem: + en: dc5156548e545037 + zh: 72010884a2a27877 +/agent-note-bundle-the-desktop-main-process-after-the-workspace-tsdown-pass/decision: + en: 9b3c9c696207b13e + zh: 4996ad87dd07d839 +/agent-note-bundle-the-desktop-main-process-after-the-workspace-tsdown-pass/alternatives-considered: + en: a15cfe689823ae57 + zh: 1d691cd335bdcb87 +/agent-note-bundle-the-desktop-main-process-after-the-workspace-tsdown-pass/consequences: + en: e46c28e2ba972cfb + zh: 70d4076a89e0b2ec diff --git a/.agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.md b/.agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.md new file mode 100644 index 0000000000..3c997f0707 --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.md @@ -0,0 +1,29 @@ +# Agent Note: Bundle the Desktop main process after the workspace tsdown pass + +Status: implemented + +English | [中文](2026-09-22-desktop-main-bundle-after-workspace-tsdown.zh.md) + +## Problem + +A macOS Desktop package built from a fresh worktree crashed at launch with `ERR_MODULE_NOT_FOUND: Cannot find package '@deepseek-ai/dsh-home-paths' imported from app.asar/lib/main.js`. The packaging log showed why: rolldown had reported `[UNRESOLVED_IMPORT] Could not resolve '@deepseek-ai/dsh-home-paths' … treating it as an external dependency`, and the same for `@deepseek-ai/dsh-app-boot` and `@deepseek-ai/dsh-deepseek-account`. The three packages are workspace devDependencies of `apps/desktop` that the main-process bundle must inline, because electron-builder copies only the manifest's `dependencies` into `app.asar/node_modules`. + +The root tsdown config builds every matched workspace member concurrently (`Promise.all` over the resolved configs in tsdown 0.22, with no dependency ordering), and `apps/desktop` was one of those members. Its bundle resolved the three packages through their `exports` to `lib/index.js` files that other concurrent builds had not written yet. On a checkout that had been built before, the stale `lib/` outputs existed and the bundle inlined them, which is why the defect surfaced only on a clean tree; `clean: false` in both configs kept it hidden. The broken bundle was also smaller (189 KB instead of 315 KB) and the packaging run passed every existing check, because the runtime payload smoke exercises the dsh runtime, not the Electron main process. + +## Decision + +`apps/desktop` leaves the root tsdown `workspace` list. The root `build:lib:host` script runs the Host tsdown pass and then `pnpm --filter @deepseek-ai/dsh-desktop run bundle`, so the main bundle resolves workspace `lib/` outputs that already exist. The package's own `build` script keeps the same `tsc -b` then `bundle` order for local use. A standalone run of the Desktop config produces byte-identical output to the former workspace-mode run: the config was already self-contained, and the root plugins contributed nothing to it. + +The Desktop config also asserts the invariant the crash violated. [`desktop-bundle-imports`](../../../../apps/desktop/scripts/desktop-bundle-imports.mjs) is a rolldown plugin on every Desktop bundle whose `moduleParsed` hook fails the build when a module imports a bare specifier the packaged application cannot resolve, whether through a static import, a dynamic `import()`, or a `require()` call: the main bundle may import `electron`, Node builtins, and the manifest's `dependencies`; a sandboxed preload only `electron`, `events`, `timers`, and `url`, the modules Electron's sandbox `require` polyfill resolves. The hook reads each module's import records, where an external import keeps its bare specifier and a bundled one carries an absolute id; chunk metadata (`imports`/`dynamicImports`) omits external `import()` and `require()` targets and cannot serve the check. The check names the actual requirement rather than the symptom, so it also rejects a workspace package moved out of `dependencies` or a broken `exports` entry, and a rejected bundle writes no output. + +## Alternatives considered + +**Declare the three packages as runtime `dependencies` so electron-builder ships them in the asar.** This is how `@deepseek-ai/cordis` and `@deepseek-ai/dsh-api-gateway` reach the asar today, and it removes the ordering problem. `dsh-app-boot` would bring a large dependency tree into `app.asar/node_modules`, duplicating the copy already inside the packed dsh runtime and enlarging the payload the runtime file policy must screen. + +**Fail on rolldown's `UNRESOLVED_IMPORT` warning** through `inputOptions.onLog` or `failOnWarn`. It catches only the unresolved case and would not have covered a dependency misdeclared as a devDependency, which produces a resolved, inlined bundle when the output exists and an external import when it does not. The packaged-imports check covers both with one rule. + +**Order the workspace build by dependency graph.** tsdown offers no such ordering, and every other member either inlines nothing from the workspace or externalizes declared `dependencies`, which need no ordering. One extra step for the one package that needs it is smaller than a general scheduler. + +## Consequences + +A clean checkout, including CI and a fresh worktree, produces the same Desktop main bundle as a long-lived one. A missing or misdeclared runtime import now fails `pnpm run build` and every packaging command with the importing module and the offending specifiers, before signing and notarization spend their time. The Host build gains one sequential step of about a second on a development machine. `docs/development.md` lists the desktop bundle step in the root build order, `scripts/wine-windows-gates.sh` mirrors it, and the [Desktop README](../../../../apps/desktop/README.md#bundled-workspace-dependencies) owns the import rule. diff --git a/.agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.zh.md b/.agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.zh.md new file mode 100644 index 0000000000..3f741125f6 --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.zh.md @@ -0,0 +1,29 @@ +# Agent Note:Desktop 主进程在工作区 tsdown 阶段之后再打 bundle + +Status: implemented + +[English](2026-09-22-desktop-main-bundle-after-workspace-tsdown.md) | 中文 + +## 问题 + +从全新 worktree 打出的 macOS Desktop 安装包启动即崩:`ERR_MODULE_NOT_FOUND: Cannot find package '@deepseek-ai/dsh-home-paths' imported from app.asar/lib/main.js`。打包日志给出了原因:rolldown 报告了 `[UNRESOLVED_IMPORT] Could not resolve '@deepseek-ai/dsh-home-paths' … treating it as an external dependency`,`@deepseek-ai/dsh-app-boot` 与 `@deepseek-ai/dsh-deepseek-account` 也是同样情况。这三个包是 `apps/desktop` 的工作区 devDependencies,主进程 bundle 必须把它们内联,因为 electron-builder 只把清单中的 `dependencies` 复制进 `app.asar/node_modules`。 + +根 tsdown 配置并发构建所有匹配到的 workspace 成员(tsdown 0.22 对解析出的配置做 `Promise.all`,没有任何依赖排序),而 `apps/desktop` 是其中一员。它的 bundle 通过这三个包的 `exports` 解析到 `lib/index.js`,而其他并发构建此时还没有写出这些文件。在此前构建过的检出目录里,陈旧的 `lib/` 产物存在,bundle 会把它们内联,因此缺陷只在干净树上出现;两份配置里的 `clean: false` 一直掩盖着它。坏的 bundle 也更小(189 KB 而不是 315 KB),并且打包流程通过了所有已有检查,因为运行时载荷 smoke 检验的是 dsh 运行时,不是 Electron 主进程。 + +## 决策 + +`apps/desktop` 退出根 tsdown 的 `workspace` 列表。根 `build:lib:host` 脚本先跑 Host tsdown 阶段,再执行 `pnpm --filter @deepseek-ai/dsh-desktop run bundle`,让主进程 bundle 解析的是已经存在的工作区 `lib/` 产物。该包自己的 `build` 脚本为本地使用保留同样的先 `tsc -b` 再 `bundle` 的顺序。单独运行 Desktop 配置得到的产物与此前 workspace 模式下的产物逐字节一致:该配置本来就是自足的,根配置的插件没有为它贡献任何内容。 + +Desktop 配置同时断言这次崩溃所违反的不变量。[`desktop-bundle-imports`](../../../../apps/desktop/scripts/desktop-bundle-imports.mjs) 是挂在每个 Desktop bundle 上的 rolldown 插件,其 `moduleParsed` 钩子在某个模块以静态 import、动态 `import()` 或 `require()` 导入了打包应用无法解析的裸说明符时让构建失败:主进程 bundle 可以导入 `electron`、Node 内置模块与清单的 `dependencies`;沙箱 preload 只能导入 `electron`、`events`、`timers` 与 `url`,即 Electron 沙箱 `require` polyfill 能解析的模块。该钩子读取每个模块的导入记录,其中外部导入保留裸说明符、被打包的导入带有绝对 id;chunk 元数据(`imports`/`dynamicImports`)不包含外部的 `import()` 与 `require()` 目标,无法用于这项检查。这项检查陈述的是真正的要求而非症状,因此它同样拒绝被移出 `dependencies` 的工作区包或损坏的 `exports` 条目,且被拒绝的 bundle 不写出任何产物。 + +## 备选方案 + +**把这三个包声明为运行时 `dependencies`,让 electron-builder 装进 asar。** `@deepseek-ai/cordis` 与 `@deepseek-ai/dsh-api-gateway` 今天就是这样进入 asar 的,这也消除了顺序问题。但 `dsh-app-boot` 会把一棵很大的依赖树带进 `app.asar/node_modules`,与 packed dsh 运行时内已有的副本重复,并扩大运行时文件策略必须筛查的载荷。 + +**通过 `inputOptions.onLog` 或 `failOnWarn` 让 rolldown 的 `UNRESOLVED_IMPORT` warning 直接失败。** 它只覆盖未解析这一种情况,覆盖不了被误声明为 devDependency 的依赖:产物存在时它会被解析并内联,不存在时才留成外部导入。打包导入检查用一条规则同时覆盖两者。 + +**按依赖图给 workspace 构建排序。** tsdown 不提供这种排序,而其他每个成员要么不从工作区内联任何内容,要么把已声明的 `dependencies` 留成外部导入,都不需要排序。为唯一需要它的包多加一步,比通用调度器更小。 + +## 后果 + +干净的检出目录(包括 CI 与全新 worktree)产出的 Desktop 主进程 bundle 与长期使用的检出目录一致。缺失或误声明的运行时导入现在会让 `pnpm run build` 和每条打包命令在签名与公证耗时之前失败,并报出导入方模块与违规说明符。Host 构建多出一个串行步骤,在开发机上约一秒。`docs/development.md` 在根构建顺序中列出了 desktop bundle 步骤,`scripts/wine-windows-gates.sh` 与之保持一致,导入规则由 [Desktop README](../../../../apps/desktop/README.zh.md#bundled-workspace-dependencies) 负责。 diff --git a/.agents/notes/implemented/process/2026-09-22-workspace-release-ranges.i18n.yaml b/.agents/notes/implemented/process/2026-09-22-workspace-release-ranges.i18n.yaml index 528c760888..05753024a2 100644 --- a/.agents/notes/implemented/process/2026-09-22-workspace-release-ranges.i18n.yaml +++ b/.agents/notes/implemented/process/2026-09-22-workspace-release-ranges.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-22-workspace-release-ranges.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-22-workspace-release-ranges.md -2026-09-22-workspace-release-ranges.md: 57c74df3eaeac16ba40f55cdc4069762ae8fe2ef -2026-09-22-workspace-release-ranges.zh.md: f39ede4fb1941956af12d0391f5b88bd244db6f8 +/agent-note-workspace-dependency-release-ranges: + en: 8b7bf2179034aa08 + zh: a7a8b5dc60849d88 +/agent-note-workspace-dependency-release-ranges/problem: + en: ea71dd3eea6e1c60 + zh: 2a8ea98e8f6a3fbf +/agent-note-workspace-dependency-release-ranges/decision: + en: c7e9c7eb5b3e2ebf + zh: b74ef023fc894e36 +/agent-note-workspace-dependency-release-ranges/alternatives-considered: + en: b6aa87296ee61fcf + zh: f516320e589ce7a3 +/agent-note-workspace-dependency-release-ranges/consequences: + en: 49eac7a43407bbd9 + zh: 8a39766e8df596b8 diff --git a/.agents/notes/implemented/process/2026-09-23-section-keyed-translation-pairing-records.i18n.yaml b/.agents/notes/implemented/process/2026-09-23-section-keyed-translation-pairing-records.i18n.yaml new file mode 100644 index 0000000000..f05c998dde --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-23-section-keyed-translation-pairing-records.i18n.yaml @@ -0,0 +1,25 @@ +# Bilingual-pair consistency record for 2026-09-23-section-keyed-translation-pairing-records.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-23-section-keyed-translation-pairing-records.md +/agent-note-section-keyed-translation-pairing-records: + en: fe3ee02933f0e25b + zh: 3518b378aebef215 +/agent-note-section-keyed-translation-pairing-records/problem: + en: 1662619f5cc6743f + zh: e98e9b39e82a2294 +/agent-note-section-keyed-translation-pairing-records/decision: + en: 333d08badeeef8a6 + zh: 2ccb1fe95b3457ff +/agent-note-section-keyed-translation-pairing-records/alternatives-considered: + en: 3e17a6963d74e3de + zh: cc086da130648d3c +/agent-note-section-keyed-translation-pairing-records/consequences: + en: 7a1f77c69ef79755 + zh: 7f12bd25f556ba9c +/agent-note-section-keyed-translation-pairing-records/measured-effect: + en: 97af2f09c25338f1 + zh: 2ec62a414fa61254 +/agent-note-section-keyed-translation-pairing-records/related: + en: 8f208df4c003e06e + zh: c1660f5b55dea743 diff --git a/.agents/notes/implemented/process/2026-09-23-section-keyed-translation-pairing-records.md b/.agents/notes/implemented/process/2026-09-23-section-keyed-translation-pairing-records.md new file mode 100644 index 0000000000..e01eac4bbc --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-23-section-keyed-translation-pairing-records.md @@ -0,0 +1,56 @@ +# Agent Note: Section-keyed translation pairing records + +Status: implemented + +English | [中文](2026-09-23-section-keyed-translation-pairing-records.zh.md) + +## Problem + +A consistency record held the full blob hash of each language file. Any edit to a pair changed both lines, so two branches that edited different parts of the same pair always conflicted on the record, even when Git merged both Markdown files cleanly. Generated references such as `docs/config-catalog.md`, `docs/module-graph.md`, and `docs/event-producer-consumer.md` were affected most: most PRs that touch packages, config, or events regenerate one of them, and each regeneration also required a hand-copied Chinese update and a new record. A worktree-local merge driver composed such records, but GitHub's mergeability check never runs it, so PRs still showed a conflict until someone merged the base locally and pushed. + +## Decision + +`foo.i18n.yaml` holds one entry per heading section that contains hashed content. `verify-translation-pairing` computes the entries; `scripts/translation-pairing-record.ts` owns the format. + +- Both sides are split at every heading. Section `i` of the English file corresponds to section `i` of the Chinese file; different heading counts are a structure error and cannot be recorded. +- The key is the English heading-slug path, such as `/plugin-config-catalog/loadable-plugins-with-no-config`. Text before the first heading is `/`, and a repeated path gets `~2`, `~3`, and so on. Keys are counted over every section, including sections without entries, so a key depends only on headings. +- Each side's hash covers the section's top-level blocks after paired-document link localization, except fenced code blocks and generated regions. Those two kinds of content are exactly what the pairing gate already requires to be identical on both sides; any other content is hashed even when it happens to be identical. The entry holds a 16-hex SHA-256 prefix of each side's hashed blocks. A section with no hashed blocks has no entry. +- Each entry spans three lines: an unchanged key line followed by the `en:` and `zh:` hash lines. The key line separates neighboring entries, so Git's text merge treats changes to adjacent entries as separate hunks. + +A record conflict therefore requires both branches to change hashed content in the same section. + +Generators put their generated data in generated regions and write each region into both pages, so regeneration changes neither the record nor the Chinese prose. `gen-config-catalog` writes both languages and the record, with one region per package and one per package table; labels inside a region are the code identifiers `inject`, `refs`, `source`, and `class`, which the translated introduction explains. `gen-module-graph` keeps its table in a region with identifier column headers. `gen-doc-graphs` splices the event matrix tables into the authored Chinese page, and `gen-cordis-catalog` already did the same for subsystem regions. + +`gen-translation-brief` recovers the last-confirmed text from the newest commit of the pair whose contents produce the committed record. Records no longer point to Git blobs, and `--write` no longer stores snapshot objects or refs. + +Archived Agent Notes keep their sealed whole-file records; `verify-archived-agent-notes` owns that format. + +## Alternatives considered + +**Keep whole-file hashes and the merge driver.** The driver resolved the conflict only in local worktrees where it was installed. GitHub still reported the PR as conflicted, raw merges without the installed runtime stopped, and the driver, resolver, installer integration, and their tests were about 1,400 lines of code to maintain. + +**One entry per top-level block instead of per heading section.** Fewer false conflicts inside long sections, but the record would grow to roughly the block count of the document. Positional block keys would also renumber on every insertion and create conflicts of their own. + +**Positional section keys (`h2[3]`).** Inserting a section renumbers every later key and changes every later record line, which recreates the conflicts this format removes. Heading-slug keys change only when that heading's English text changes. + +**Resolve on GitHub through Actions or an app.** Hosted automation would need credentials, concurrency control, and permission to rewrite PR branches. A record that Git's default text merge composes needs none of these. + +**Hash whole sections, including code blocks and regions.** Every regenerated row or code block would still change a record line, so generated references would keep conflicting on their largest sections. + +**Leave out any block that is byte-identical on both sides.** It also keeps generated rows out of the record, but it decides implicitly what needs no translation: an English paragraph copied untranslated into the Chinese file would be left out too, and a later edit to it would no longer change the record. Code blocks and generated regions are declared shared content that existing gates check. + +## Consequences + +Edits to different sections, and regenerated regions and code blocks, merge without a local tool, including on GitHub. Replaying the merge commits reachable from `master` between 2026-08-20 and 2026-09-23 shows the effect on real history: see [Measured effect](#measured-effect). + +A same-section conflict is resolved by resolving the Markdown and re-running `verify-translation-pairing --write `; no command automates it. Chinese readers of generated regions see code identifiers and English table headers instead of translated labels. Recovering last-confirmed text for the brief requires the confirmed pair to be committed. + +## Measured effect + +The replay covered 2016 two-parent merge commits reachable from `master` between 2026-08-20 and 2026-09-23, most of them PR branches merging the base forward. For every active pair whose record both parents changed, it ran Git's default text merge on the old record, on the section-keyed record computed from the same commit contents, and on the two Markdown files. It counts a record whose headings did not align at some commit as a conflict. The old format conflicted in 2950 pair merges across 850 merge commits; the section-keyed format conflicts in 1586 pair merges across 595 merge commits, a 46% reduction per pair. The Markdown files themselves conflicted in 926 pair merges across 338 merge commits, which no record format can avoid. Merge commits whose only conflicts were records fell from 512 to 257 (50%). + +The replay uses each commit's content as it was, before the generators wrapped their data in regions, so `docs/module-graph.md` (277 conflicts), `docs/event-producer-consumer.md` (220), and `docs/config-catalog.md` (110) still conflict on generated data in it. With that data in regions, their records change only when their prose changes; excluding their generated rows from the same replay left 0 and 14 conflicts for the first two. Substituting that for the three pages projects about 990 pair conflicts, about 66% below the old format; this projection is an estimate, not a replayed measurement. + +## Related + +The [bilingual pairing gate Agent Note](2026-07-02-bilingual-docs-and-pairing-gate.md) owns the three-file pair and its equal-authority rule; this note replaces its whole-file hash record. The [archived automatic pairing merges Agent Note](../../archived/process/2026-08-08-automatic-translation-pairing-merges.md) records the retired merge driver. diff --git a/.agents/notes/implemented/process/2026-09-23-section-keyed-translation-pairing-records.zh.md b/.agents/notes/implemented/process/2026-09-23-section-keyed-translation-pairing-records.zh.md new file mode 100644 index 0000000000..e4746a5092 --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-23-section-keyed-translation-pairing-records.zh.md @@ -0,0 +1,56 @@ +# Agent Note: 按分节记录翻译配对 + +Status: implemented + +[English](2026-09-23-section-keyed-translation-pairing-records.md) | 中文 + +## Problem + +一致性记录过去保存每个语言文件完整的 blob hash。对配对的任何修改都会改动这两行,因此两个分支即使修改同一配对的不同部分、Git 也能干净合并两个 Markdown 文件,记录仍然必然冲突。受影响最大的是 `docs/config-catalog.md`、`docs/module-graph.md` 和 `docs/event-producer-consumer.md` 等生成参考文档:大多数涉及包、配置或事件的 PR 都会重新生成其中之一,而每次重新生成还要求手工复制中文更新并写入新记录。worktree 本地的合并驱动可以组合这类记录,但 GitHub 的可合并性检查从不运行它,因此在有人于本地合并基线分支并推送之前,PR 仍显示冲突。 + +## Decision + +`foo.i18n.yaml` 为每个含有计入 hash 内容的标题分节保存一个条目。`verify-translation-pairing` 计算这些条目;`scripts/translation-pairing-record.ts` 负责该格式。 + +- 两侧都在每个标题处切分。英文文件的第 `i` 个分节对应中文文件的第 `i` 个分节;标题数量不同属于结构错误,无法记录。 +- 键是英文标题 slug 组成的路径,例如 `/plugin-config-catalog/loadable-plugins-with-no-config`。第一个标题之前的文本为 `/`,重复路径依次加 `~2`、`~3` 等后缀。键的计数覆盖每个分节(包括没有条目的分节),因此键只取决于标题。 +- 每侧的 hash 覆盖该分节在配对文档链接本地化后的顶层块,只排除围栏代码块和生成区域。这两类内容正是配对门禁已要求两侧一致的内容;其他内容即使碰巧相同也计入 hash。条目保存每侧计入 hash 的块的 SHA-256 前 16 位十六进制值。没有计入 hash 的块的分节没有条目。 +- 每个条目占三行:一行不变的键,后跟 `en:` 与 `zh:` 两行 hash。键行把相邻条目隔开,因此 Git 文本合并把对相邻条目的修改视为不同的 hunk。 + +因此,只有两个分支都修改了同一分节中计入 hash 的内容时,记录才会冲突。 + +生成器把生成数据放在生成区域中,并把每个区域写入两种语言的页面,因此重新生成既不改变记录,也不改变中文说明文字。`gen-config-catalog` 写出两种语言和记录,每个包一个区域,每个包表格一个区域;区域内的标签是代码标识符 `inject`、`refs`、`source` 和 `class`,由已翻译的介绍段落解释。`gen-module-graph` 把表格放在区域中,列头使用标识符。`gen-doc-graphs` 把事件矩阵的表格写入人工撰写的中文页面,`gen-cordis-catalog` 已经以同样方式处理子系统区域。 + +`gen-translation-brief` 从配对的提交中找到内容能生成已提交记录的最新提交,并从中还原上次确认的文本。记录不再指向 Git blob,`--write` 也不再存储快照对象或 ref。 + +已归档的 Agent Note 保留其已封存的整文件记录;该格式由 `verify-archived-agent-notes` 负责。 + +## Alternatives considered + +**保留整文件 hash 和合并驱动。** 驱动只在已安装它的本地 worktree 中解决冲突。GitHub 仍把 PR 报告为冲突,未安装运行时的原始合并会停止,而驱动、解决命令、安装脚本集成及其测试共约 1,400 行需要维护的代码。 + +**按顶层块而非按标题分节记录条目。** 长分节内的误报冲突更少,但记录会增长到约等于文档的块数。按位置编号的块键还会在每次插入时重新编号,自身又制造冲突。 + +**按位置编号的分节键(`h2[3]`)。** 插入一个分节会让之后的每个键重新编号,并改动之后的每一行记录,重新造成这种格式要消除的冲突。标题 slug 键只在该标题的英文文本改变时才改变。 + +**通过 Actions 或 GitHub App 在 GitHub 上解决。** 托管自动化需要凭证、并发控制以及改写 PR 分支的权限。Git 默认文本合并即可组合的记录不需要这些。 + +**对整个分节(包括代码块和区域)取 hash。** 每次重新生成的行或代码块仍会改动一行记录,因此生成参考文档最大的分节仍会冲突。 + +**排除两侧逐字节相同的任何块。** 这同样能让生成的行不进入记录,但它隐式地判定哪些内容不需要翻译:原样复制到中文文件而未翻译的英文段落也会被排除,之后对它的修改也不再改变记录。代码块和生成区域是现有门禁已检查的、明确声明的共享内容。 + +## Consequences + +对不同分节的修改,以及重新生成的区域和代码块,无需本地工具即可合并,在 GitHub 上也是如此。重放 2026-08-20 至 2026-09-23 期间可从 `master` 到达的合并提交可以看到它在真实历史上的效果:见[实测效果](#measured-effect)。 + +同一分节的冲突需要先解决 Markdown 冲突,再重新运行 `verify-translation-pairing --write `;没有命令会自动完成。生成区域的中文读者看到的是代码标识符和英文表头,而不是译文标签。为 brief 还原上次确认的文本,要求已确认的配对已经提交。 + +## Measured effect + +重放覆盖了 2026-08-20 至 2026-09-23 期间可从 `master` 到达的 2016 个双父合并提交,其中大多数是 PR 分支向前合并基线分支。对两个父提交都修改了其记录的每个活跃配对,它分别对旧记录、根据同一提交内容计算出的按分节记录,以及两个 Markdown 文件运行 Git 默认文本合并。某个提交中标题未对齐而无法计算的记录计为冲突。旧格式在 850 个合并提交中的 2950 次配对合并里冲突;按分节格式在 595 个合并提交中的 1586 次配对合并里冲突,按配对计减少 46%。Markdown 文件本身在 338 个合并提交中的 926 次配对合并里冲突,这部分任何记录格式都无法避免。只有记录冲突的合并提交从 512 个降到 257 个(减少 50%)。 + +重放使用各提交当时的内容,那时生成器还未把数据放进区域,因此 `docs/module-graph.md`(277 次)、`docs/event-producer-consumer.md`(220 次)和 `docs/config-catalog.md`(110 次)仍因其中的生成数据冲突。数据放进区域后,它们的记录只在说明文字改变时才变;在同一重放中排除其生成行后,前两者分别剩 0 次和 14 次冲突。用这一结果替换这三个页面后,预计约 990 次配对冲突,比旧格式少约 66%;这是估算,不是重放实测。 + +## Related + +[双语配对门禁 Agent Note](2026-07-02-bilingual-docs-and-pairing-gate.zh.md) 负责三文件配对及其两种语言同权的规则;本文取代其中的整文件 hash 记录。[已归档的自动配对合并 Agent Note](../../archived/process/2026-08-08-automatic-translation-pairing-merges.md) 记录已退役的合并驱动。 diff --git a/.agents/notes/implemented/simplification/2026-06-20-collapse-trace-only-session-events.i18n.yaml b/.agents/notes/implemented/simplification/2026-06-20-collapse-trace-only-session-events.i18n.yaml index a7506a8eeb..be5d21a505 100644 --- a/.agents/notes/implemented/simplification/2026-06-20-collapse-trace-only-session-events.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-06-20-collapse-trace-only-session-events.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-20-collapse-trace-only-session-events.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-06-20-collapse-trace-only-session-events.md -2026-06-20-collapse-trace-only-session-events.md: f83d93a899d59eb3ebb3f22f36e32aa7865bf902 -2026-06-20-collapse-trace-only-session-events.zh.md: e53544aed0d3b88c7eb85cd1e9a4f12af7686256 +/agent-note-fold-trace-only-session-facts-into-load-bearing-events: + en: e7ada88fff270fa2 + zh: 501f2d2ab2122718 +/agent-note-fold-trace-only-session-facts-into-load-bearing-events/problem: + en: 909f9925807d0e0a + zh: eba8fb3aba92caa8 +/agent-note-fold-trace-only-session-facts-into-load-bearing-events/decision: + en: d07841a539028e7a + zh: 5ebaef62105a0da8 +/agent-note-fold-trace-only-session-facts-into-load-bearing-events/alternatives-considered: + en: f99cc05ab13c85c3 + zh: 93c92b3894cee7b1 +/agent-note-fold-trace-only-session-facts-into-load-bearing-events/verification: + en: 67e74bfc51b0a1ed + zh: dfdc9364ec831b9f +/agent-note-fold-trace-only-session-facts-into-load-bearing-events/consequences: + en: 1c0e59938ce8408f + zh: 8c891d273da28f27 +/agent-note-fold-trace-only-session-facts-into-load-bearing-events/implementation-note: + en: 40e0c79252a438bc + zh: 27332c259b4bdf95 diff --git a/.agents/notes/implemented/simplification/2026-06-20-unify-agent-and-session-id.i18n.yaml b/.agents/notes/implemented/simplification/2026-06-20-unify-agent-and-session-id.i18n.yaml index 6b7315b167..3e2757185e 100644 --- a/.agents/notes/implemented/simplification/2026-06-20-unify-agent-and-session-id.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-06-20-unify-agent-and-session-id.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-20-unify-agent-and-session-id.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-06-20-unify-agent-and-session-id.md -2026-06-20-unify-agent-and-session-id.md: 4084912f95aa2354e815a1b4c05cd7f90bd3c315 -2026-06-20-unify-agent-and-session-id.zh.md: 3adba379f12a46e6f151e6777e0a63f4b16e9cd6 +/agent-note-unify-the-agent-id-and-the-session-id: + en: a3b5f1ad744e332a + zh: f56748eb6f1c1e8f +/agent-note-unify-the-agent-id-and-the-session-id/problem: + en: 13081f69bc061561 + zh: 6062223de9302202 +/agent-note-unify-the-agent-id-and-the-session-id/decision: + en: 58fe3d6c1fbe5aff + zh: 564332602546955e +/agent-note-unify-the-agent-id-and-the-session-id/alternatives-considered: + en: 5dba32bffc8ba6f4 + zh: 4e0d6f084e94eaa3 +/agent-note-unify-the-agent-id-and-the-session-id/verification: + en: bb4f738c649a2d9f + zh: dd46752393643444 +/agent-note-unify-the-agent-id-and-the-session-id/consequences: + en: 38daf65318d286fb + zh: 620933bffd049c42 diff --git a/.agents/notes/implemented/simplification/2026-06-26-fsspec-style-fs-seam.i18n.yaml b/.agents/notes/implemented/simplification/2026-06-26-fsspec-style-fs-seam.i18n.yaml index f45df2a68a..413cf22c2d 100644 --- a/.agents/notes/implemented/simplification/2026-06-26-fsspec-style-fs-seam.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-06-26-fsspec-style-fs-seam.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-26-fsspec-style-fs-seam.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-06-26-fsspec-style-fs-seam.md -2026-06-26-fsspec-style-fs-seam.md: 138d6d4d74d162ab2149350a76fc72dc31c1818e -2026-06-26-fsspec-style-fs-seam.zh.md: bc7a3756dbf08673cfa63693a68aba1eb73da323 +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin: + en: 181df186598c42fc + zh: 07b7687434105955 +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin/problem: + en: 4069760b095aa1b6 + zh: ea8baf0050362519 +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin/decision: + en: 6f6dc20965bb9948 + zh: 5a858a0359f96a98 +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin/provider-contract: + en: a04b6ceab91aa265 + zh: 5fae55161f754f4d +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin/policy-contract: + en: bd54f18f4665b1ec + zh: eee54b7890c9d8be +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin/tool-contract: + en: b517106d3e0ac7ef + zh: 2b128d7af26ebed2 +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin/concurrency-boundary: + en: 6a459d121a49988c + zh: 048de517a0f952b6 +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin/supersedes: + en: 780789585ce58330 + zh: 7b4b8d171dfdefae +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin/verification: + en: ee6e0f4922f991af + zh: 3ce55e7b7d0fd431 +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin/later-extension: + en: b56210bf2c8f8dec + zh: 27decb39624c0ef7 +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin/alternatives-considered: + en: 3d169e07a912cbab + zh: d8a550835cfe7801 +/agent-note-split-the-filesystem-seam-provider-text-mutations-plus-the-dsh-fs-observation-policy-plugin/consequences: + en: 70264e0d9422b871 + zh: ae93add503e8a9bc diff --git a/.agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.i18n.yaml b/.agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.i18n.yaml index d4d6d30f86..cea714ade6 100644 --- a/.agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-17-one-send-one-turn.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.md -2026-07-17-one-send-one-turn.md: 71ea5d23c303a2e5de472ceabf9868364d916ab9 -2026-07-17-one-send-one-turn.zh.md: 8478f3fb35698087873b39773f8997ec33832f2a +/agent-note-remove-implicit-batching-from-ordinary-sends: + en: 5376ddae6e8cf5b9 + zh: 1dae892f25da755e +/agent-note-remove-implicit-batching-from-ordinary-sends/problem: + en: ed05e7ef01abfafc + zh: 40293ad57c00f902 +/agent-note-remove-implicit-batching-from-ordinary-sends/decision: + en: 354fbb4e6a776538 + zh: c78879212400bf0f +/agent-note-remove-implicit-batching-from-ordinary-sends/alternatives-considered: + en: f944e18c49b30b4c + zh: cfcc0b18ce94f37c +/agent-note-remove-implicit-batching-from-ordinary-sends/verification: + en: 9f75f226ac06ba1f + zh: 2ae17eda85a56324 +/agent-note-remove-implicit-batching-from-ordinary-sends/consequences: + en: afb9764a5345a188 + zh: 10ee27c54cbdbbdb diff --git a/.agents/notes/implemented/simplification/2026-07-20-unwrap-injected-content-envelopes.i18n.yaml b/.agents/notes/implemented/simplification/2026-07-20-unwrap-injected-content-envelopes.i18n.yaml index dbf98656ed..bcce3bc92b 100644 --- a/.agents/notes/implemented/simplification/2026-07-20-unwrap-injected-content-envelopes.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-07-20-unwrap-injected-content-envelopes.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-20-unwrap-injected-content-envelopes.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-20-unwrap-injected-content-envelopes.md -2026-07-20-unwrap-injected-content-envelopes.md: 7d14ada7cc1b88071ec4f07870afcfff6211a883 -2026-07-20-unwrap-injected-content-envelopes.zh.md: 813adfb818cac35da6e8c3b279b2e795fa99ad1a +/agent-note-project-injected-content-verbatim-dropping-the-xml-envelopes: + en: 488b566c13d0cd05 + zh: e9b9a14dc644a313 +/agent-note-project-injected-content-verbatim-dropping-the-xml-envelopes/problem: + en: 0005839a50aa093b + zh: bfb21448bbec1ac9 +/agent-note-project-injected-content-verbatim-dropping-the-xml-envelopes/decision: + en: ed1a833070d10b97 + zh: b7ce57a2b927f064 +/agent-note-project-injected-content-verbatim-dropping-the-xml-envelopes/alternatives-considered: + en: 93dca58966e5d55e + zh: 9fe7fd528d0114a2 +/agent-note-project-injected-content-verbatim-dropping-the-xml-envelopes/consequences: + en: 2b369a5b2ee9435b + zh: f72957abff1d2327 +/agent-note-project-injected-content-verbatim-dropping-the-xml-envelopes/deferred: + en: a772793aea7ee7ee + zh: a57b31af4422406d diff --git a/.agents/notes/implemented/simplification/2026-07-22-plan-specific-collaboration-state.i18n.yaml b/.agents/notes/implemented/simplification/2026-07-22-plan-specific-collaboration-state.i18n.yaml index f11b9827e8..ad1c43c6dd 100644 --- a/.agents/notes/implemented/simplification/2026-07-22-plan-specific-collaboration-state.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-07-22-plan-specific-collaboration-state.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-22-plan-specific-collaboration-state.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-22-plan-specific-collaboration-state.md -2026-07-22-plan-specific-collaboration-state.md: 20648b8d6cee3e3c049aeee3022bd322d657ba1c -2026-07-22-plan-specific-collaboration-state.zh.md: 2142839d5a834abba7aac042c8b1fee7a56c56b1 +/agent-note-plan-specific-collaboration-state: + en: b1e94e354a36ef2b + zh: bbc98d4b9a837a5a +/agent-note-plan-specific-collaboration-state/problem: + en: e79a03a0ec1ebc34 + zh: 94adee6ef4f1bcc2 +/agent-note-plan-specific-collaboration-state/decision: + en: 1255fd4c4852ea9c + zh: 27e431da895a9a69 +/agent-note-plan-specific-collaboration-state/decision/boundary-and-model-contract: + en: f9d67f4f91e14f9d + zh: 3284e2432e8a8466 +/agent-note-plan-specific-collaboration-state/decision/reviewed-exit: + en: 283fec44700c41e5 + zh: 99b8634a1dff791c +/agent-note-plan-specific-collaboration-state/deleted-api: + en: 7da48b6397bad4d0 + zh: cc0af0e26a81c7e0 +/agent-note-plan-specific-collaboration-state/alternatives-considered: + en: 4098e049cd6d28d8 + zh: 4ab332ad6af53ccf +/agent-note-plan-specific-collaboration-state/verification: + en: 41179b6ab02b3f90 + zh: 47f5a602496281cd +/agent-note-plan-specific-collaboration-state/consequences: + en: a71537da7d3921e2 + zh: a2ab69676bfe985d diff --git a/.agents/notes/implemented/simplification/2026-07-23-acp-automation-only-protocol.i18n.yaml b/.agents/notes/implemented/simplification/2026-07-23-acp-automation-only-protocol.i18n.yaml index 9640e9d10e..0be5f93a6e 100644 --- a/.agents/notes/implemented/simplification/2026-07-23-acp-automation-only-protocol.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-07-23-acp-automation-only-protocol.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-23-acp-automation-only-protocol.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-23-acp-automation-only-protocol.md -2026-07-23-acp-automation-only-protocol.md: d3d6a7abb6f347b04fdbfcea2940e8df0432b806 -2026-07-23-acp-automation-only-protocol.zh.md: d332e3f7c4798f391fe34b1e50bd63276f0121b8 +/agent-note-acp-as-an-automation-only-protocol: + en: e8a5a82b0137b656 + zh: 8b371b4add7c17b4 +/agent-note-acp-as-an-automation-only-protocol/problem: + en: 5123f99030ae618e + zh: fa62dc7b9a4b9fef +/agent-note-acp-as-an-automation-only-protocol/decision: + en: d9a2404790fe7cf0 + zh: 5fbd7f65d5ed1c4f +/agent-note-acp-as-an-automation-only-protocol/snapshot-boundary: + en: 4f015bfadd7027e2 + zh: 7d68f4c3b9a875d5 +/agent-note-acp-as-an-automation-only-protocol/alternatives-considered: + en: 13192a25709b5d95 + zh: 6cadde33a58510b5 +/agent-note-acp-as-an-automation-only-protocol/consequences: + en: bce44fd4a6d9f755 + zh: 351e80b7c02f6ce7 diff --git a/.agents/notes/implemented/simplification/2026-07-24-agent-loop-observable-state-machine.i18n.yaml b/.agents/notes/implemented/simplification/2026-07-24-agent-loop-observable-state-machine.i18n.yaml index d768a5513b..0e8ec12298 100644 --- a/.agents/notes/implemented/simplification/2026-07-24-agent-loop-observable-state-machine.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-07-24-agent-loop-observable-state-machine.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-24-agent-loop-observable-state-machine.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-24-agent-loop-observable-state-machine.md -2026-07-24-agent-loop-observable-state-machine.md: f250d645ca0a69c0fcad0078292de1d6531db19d -2026-07-24-agent-loop-observable-state-machine.zh.md: c77e5ad8f664851917bc578f1fb39760a80d2593 +/agent-note-collapse-agent-loop-events-around-the-observable-state-machine: + en: b7998bdbf46a06b1 + zh: ea7b4e8ef8e3cef5 +/agent-note-collapse-agent-loop-events-around-the-observable-state-machine/problem: + en: c55232633eaacf5a + zh: a71c538c61234c42 +/agent-note-collapse-agent-loop-events-around-the-observable-state-machine/decision: + en: 75a1c677da39192e + zh: 81a07f55fce3cbc0 +/agent-note-collapse-agent-loop-events-around-the-observable-state-machine/alternatives-considered: + en: 0d61d49e9f5964c2 + zh: f5e8802c7fe67839 +/agent-note-collapse-agent-loop-events-around-the-observable-state-machine/consequences: + en: 675d4ae63174031d + zh: 2649109d067352e2 +/agent-note-collapse-agent-loop-events-around-the-observable-state-machine/related: + en: f1610942ca31fdb8 + zh: 04eb3d4ce8e641af diff --git a/.agents/notes/implemented/simplification/2026-07-27-request-error-retry-action.i18n.yaml b/.agents/notes/implemented/simplification/2026-07-27-request-error-retry-action.i18n.yaml index bccb2cfc58..204f3b5cba 100644 --- a/.agents/notes/implemented/simplification/2026-07-27-request-error-retry-action.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-07-27-request-error-retry-action.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-27-request-error-retry-action.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-27-request-error-retry-action.md -2026-07-27-request-error-retry-action.md: 9853d7d0439093afd3e7a611e360a6b32517ca4c -2026-07-27-request-error-retry-action.zh.md: e0c4749b7ed6bddcbc44f3ab512df542f33831bd +/agent-note-request-error-retry-action: + en: 672e3acc184e72f7 + zh: 10334d48de7dcc0e +/agent-note-request-error-retry-action/problem: + en: 8b9476349def23b6 + zh: e3b034bae896e24b +/agent-note-request-error-retry-action/decision: + en: 3937a99236b23d80 + zh: ec5e9cb21744e3ae +/agent-note-request-error-retry-action/alternatives-considered: + en: 8f50ac6497dfd03e + zh: 4f1d07901132a184 +/agent-note-request-error-retry-action/consequences: + en: 3e60793a09964f5a + zh: b28626761a229d85 diff --git a/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.i18n.yaml b/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.i18n.yaml index a8f49b1780..036542d074 100644 --- a/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-28-remove-synthetic-log-only-turns.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md -2026-07-28-remove-synthetic-log-only-turns.md: 073ac0888054c907087dd0c5f2d01b03a5e87455 -2026-07-28-remove-synthetic-log-only-turns.zh.md: 67b24c7423ee37c40361cb937fdad42243362dfd +/agent-note-remove-synthetic-turns-for-log-only-events: + en: 558a3b8b47acfec2 + zh: 9e6cc6443e468745 +/agent-note-remove-synthetic-turns-for-log-only-events/problem: + en: 33413b092d535f4f + zh: 02f79f372227c104 +/agent-note-remove-synthetic-turns-for-log-only-events/decision: + en: a49da9273f224a87 + zh: 870ffea9aacca6c7 +/agent-note-remove-synthetic-turns-for-log-only-events/alternatives-considered: + en: fbee860bf43530a7 + zh: 276647ba5402d6a8 +/agent-note-remove-synthetic-turns-for-log-only-events/verification: + en: bb7b19f80c4fbed6 + zh: ef06defe5b745e38 +/agent-note-remove-synthetic-turns-for-log-only-events/consequences: + en: 0c636b744dfa4ca9 + zh: 05f409a4fd962015 diff --git a/.agents/notes/implemented/simplification/2026-08-09-explicit-schedule-time-zone.i18n.yaml b/.agents/notes/implemented/simplification/2026-08-09-explicit-schedule-time-zone.i18n.yaml index 11c416587f..acb0275dcc 100644 --- a/.agents/notes/implemented/simplification/2026-08-09-explicit-schedule-time-zone.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-08-09-explicit-schedule-time-zone.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-09-explicit-schedule-time-zone.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-08-09-explicit-schedule-time-zone.md -2026-08-09-explicit-schedule-time-zone.md: 2f23394e65d37f9eb714c2e55b0556cdf0bc967e -2026-08-09-explicit-schedule-time-zone.zh.md: aafa5d56853339e51b9a4265a32fca1a24e7b1dd +/agent-note-explicit-schedule-time-zone-boundary: + en: 475b5512c7155605 + zh: e564e8c4f718f0c0 +/agent-note-explicit-schedule-time-zone-boundary/problem: + en: 4a7e52f6a16dec96 + zh: d558db30801355d9 +/agent-note-explicit-schedule-time-zone-boundary/decision: + en: 6f233286c95b5294 + zh: 5a1f4ba6f5ccbd36 +/agent-note-explicit-schedule-time-zone-boundary/alternatives-considered: + en: 982fe0b8d24a66ce + zh: e6dceee1ce776d21 +/agent-note-explicit-schedule-time-zone-boundary/verification: + en: 56dcb44f09be3713 + zh: 59a6814a662458ad +/agent-note-explicit-schedule-time-zone-boundary/consequences: + en: d9358667c58662e4 + zh: d536bb0fccd9f0a9 diff --git a/.agents/notes/implemented/simplification/2026-08-28-omit-unneeded-invariant-companions.i18n.yaml b/.agents/notes/implemented/simplification/2026-08-28-omit-unneeded-invariant-companions.i18n.yaml index 57d6fb3b1f..8ccac77c7e 100644 --- a/.agents/notes/implemented/simplification/2026-08-28-omit-unneeded-invariant-companions.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-08-28-omit-unneeded-invariant-companions.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-28-omit-unneeded-invariant-companions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-08-28-omit-unneeded-invariant-companions.md -2026-08-28-omit-unneeded-invariant-companions.md: 82d421677cb2f2a425c92e203766527aac7ce860 -2026-08-28-omit-unneeded-invariant-companions.zh.md: d0fda9154675d038c1f304609313654fc4e51f23 +/agent-note-omit-invariant-companions-without-independent-observations: + en: 1aaf29f8d757fcc8 + zh: 76d99dd71bfabbaa +/agent-note-omit-invariant-companions-without-independent-observations/problem: + en: 53d9687bdef70d91 + zh: 61d225b1cd374c28 +/agent-note-omit-invariant-companions-without-independent-observations/decision: + en: a15c7c13f167e5ac + zh: 63bcc2ef60c2f344 +/agent-note-omit-invariant-companions-without-independent-observations/decision/independent-observations-justify-publication: + en: ee3e2ff2f0565d94 + zh: 232ddf075bf3b353 +/agent-note-omit-invariant-companions-without-independent-observations/decision/omission-is-explicit-in-the-package-readme: + en: 465c523c29fd7836 + zh: 9967d7e5b17f1adf +/agent-note-omit-invariant-companions-without-independent-observations/decision/audit-result: + en: b19c08cd1f7df630 + zh: 30e872df9ee3ff0a +/agent-note-omit-invariant-companions-without-independent-observations/alternatives-considered: + en: 5908a05a2aeb3f82 + zh: 9a01748e8d8b86f4 +/agent-note-omit-invariant-companions-without-independent-observations/consequences: + en: c648b67008e676f1 + zh: c89400eae3fef89c diff --git a/.agents/notes/implemented/simplification/2026-08-30-jsonl-only-session-persistence.i18n.yaml b/.agents/notes/implemented/simplification/2026-08-30-jsonl-only-session-persistence.i18n.yaml index 5b414b1e68..31ce312f8a 100644 --- a/.agents/notes/implemented/simplification/2026-08-30-jsonl-only-session-persistence.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-08-30-jsonl-only-session-persistence.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-30-jsonl-only-session-persistence.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-08-30-jsonl-only-session-persistence.md -2026-08-30-jsonl-only-session-persistence.md: eeb89d8ecc06b082c5346d61e85b40d317e31c89 -2026-08-30-jsonl-only-session-persistence.zh.md: 210e66fa75db5959f198235c31022792f5f35ea8 +/agent-note-jsonl-only-first-party-session-persistence: + en: 4060d3d6df88fea3 + zh: f6ed66cd7e39c465 +/agent-note-jsonl-only-first-party-session-persistence/problem: + en: fd4ad3e29b080f22 + zh: 6b3e1e88cea3e3ce +/agent-note-jsonl-only-first-party-session-persistence/decision: + en: 8c80ac91f1c31247 + zh: 560796b1b338f60f +/agent-note-jsonl-only-first-party-session-persistence/alternatives-considered: + en: d09a6b404ee37a4c + zh: a846a6ee2d3851c3 +/agent-note-jsonl-only-first-party-session-persistence/consequences: + en: 952ee4c54a2f9851 + zh: 1e7f908464b86a4a diff --git a/.agents/notes/implemented/simplification/2026-09-03-minimal-profiles-persistent-shell-only.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-03-minimal-profiles-persistent-shell-only.i18n.yaml index cd6b1146aa..2f39ebf65f 100644 --- a/.agents/notes/implemented/simplification/2026-09-03-minimal-profiles-persistent-shell-only.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-03-minimal-profiles-persistent-shell-only.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-03-minimal-profiles-persistent-shell-only.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-03-minimal-profiles-persistent-shell-only.md -2026-09-03-minimal-profiles-persistent-shell-only.md: 2bc4ef7ada0767d96c0ac448e19e13e8e06a945c -2026-09-03-minimal-profiles-persistent-shell-only.zh.md: d54e5734ac04825e2d28f59d9104a01b5caf9fb7 +/agent-note-minimal-profiles-expose-only-a-persistent-shell: + en: d48e78dc2040921c + zh: 70122e09d8c78e77 +/agent-note-minimal-profiles-expose-only-a-persistent-shell/problem: + en: a5d116f8ba3ed48b + zh: d60d307237a69573 +/agent-note-minimal-profiles-expose-only-a-persistent-shell/decision: + en: 95a1c2d9322ed9da + zh: 04bc770915863950 +/agent-note-minimal-profiles-expose-only-a-persistent-shell/alternatives-considered: + en: 55fc282c31b7d4e8 + zh: 6daa72fb5527fcca +/agent-note-minimal-profiles-expose-only-a-persistent-shell/consequences: + en: 4f0e22319608c3be + zh: a6393182b9452c4a diff --git a/.agents/notes/implemented/simplification/2026-09-05-base-default-file-editor.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-05-base-default-file-editor.i18n.yaml index 3b4fcb4fa3..e70adc677c 100644 --- a/.agents/notes/implemented/simplification/2026-09-05-base-default-file-editor.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-05-base-default-file-editor.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-05-base-default-file-editor.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-05-base-default-file-editor.md -2026-09-05-base-default-file-editor.md: e1e15718962322ba8c79107fda31446448b87056 -2026-09-05-base-default-file-editor.zh.md: d43df3313ecaeff8b2123208620779df2048b818 +/agent-note-shared-base-default-file-editor-selection: + en: 2adaf509a18a68eb + zh: 3103eec286980735 +/agent-note-shared-base-default-file-editor-selection/problem: + en: b9cf9c91689aeca7 + zh: 4fce9354bb6c2af0 +/agent-note-shared-base-default-file-editor-selection/decision: + en: 8aa4e6ecc02abdb8 + zh: 9925a29181c53e81 +/agent-note-shared-base-default-file-editor-selection/alternatives-considered: + en: 172ed2cdc1d47e20 + zh: e12bbb0576244f43 +/agent-note-shared-base-default-file-editor-selection/consequences: + en: 886dab29e1e6580f + zh: 49a7b2ceafac0c48 +/agent-note-shared-base-default-file-editor-selection/verification: + en: 7e8cd8a29f33aff3 + zh: ee6c24c9adf54998 diff --git a/.agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.i18n.yaml index cb5eb44cc5..6c68b294d5 100644 --- a/.agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-agent-request-freeze-evidence.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.md -2026-09-06-agent-request-freeze-evidence.md: 6603a728c3dd2acc87902169bb07a67bde0be2a4 -2026-09-06-agent-request-freeze-evidence.zh.md: a5ba15ac139d647755f9c039847acbb642d214d3 +/agent-note-reuse-only-loop-proven-message-freezes: + en: 7ec7e2c8c1eb46bb + zh: 93a619878774a795 +/agent-note-reuse-only-loop-proven-message-freezes/problem: + en: af6aa6181efb2163 + zh: 3f1630947294db0a +/agent-note-reuse-only-loop-proven-message-freezes/decision: + en: 64e5058366d82142 + zh: 073f4e1856c58294 +/agent-note-reuse-only-loop-proven-message-freezes/measurement-evidence: + en: 731e00bb5059b1f3 + zh: 118464dc6e640431 +/agent-note-reuse-only-loop-proven-message-freezes/measurement-evidence/standard-hosted-ci-calibration: + en: 22ad93c82afc0572 + zh: 86e43487e7791148 +/agent-note-reuse-only-loop-proven-message-freezes/alternatives-considered: + en: 8a00552d7797826c + zh: 765a6b84eb663bab +/agent-note-reuse-only-loop-proven-message-freezes/consequences: + en: 5947b38f7722d4db + zh: 147b5ea3d681ebd7 diff --git a/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.i18n.yaml index e5ab7e62d9..7943e40a05 100644 --- a/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-07-file-content-scan.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-file-content-scan.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-07-file-content-scan.md -2026-09-07-file-content-scan.md: 1ec46e7d685394f5165624f1e7b68622ba9f89d3 -2026-09-07-file-content-scan.zh.md: b4ebd835ca8adaf3a7b7fa09150cd5a2bec9f401 +/agent-note-scan-file-content-without-per-array-callbacks: + en: a814034fce2407dc + zh: 7de9ec55cbbb30ab +/agent-note-scan-file-content-without-per-array-callbacks/problem: + en: cb13a0053453cf45 + zh: ce40afb7fa03f9ed +/agent-note-scan-file-content-without-per-array-callbacks/decision: + en: e3d83658869a24f7 + zh: 44dd61458a47df6c +/agent-note-scan-file-content-without-per-array-callbacks/measurement-evidence: + en: ad23fa4ee386f3cf + zh: 41e54e28d26b3d02 +/agent-note-scan-file-content-without-per-array-callbacks/alternatives-considered: + en: 0128940c217dd77c + zh: 9394e713dac9675d +/agent-note-scan-file-content-without-per-array-callbacks/consequences: + en: dace71e8857e57b1 + zh: 0ee88fdaa4e067ee diff --git a/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.i18n.yaml index d589324465..ebd9b4005d 100644 --- a/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-web-subagent-catalog-projections.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.md -2026-09-08-web-subagent-catalog-projections.md: 766d33e581bcac53844b0836f23cda615858fc27 -2026-09-08-web-subagent-catalog-projections.zh.md: ef14db2530ed10a7aa34408c5a6fada6f0a28858 +/agent-note-web-subagent-catalogs-consume-shared-projections: + en: 90a80df3b19785a2 + zh: 8e29073af6c61213 +/agent-note-web-subagent-catalogs-consume-shared-projections/problem: + en: 21600a979400fc8a + zh: 59ba11ed5210986e +/agent-note-web-subagent-catalogs-consume-shared-projections/decision: + en: de9d755497c49716 + zh: 872a15b960e01618 +/agent-note-web-subagent-catalogs-consume-shared-projections/alternatives-considered: + en: 2a1d32d867c38abd + zh: 1f473782ade94fa5 +/agent-note-web-subagent-catalogs-consume-shared-projections/consequences: + en: 44d73213900d4e43 + zh: 2beec2c2634320e2 diff --git a/.agents/notes/implemented/simplification/2026-09-09-nontransactional-loader.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-09-nontransactional-loader.i18n.yaml index 258af20542..5a3be08ed1 100644 --- a/.agents/notes/implemented/simplification/2026-09-09-nontransactional-loader.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-09-nontransactional-loader.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-nontransactional-loader.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-09-nontransactional-loader.md -2026-09-09-nontransactional-loader.md: 98b0b1ce0c1250e651c5280c9b918948b17cd963 -2026-09-09-nontransactional-loader.zh.md: 77ae1ce91aa0d20940f0c63f2a2d42a0f3c07edb +/agent-note-keep-loader-mutations-non-transactional: + en: 199b544883ab8736 + zh: 4b2ad7d22985d52f +/agent-note-keep-loader-mutations-non-transactional/problem: + en: d4ab65a39cf4fd7c + zh: 62144be9b4fd7956 +/agent-note-keep-loader-mutations-non-transactional/decision: + en: 9b661159de63d421 + zh: 15697f468a90edb9 +/agent-note-keep-loader-mutations-non-transactional/alternatives-considered: + en: 72b871064c7ae315 + zh: a09e5168f8124c4c +/agent-note-keep-loader-mutations-non-transactional/consequences: + en: 2b1eece19252ad80 + zh: 8c9f5faf201521e0 diff --git a/.agents/notes/implemented/simplification/2026-09-10-derived-workspace-recency.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-10-derived-workspace-recency.i18n.yaml index 6895faecfb..282d674791 100644 --- a/.agents/notes/implemented/simplification/2026-09-10-derived-workspace-recency.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-10-derived-workspace-recency.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-derived-workspace-recency.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-10-derived-workspace-recency.md -2026-09-10-derived-workspace-recency.md: b967e332f234d6d120bb82c444e4b05818b85103 -2026-09-10-derived-workspace-recency.zh.md: 87c2bb9f2648baa613ded32cda5b8673a77c5f56 +/agent-note-derive-workspace-recency-independently-of-manual-order: + en: 96d0de6bdc9dcac1 + zh: a50ab8a60f58a24d +/agent-note-derive-workspace-recency-independently-of-manual-order/problem: + en: 796dc4d186169b89 + zh: 058b6a8438e46238 +/agent-note-derive-workspace-recency-independently-of-manual-order/decision: + en: c598d4991271fbf4 + zh: 6454e56191922501 +/agent-note-derive-workspace-recency-independently-of-manual-order/alternatives-considered: + en: 0e74f1c4f176107a + zh: 66a66eaa811c8b11 +/agent-note-derive-workspace-recency-independently-of-manual-order/consequences: + en: f4658d8f0f3ff8d3 + zh: 68c3c8c87b9c4e31 +/agent-note-derive-workspace-recency-independently-of-manual-order/testing: + en: 82b15f31cd5b5315 + zh: 5f14bfe0d0e8ef0c diff --git a/.agents/notes/implemented/simplification/2026-09-11-remove-e2b-providers.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-11-remove-e2b-providers.i18n.yaml index 5d922e128e..fd8eb2f048 100644 --- a/.agents/notes/implemented/simplification/2026-09-11-remove-e2b-providers.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-11-remove-e2b-providers.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-11-remove-e2b-providers.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-11-remove-e2b-providers.md -2026-09-11-remove-e2b-providers.md: 6ff8f51e94875b9496da2c77b1e160357a15add9 -2026-09-11-remove-e2b-providers.zh.md: ebc592fb564d1ed1a0e981dc9b1bd3806de54414 +/agent-note-remove-the-e2b-execution-providers: + en: 0f876c637fad20a9 + zh: a7616ada505f0bc1 +/agent-note-remove-the-e2b-execution-providers/problem: + en: 92edfc6f0da7a874 + zh: 21487929a5631087 +/agent-note-remove-the-e2b-execution-providers/decision: + en: 924d9953c601a131 + zh: 6bb14feef8f4238a +/agent-note-remove-the-e2b-execution-providers/alternatives-considered: + en: dc8a267887d4a65c + zh: 806f4a6c844b6284 +/agent-note-remove-the-e2b-execution-providers/consequences: + en: ec119616577fb094 + zh: 4dafe3fd08e11b79 +/agent-note-remove-the-e2b-execution-providers/reintroduction-conditions: + en: ddc5f44430a6b6d5 + zh: 372f28000c98cbd6 +/agent-note-remove-the-e2b-execution-providers/verification: + en: d4f3b559dd32d80a + zh: c4ba5b64178faf81 diff --git a/.agents/notes/implemented/simplification/2026-09-12-ralph-off-in-shipped-defaults.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-12-ralph-off-in-shipped-defaults.i18n.yaml index 9d38b3b53b..2f8e4c8416 100644 --- a/.agents/notes/implemented/simplification/2026-09-12-ralph-off-in-shipped-defaults.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-12-ralph-off-in-shipped-defaults.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-ralph-off-in-shipped-defaults.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-12-ralph-off-in-shipped-defaults.md -2026-09-12-ralph-off-in-shipped-defaults.md: fbd7ea72e02302f45029d2b7677d9a4d15ee2e63 -2026-09-12-ralph-off-in-shipped-defaults.zh.md: 377f8656236b55dc8de79a78abe742b595e3617c +/agent-note-ship-ralph-off-in-the-default-compositions: + en: 59fe1293d618be67 + zh: 0da7f1b4447f10f1 +/agent-note-ship-ralph-off-in-the-default-compositions/problem: + en: c8c152617cca4d5d + zh: 1846b119989b9e5b +/agent-note-ship-ralph-off-in-the-default-compositions/decision: + en: 7d95a71842e74d38 + zh: fc0d360ff3acc8b5 +/agent-note-ship-ralph-off-in-the-default-compositions/alternatives-considered: + en: 4e6ed0566a2de3a8 + zh: c1e7ba6dd4047fa0 +/agent-note-ship-ralph-off-in-the-default-compositions/consequences: + en: 427242f0a8df0c66 + zh: ca3dd1bd4cd54605 +/agent-note-ship-ralph-off-in-the-default-compositions/verification: + en: 2511c9dd0da7ab60 + zh: 6d4e801f33f3d81b diff --git a/.agents/notes/implemented/simplification/2026-09-15-host-only-remote-input-validation.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-15-host-only-remote-input-validation.i18n.yaml index 75a1eea7ed..5029c4401d 100644 --- a/.agents/notes/implemented/simplification/2026-09-15-host-only-remote-input-validation.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-15-host-only-remote-input-validation.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-host-only-remote-input-validation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-15-host-only-remote-input-validation.md -2026-09-15-host-only-remote-input-validation.md: 5c256fb5f5b78b646c645a44b77718fa40a62399 -2026-09-15-host-only-remote-input-validation.zh.md: 92a3f2415c6206a0513d8338bbb8d0844bf5d43d +/agent-note-validate-remote-inputs-only-on-the-host: + en: 4434bfb455727454 + zh: 776fc3b42ce339e6 +/agent-note-validate-remote-inputs-only-on-the-host/problem: + en: 6cddd9c31c5bf1e5 + zh: f2730b6448f7fc26 +/agent-note-validate-remote-inputs-only-on-the-host/decision: + en: 6e3ef9540b02336b + zh: e8abe4ea84d95b95 +/agent-note-validate-remote-inputs-only-on-the-host/alternatives-considered: + en: 1c9ed80b25403e03 + zh: edbc8301e50cf3a1 +/agent-note-validate-remote-inputs-only-on-the-host/consequences: + en: caf3ffc95133ac40 + zh: f29864e4b636d6f7 diff --git a/.agents/notes/implemented/simplification/2026-09-15-model-agent-availability-and-team-targets.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-15-model-agent-availability-and-team-targets.i18n.yaml index 165022b7dc..a259fd41c0 100644 --- a/.agents/notes/implemented/simplification/2026-09-15-model-agent-availability-and-team-targets.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-15-model-agent-availability-and-team-targets.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-15-model-agent-availability-and-team-targets.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-15-model-agent-availability-and-team-targets.md -2026-09-15-model-agent-availability-and-team-targets.md: e1f7f95cfa333be6d05677b4b19775c744f2817c -2026-09-15-model-agent-availability-and-team-targets.zh.md: 0447d7d4059eb75d1fb9169389cd83a54292aadf +/agent-note-model-agent-availability-and-team-targets: + en: 7c8722f7b156cd8c + zh: aad147cf37021d82 +/agent-note-model-agent-availability-and-team-targets/problem: + en: 66cc6cea878418a6 + zh: 5df1e5508e10fc02 +/agent-note-model-agent-availability-and-team-targets/decision: + en: 044f44c456540021 + zh: 975794704c37186f +/agent-note-model-agent-availability-and-team-targets/alternatives-considered: + en: a19b8766bcff7e49 + zh: 0851603e9c8315c6 +/agent-note-model-agent-availability-and-team-targets/consequences: + en: 9b622b43322a407e + zh: ffe2e0199ba85b5e diff --git a/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.i18n.yaml index a6c46b0bbd..3d56b5605f 100644 --- a/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-16-subagent-catalog-membership-only.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-16-subagent-catalog-membership-only.md -2026-09-16-subagent-catalog-membership-only.md: d1d0956380ef2b2ffd610e5a3d07c7988991e42e -2026-09-16-subagent-catalog-membership-only.zh.md: 4225a331a0b3c483349760cd805416a94c4b915a +/agent-note-keep-model-configuration-outside-subagent-catalogs: + en: 58a38a2045e8bd43 + zh: 1a1b02b0a93ebc9e +/agent-note-keep-model-configuration-outside-subagent-catalogs/problem: + en: d817b413b7e38939 + zh: a4a3a12df1407a34 +/agent-note-keep-model-configuration-outside-subagent-catalogs/decision: + en: e46b59047e7cbe7d + zh: 2249547faa8e6a72 +/agent-note-keep-model-configuration-outside-subagent-catalogs/alternatives-considered: + en: 415a276e8011a2ab + zh: d86739d9fbe72fb9 +/agent-note-keep-model-configuration-outside-subagent-catalogs/consequences: + en: 6849156944864ab6 + zh: b74ba42a7d5711d9 diff --git a/.agents/notes/implemented/simplification/2026-09-19-deepseek-messages-only.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-19-deepseek-messages-only.i18n.yaml index 07287b00f8..b97e9bb8dd 100644 --- a/.agents/notes/implemented/simplification/2026-09-19-deepseek-messages-only.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-19-deepseek-messages-only.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-deepseek-messages-only.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-19-deepseek-messages-only.md -2026-09-19-deepseek-messages-only.md: c10ecae950bb12f4556021de21c9716ad2906227 -2026-09-19-deepseek-messages-only.zh.md: 3cfadac6ebc0b4bb1587a8b72e9b169d2ade2ee9 +/agent-note-one-messages-transport-for-the-official-deepseek-route: + en: 7f7651d2e098b62d + zh: 0b12845f48f7ae93 +/agent-note-one-messages-transport-for-the-official-deepseek-route/problem: + en: 050718df19ce3089 + zh: 676838e85ba91e25 +/agent-note-one-messages-transport-for-the-official-deepseek-route/decision: + en: 33738d00a2d9564b + zh: 00101971b1a18d64 +/agent-note-one-messages-transport-for-the-official-deepseek-route/alternatives-considered: + en: f92695788ada65aa + zh: b885b30ba9f846f8 +/agent-note-one-messages-transport-for-the-official-deepseek-route/consequences: + en: 23f7d09fb7cf709c + zh: 1db0bf29cdc38871 diff --git a/.agents/notes/implemented/simplification/2026-09-19-remove-desktop-profile-core-cleanup.i18n.yaml b/.agents/notes/implemented/simplification/2026-09-19-remove-desktop-profile-core-cleanup.i18n.yaml index 7dd1a29921..12e19d3efa 100644 --- a/.agents/notes/implemented/simplification/2026-09-19-remove-desktop-profile-core-cleanup.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-09-19-remove-desktop-profile-core-cleanup.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-remove-desktop-profile-core-cleanup.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-19-remove-desktop-profile-core-cleanup.md -2026-09-19-remove-desktop-profile-core-cleanup.md: a42100e8dc247611e29ddd2b8075b3b98e388177 -2026-09-19-remove-desktop-profile-core-cleanup.zh.md: 9a6be335a427e3f3083362ffd9e3aaa2f236635d +/agent-note-remove-the-desktop-production-profile-core-package-cleanup: + en: c0f7b1fb34a21423 + zh: 2ed4b90f28d21faa +/agent-note-remove-the-desktop-production-profile-core-package-cleanup/problem: + en: 7176d7d629dd9e9f + zh: f0e02f220e3ae72b +/agent-note-remove-the-desktop-production-profile-core-package-cleanup/decision: + en: 411b72fcdcb37d61 + zh: 7fac6dfd6d0ab0e4 +/agent-note-remove-the-desktop-production-profile-core-package-cleanup/alternatives-considered: + en: 92f74de20afec309 + zh: 6ace8389378cc343 +/agent-note-remove-the-desktop-production-profile-core-package-cleanup/verification: + en: dfb7a6977452f472 + zh: 424f2003f8372fe3 +/agent-note-remove-the-desktop-production-profile-core-package-cleanup/consequences: + en: 1012a408f055e2f3 + zh: 48329f673f2e440f diff --git a/.agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.i18n.yaml b/.agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.i18n.yaml index 42cefa39a0..f2eedbf389 100644 --- a/.agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.i18n.yaml @@ -1,6 +1,46 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-19-acp-snapshot-tests.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.md -2026-06-19-acp-snapshot-tests.md: 3a21d09609d45b574d7f19c3704a44dde5a3d17c -2026-06-19-acp-snapshot-tests.zh.md: e9f3682289a05e4e54db2de3adcd3bee7042ef1b +/agent-note-acp-snapshot-tests-record-once-replay-deterministic: + en: 2f19b76966d5cf54 + zh: cbaed521d650e079 +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/problem: + en: d1738d268738633e + zh: ce62a5b0ff65ce8c +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/decision: + en: a9e85418ad5d2bbd + zh: 8e86b30a2a5bd049 +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/decision/the-fixture-projects-the-persisted-session-jsonl: + en: bdd1333366edfc30 + zh: ed8a0fbab516a62b +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/decision/replay-derives-the-model-script-from-the-log: + en: cb71313f2b14f855 + zh: f85809cfd19ce6af +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/decision/the-in-memory-replay-entry-honors-the-full-llm-contract: + en: 5d750b82fd88597c + zh: 22dc6dec0d638449 +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/decision/positional-replay-one-in-flight-stream: + en: 9ecd0c3efce1b2a1 + zh: 51612956e0c4fc85 +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/decision/recording-harvests-the-log-keyless-replay-needs-a-providerless-config: + en: 17239981275e59c8 + zh: 8f7fc2d9e6abd3ee +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/decision/two-outputs-normalize-then-compare: + en: ee891a839a0c05e9 + zh: 677259307e4357fa +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/decision/isolation-normalization-now-sandbox-later: + en: ce58ef2e3180d0d3 + zh: 1e9354614e4d7219 +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/decision/the-replay-plugin-is-its-own-package: + en: 6c3f938c57f4458b + zh: f64bb14ffb80ab90 +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/decision/two-subcommands-replay-in-the-default-gate: + en: a50cb4cd2be177f7 + zh: a29f45aafb83fa6c +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/alternatives-considered: + en: c4e83a568e8f483e + zh: eff19f1872565ff6 +/agent-note-acp-snapshot-tests-record-once-replay-deterministic/consequences: + en: ea210a6a43707447 + zh: 8c1e2a474d595b96 diff --git a/.agents/notes/implemented/testing/2026-06-19-real-api-e2e-ci.i18n.yaml b/.agents/notes/implemented/testing/2026-06-19-real-api-e2e-ci.i18n.yaml index b55464949e..5958148df6 100644 --- a/.agents/notes/implemented/testing/2026-06-19-real-api-e2e-ci.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-06-19-real-api-e2e-ci.i18n.yaml @@ -1,6 +1,52 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-19-real-api-e2e-ci.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-06-19-real-api-e2e-ci.md -2026-06-19-real-api-e2e-ci.md: bdb20b3d5413077a4ddf1c1d9293b3b808cd6c8c -2026-06-19-real-api-e2e-ci.zh.md: b95f7df62e0a57d4c58fc5c12a83905dd848c55e +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api: + en: 705c6fd43858bdac + zh: 2bbc6491368fb4c0 +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/problem: + en: 80cf8dc578552364 + zh: a54441ea02664483 +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/decision: + en: 3fbdb8769322e05f + zh: f46f68f8eba74d67 +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/decision/a-separate-workflow-not-a-job-in-ci-yml: + en: e4745c43611b96bb + zh: 8fb980401b0c5e9b +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/decision/cost-is-not-the-constraint-reliability-is: + en: 88b945361b1d4804 + zh: 0887a653945f4dda +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/decision/triggers-trusted-events-only: + en: 42a2fb15f00aec3a + zh: c4775447c863d209 +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/decision/the-untrusted-pr-gate: + en: e94c28db20896508 + zh: c8e77c54dceed035 +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/decision/preflight-fail-loud-never-false-green: + en: 07904c7ad53be5ad + zh: 67d84d4dc6f082a9 +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/decision/secret-mapping-and-hygiene: + en: fbbcc9a926dfc943 + zh: 506acdb4e034574b +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/decision/scope-runtime-shape: + en: c59c441547da2a4d + zh: b08d50e7cfd40cd5 +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/security: + en: 1fd3925ab26c11d4 + zh: 0d7103fd0b1afa89 +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/security/who-can-reach-the-secret-in-a-private-repository: + en: a748b4e79bab26e1 + zh: 1c607bc65274cdef +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/security/the-residual-exposure-the-pull-request-trigger-adds: + en: 04463ffd6f67a2bd + zh: 4126fb30873782ed +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/security/what-changes-when-the-repo-goes-public: + en: 02aa2f4100f6aac5 + zh: f9868c6a12e19ecd +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/alternatives-considered: + en: 7e7aa3a387a174bc + zh: 2431a0df2fb478a8 +/agent-note-real-api-e2e-in-ci-against-the-external-deepseek-api/consequences: + en: a999af1cbd7776da + zh: 5f1fab52fd4eb304 diff --git a/.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.i18n.yaml b/.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.i18n.yaml index ac15111eb8..432ef80b37 100644 --- a/.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.i18n.yaml @@ -1,6 +1,46 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-24-web-gui-browser-e2e-lane.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.md -2026-07-24-web-gui-browser-e2e-lane.md: eb79591e7b94fccb8eb92aec4024738825d214fc -2026-07-24-web-gui-browser-e2e-lane.zh.md: f715f4ca93b202f72e632e5ddae0d13559a927a7 +/agent-note-keyless-browser-e2e-lane-for-the-web-gui: + en: acbf72f6a3c5bea9 + zh: 4d655027ac2b78db +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/problem: + en: 547a3f60ac28095e + zh: 85a9d996257f0273 +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/decision: + en: c2f86db5f0b6b5a4 + zh: dd07b529cc65e7d2 +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/decision/scaffold-apps-web-tests-scaffold-ts: + en: 3d09cd693966a674 + zh: 4cda02850961f8d0 +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/decision/determinism-rules: + en: 41790d8d79b7ada3 + zh: 1fc7e85a1accd806 +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/decision/expected-outputs: + en: ca1ae9ccbeab8c01 + zh: 662cd5d98ee20ccc +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/decision/modes-and-fixtures: + en: 54f10befeaaade72 + zh: 3a7726c1f4be51cc +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/decision/coverage-contract: + en: c529437d4fbaeeb3 + zh: fe13551e56cba7df +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/decision/ci-stance: + en: 23b625d86ba7f5e2 + zh: 88f33b233fca0a82 +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/prior-art: + en: 7472e212043721dd + zh: 61dd9f5a8e12730b +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/alternatives-considered: + en: 5bd57b3dbacd8380 + zh: a154f27d93930f77 +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/testing: + en: f4459a24f56c9cfe + zh: a15bdc45785ed7e8 +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/deferred: + en: aef84d3933bb72a1 + zh: 1cc5e2f1c9bcccf9 +/agent-note-keyless-browser-e2e-lane-for-the-web-gui/consequences: + en: 30928e1b547ddc34 + zh: 068bd12b2ac119dc diff --git a/.agents/notes/implemented/testing/2026-07-30-web-browser-snapshot-ci-gate.i18n.yaml b/.agents/notes/implemented/testing/2026-07-30-web-browser-snapshot-ci-gate.i18n.yaml index aeb64a1a11..8a40db5638 100644 --- a/.agents/notes/implemented/testing/2026-07-30-web-browser-snapshot-ci-gate.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-07-30-web-browser-snapshot-ci-gate.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-30-web-browser-snapshot-ci-gate.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-07-30-web-browser-snapshot-ci-gate.md -2026-07-30-web-browser-snapshot-ci-gate.md: 352072bca6e1a9e1d5b72973d2c3c9e96bc58ad9 -2026-07-30-web-browser-snapshot-ci-gate.zh.md: cd04f33a5db6ddb3c88a235fb34ea31da0e5a869 +/agent-note-required-ci-gate-for-web-browser-expected-outputs: + en: 246ce605a87c0592 + zh: 37b3fb230abcb280 +/agent-note-required-ci-gate-for-web-browser-expected-outputs/problem: + en: e04a5ecbd6d6a39e + zh: 049ce77a1a679daa +/agent-note-required-ci-gate-for-web-browser-expected-outputs/decision: + en: 915efba11d7ece34 + zh: 540495b04ef9a305 +/agent-note-required-ci-gate-for-web-browser-expected-outputs/alternatives-considered: + en: 145e763735dd33b1 + zh: 4ea34838629cd3bf +/agent-note-required-ci-gate-for-web-browser-expected-outputs/consequences: + en: d4c6e69ad04c5748 + zh: 5f3034df8f13b106 diff --git a/.agents/notes/implemented/testing/2026-08-03-opt-in-reasoning-chunk-browser-stress.i18n.yaml b/.agents/notes/implemented/testing/2026-08-03-opt-in-reasoning-chunk-browser-stress.i18n.yaml index e8edd6c33e..42da714161 100644 --- a/.agents/notes/implemented/testing/2026-08-03-opt-in-reasoning-chunk-browser-stress.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-08-03-opt-in-reasoning-chunk-browser-stress.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-03-opt-in-reasoning-chunk-browser-stress.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-08-03-opt-in-reasoning-chunk-browser-stress.md -2026-08-03-opt-in-reasoning-chunk-browser-stress.md: 5b679ce2682743531bd3ff48621cbde462a335aa -2026-08-03-opt-in-reasoning-chunk-browser-stress.zh.md: 3d730a4505351be968c71092c65a9b9c6b69818c +/agent-note-frame-coalesced-reasoning-chunk-publication-and-browser-stress-validation: + en: c63de146daf09530 + zh: 5e117bc92e2ac783 +/agent-note-frame-coalesced-reasoning-chunk-publication-and-browser-stress-validation/problem: + en: 73673725b44538c9 + zh: 32027f7a457ee3ae +/agent-note-frame-coalesced-reasoning-chunk-publication-and-browser-stress-validation/decision: + en: 76879cc8efbe7c80 + zh: 539556341dcb04e5 +/agent-note-frame-coalesced-reasoning-chunk-publication-and-browser-stress-validation/alternatives-considered: + en: 8d0a7be0a8660a9c + zh: c1e94daae31893c5 +/agent-note-frame-coalesced-reasoning-chunk-publication-and-browser-stress-validation/consequences: + en: 7b67ec0da7f08635 + zh: 2b808c760e8df494 diff --git a/.agents/notes/implemented/testing/2026-08-23-installed-python-wheel-black-box-ci.i18n.yaml b/.agents/notes/implemented/testing/2026-08-23-installed-python-wheel-black-box-ci.i18n.yaml index ad99495034..be0529a4d9 100644 --- a/.agents/notes/implemented/testing/2026-08-23-installed-python-wheel-black-box-ci.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-08-23-installed-python-wheel-black-box-ci.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-23-installed-python-wheel-black-box-ci.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-08-23-installed-python-wheel-black-box-ci.md -2026-08-23-installed-python-wheel-black-box-ci.md: a23f7ea1b0157ba4ec050069b9fa9a4ea705bfa7 -2026-08-23-installed-python-wheel-black-box-ci.zh.md: 1751430445c6f42cf37fdf9b6164c19b04f01536 +/agent-note-installed-wheel-python-runtime-pull-request-validation: + en: e7a926cb3fc87ca2 + zh: 9d4df26986ee2c25 +/agent-note-installed-wheel-python-runtime-pull-request-validation/problem: + en: a8679e0c46ab5294 + zh: 1c3b4edd7263d8a9 +/agent-note-installed-wheel-python-runtime-pull-request-validation/decision: + en: a15c7c13f167e5ac + zh: a15c7c13f167e5ac +/agent-note-installed-wheel-python-runtime-pull-request-validation/decision/installed-artifact-boundary: + en: 57b22736a43ce8ef + zh: b80a12ade299258a +/agent-note-installed-wheel-python-runtime-pull-request-validation/decision/keyless-behavior: + en: c1b78f6c3cedd4d2 + zh: 03e267c73af6036b +/agent-note-installed-wheel-python-runtime-pull-request-validation/decision/real-deepseek-api: + en: 0f98f5b5f78b5603 + zh: 95ee8bafa66d6b1b +/agent-note-installed-wheel-python-runtime-pull-request-validation/decision/required-targets: + en: 4eafb728b9b3d596 + zh: e127fdfe44659767 +/agent-note-installed-wheel-python-runtime-pull-request-validation/existing-decisions-and-supersession: + en: 04aa439d4e607324 + zh: f4c1d24b6a418cc4 +/agent-note-installed-wheel-python-runtime-pull-request-validation/alternatives-considered: + en: 360a7e4cd0f6e1ec + zh: 53beb38864ff052d +/agent-note-installed-wheel-python-runtime-pull-request-validation/consequences: + en: 6161aae704abdd20 + zh: 4c81c9f6d1bef7d4 diff --git a/.agents/notes/implemented/testing/2026-08-24-session-log-snapshot-corpus.i18n.yaml b/.agents/notes/implemented/testing/2026-08-24-session-log-snapshot-corpus.i18n.yaml index 9cb458cb68..a82fdb832c 100644 --- a/.agents/notes/implemented/testing/2026-08-24-session-log-snapshot-corpus.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-08-24-session-log-snapshot-corpus.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-24-session-log-snapshot-corpus.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-08-24-session-log-snapshot-corpus.md -2026-08-24-session-log-snapshot-corpus.md: a9001c2eabd610e08cfb1177f2b1339f306320af -2026-08-24-session-log-snapshot-corpus.zh.md: d02c798af23a205993e92ed72a0f3a162f8bdded +/agent-note-session-log-snapshot-corpus: + en: 9cb40b5081c110bc + zh: 17c221d99b579119 +/agent-note-session-log-snapshot-corpus/problem: + en: ec6f331737be909e + zh: 5faee4c81cf2314f +/agent-note-session-log-snapshot-corpus/decision: + en: 1611b352461c63c5 + zh: f32a5229bac3264a +/agent-note-session-log-snapshot-corpus/alternatives-considered: + en: 76db318c1c2dad2d + zh: b868b7c9b29c1e00 +/agent-note-session-log-snapshot-corpus/invariants: + en: 04098d11861c90ae + zh: 6af6c376fe1ba8bb +/agent-note-session-log-snapshot-corpus/consequences: + en: 3d5810a9518fcb8d + zh: 075ad9a226b8b312 +/agent-note-session-log-snapshot-corpus/risks: + en: 333b33afa03cf4e1 + zh: 3b8f3bcdf57cfe8e diff --git a/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.i18n.yaml b/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.i18n.yaml index 2eb9f0f8ea..fa8f7c9390 100644 --- a/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-04-session-open-performance-gate.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-04-session-open-performance-gate.md -2026-09-04-session-open-performance-gate.md: 1b2b0aabb79aceb0ac515a1d90ba3e2ba042535c -2026-09-04-session-open-performance-gate.zh.md: 9ad56796aac6310977aedfff0f9188e46cbbf3d7 +/agent-note-required-ci-performance-gate-for-opening-large-sessions: + en: 3e87960dd29e5814 + zh: 7abaea0b9397e16d +/agent-note-required-ci-performance-gate-for-opening-large-sessions/problem: + en: 00ba1f66195351e2 + zh: a738b81adceda351 +/agent-note-required-ci-performance-gate-for-opening-large-sessions/decision: + en: 75679c69eeeb1e02 + zh: 49ea45fa46ae3fcb +/agent-note-required-ci-performance-gate-for-opening-large-sessions/calibration-evidence: + en: f1001a139470f6b7 + zh: b7b46f96b84b1271 +/agent-note-required-ci-performance-gate-for-opening-large-sessions/calibration-evidence/indexed-traversal-of-stored-json-arrays: + en: 4ff4df8437e978a8 + zh: 642ac8ab685c7a11 +/agent-note-required-ci-performance-gate-for-opening-large-sessions/alternatives-considered: + en: 5debbc2a0382ed13 + zh: 415d11776f73f871 +/agent-note-required-ci-performance-gate-for-opening-large-sessions/consequences: + en: 845730942e93aa38 + zh: f8d6cd2a8e5e6859 diff --git a/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.i18n.yaml b/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.i18n.yaml index aeaed20365..60da3ac257 100644 --- a/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-backend-continuation-performance.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.md -2026-09-06-backend-continuation-performance.md: a2423a404e23f6a4ccb6a4fb177ec6842b7bf584 -2026-09-06-backend-continuation-performance.zh.md: 942cfd37528d121bf482c48c5d75dd1f2de30887 +/agent-note-performance-baselines-for-tool-heavy-backend-continuation: + en: 542fea07db8861a3 + zh: 3a9d381c2366f5ec +/agent-note-performance-baselines-for-tool-heavy-backend-continuation/problem: + en: c6a89dac7dea293a + zh: b10610932d55996c +/agent-note-performance-baselines-for-tool-heavy-backend-continuation/decision: + en: 3429525a40e02b95 + zh: 92f12beb81003101 +/agent-note-performance-baselines-for-tool-heavy-backend-continuation/calibration-evidence: + en: 4f47ca6859cc2d70 + zh: 5bfe8314fd30d82b +/agent-note-performance-baselines-for-tool-heavy-backend-continuation/alternatives-considered: + en: 3a61dff7c926eb22 + zh: 8f2633b16be78233 +/agent-note-performance-baselines-for-tool-heavy-backend-continuation/consequences: + en: 0ffe42f70b26de41 + zh: 367038e53dc04ff4 diff --git a/.agents/notes/implemented/testing/2026-09-06-client-assembly-test-line.i18n.yaml b/.agents/notes/implemented/testing/2026-09-06-client-assembly-test-line.i18n.yaml index 1e0850bf40..f4079749aa 100644 --- a/.agents/notes/implemented/testing/2026-09-06-client-assembly-test-line.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-06-client-assembly-test-line.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-client-assembly-test-line.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-06-client-assembly-test-line.md -2026-09-06-client-assembly-test-line.md: d2515c0689b9ea39bf14e4ce653a26d9a81ebfb8 -2026-09-06-client-assembly-test-line.zh.md: 90b5768db4307c551b895d7101324f329f42c955 +/agent-note-whole-client-test-tier-over-an-endpoint-named-remote-mock: + en: f11c0f43c9f9be09 + zh: 991625645ac91f06 +/agent-note-whole-client-test-tier-over-an-endpoint-named-remote-mock/problem: + en: 33c0c3670dae25c3 + zh: 4d91a11eea9bbb8f +/agent-note-whole-client-test-tier-over-an-endpoint-named-remote-mock/decision: + en: af415345cccb067e + zh: 8e82f7136f61a80e +/agent-note-whole-client-test-tier-over-an-endpoint-named-remote-mock/product-exports-added-for-the-tier: + en: b45dd80dbe278c5f + zh: cdfb145cd8fab276 +/agent-note-whole-client-test-tier-over-an-endpoint-named-remote-mock/alternatives-considered: + en: 2898d540f4bb1ee2 + zh: a3e2f1ea4cc8154f +/agent-note-whole-client-test-tier-over-an-endpoint-named-remote-mock/consequences: + en: b6a9721dec64d304 + zh: 160edfa839b7d024 +/agent-note-whole-client-test-tier-over-an-endpoint-named-remote-mock/deferred: + en: 1f18c8a38967698a + zh: f6809d290748d9cf +/agent-note-whole-client-test-tier-over-an-endpoint-named-remote-mock/testing: + en: 84fd4b8cc4a4abc8 + zh: f5d8fcb31a6d103b diff --git a/.agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.i18n.yaml b/.agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.i18n.yaml index bc0def0cce..1d0b70851d 100644 --- a/.agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-frontend-performance-budgets.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.md -2026-09-06-frontend-performance-budgets.md: ea91edf8d39d838ab58204f8516d9d1e9d50109f -2026-09-06-frontend-performance-budgets.zh.md: 84c115ef09f55babf96eb1ef8d2f472a139dd55d +/agent-note-frontend-large-session-performance-budgets: + en: 443578f129feecd8 + zh: fcc3b1bf7dcdb1fb +/agent-note-frontend-large-session-performance-budgets/problem: + en: 9bf1200b5f980008 + zh: d2dc07922817c581 +/agent-note-frontend-large-session-performance-budgets/decision: + en: 0ff66ffe55696498 + zh: c05736fde021bcc4 +/agent-note-frontend-large-session-performance-budgets/calibration: + en: f3be2a0d346e80cc + zh: c49cc56e7714f68c +/agent-note-frontend-large-session-performance-budgets/calibration/actual-ci-runs: + en: d4d6aebafcdb8c12 + zh: 112d3ca1a4ea8ae1 +/agent-note-frontend-large-session-performance-budgets/calibration/standard-hosted-expectations-and-input-scheduling: + en: 8cb6299dbb42a9fe + zh: 51ef49d4fcaeb92f +/agent-note-frontend-large-session-performance-budgets/alternatives-considered: + en: 1472bd425ef0daec + zh: a89811758d70331e +/agent-note-frontend-large-session-performance-budgets/consequences: + en: 3f4f510612875d54 + zh: 3a4af464f159bfe8 diff --git a/.agents/notes/implemented/testing/2026-09-06-pr-ci-runner-temporary-storage.i18n.yaml b/.agents/notes/implemented/testing/2026-09-06-pr-ci-runner-temporary-storage.i18n.yaml index dccefc4520..aa5bb20d1f 100644 --- a/.agents/notes/implemented/testing/2026-09-06-pr-ci-runner-temporary-storage.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-06-pr-ci-runner-temporary-storage.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-pr-ci-runner-temporary-storage.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-06-pr-ci-runner-temporary-storage.md -2026-09-06-pr-ci-runner-temporary-storage.md: 59d609c08e1b228ae9a9705140f2832305dfead5 -2026-09-06-pr-ci-runner-temporary-storage.zh.md: f6765212af2424f2080063946f9104125993b9d5 +/agent-note-runner-owned-temporary-storage-for-pr-ci: + en: 2f9ebea4c52687b3 + zh: 5924c9657eea7ff7 +/agent-note-runner-owned-temporary-storage-for-pr-ci/problem: + en: 5787327a360024d9 + zh: ee9b8cb63d79e551 +/agent-note-runner-owned-temporary-storage-for-pr-ci/decision: + en: 44990c35e1cb69cb + zh: 38a6bed07b5596e3 +/agent-note-runner-owned-temporary-storage-for-pr-ci/recorded-acp-completion-order: + en: 51f2f962db14ba9c + zh: 5fc8a908431c3865 +/agent-note-runner-owned-temporary-storage-for-pr-ci/workspace-grant-fixture-placement: + en: 1008b2fc61d01b10 + zh: f5314d10980611ef +/agent-note-runner-owned-temporary-storage-for-pr-ci/live-verification-and-browser-fixture-inputs: + en: 0f8e8478a3fb6486 + zh: 5d74c6902ea9831c +/agent-note-runner-owned-temporary-storage-for-pr-ci/alternatives-considered: + en: 8b0f2798f91ff190 + zh: f6e871a723e4d079 +/agent-note-runner-owned-temporary-storage-for-pr-ci/consequences: + en: ff73f9c3daeb33be + zh: 28f4245c275c4109 diff --git a/.agents/notes/implemented/testing/2026-09-06-python-runtime-install-retry.i18n.yaml b/.agents/notes/implemented/testing/2026-09-06-python-runtime-install-retry.i18n.yaml index 834bf27d4b..4a7ab9e93d 100644 --- a/.agents/notes/implemented/testing/2026-09-06-python-runtime-install-retry.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-06-python-runtime-install-retry.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-python-runtime-install-retry.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-06-python-runtime-install-retry.md -2026-09-06-python-runtime-install-retry.md: 639fe2814ae1b3beadcd47d3b9eac15408c585cc -2026-09-06-python-runtime-install-retry.zh.md: 7a7943f43fcec536542c5aef0e608e177f64907f +/agent-note-bounded-retry-for-python-runtime-dependency-install: + en: 610eeadbda25f100 + zh: e063790ef0b766c9 +/agent-note-bounded-retry-for-python-runtime-dependency-install/problem: + en: ea99de707130a978 + zh: 0d8d853cf38e903a +/agent-note-bounded-retry-for-python-runtime-dependency-install/decision: + en: 8a91f9e5ade1fbbe + zh: 82851f2d37f6a216 +/agent-note-bounded-retry-for-python-runtime-dependency-install/alternatives-considered: + en: c9bee05dfbb068aa + zh: 7f0712a941209116 +/agent-note-bounded-retry-for-python-runtime-dependency-install/consequences: + en: 4d036332d39c88a6 + zh: aac5dd7e7f09df2a diff --git a/.agents/notes/implemented/testing/2026-09-06-standard-hosted-benchmark-runner.i18n.yaml b/.agents/notes/implemented/testing/2026-09-06-standard-hosted-benchmark-runner.i18n.yaml index feddeffb9f..50c9f04da5 100644 --- a/.agents/notes/implemented/testing/2026-09-06-standard-hosted-benchmark-runner.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-06-standard-hosted-benchmark-runner.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-standard-hosted-benchmark-runner.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-06-standard-hosted-benchmark-runner.md -2026-09-06-standard-hosted-benchmark-runner.md: af95af6ee8cef1128a5475863ea7a1aaf66f30b9 -2026-09-06-standard-hosted-benchmark-runner.zh.md: 47095a5b2e91318c2f3ec5ac3cc9f6df3bce04d6 +/agent-note-standard-hosted-runner-for-required-benchmarks: + en: 07d81b0ddc7349cd + zh: 0494136a627f09a4 +/agent-note-standard-hosted-runner-for-required-benchmarks/problem: + en: e930cd992a15b811 + zh: fe791e9581ff6a35 +/agent-note-standard-hosted-runner-for-required-benchmarks/decision: + en: 07bc990d5c68d617 + zh: 5bf08df36181b2a6 +/agent-note-standard-hosted-runner-for-required-benchmarks/alternatives-considered: + en: 82f0eab2a8e66383 + zh: 6677a34a53b8915f +/agent-note-standard-hosted-runner-for-required-benchmarks/consequences: + en: 173caff985f5ff21 + zh: 83f3ef068ec62439 diff --git a/.agents/notes/implemented/testing/2026-09-07-publint-test-subprocess-lifetime.i18n.yaml b/.agents/notes/implemented/testing/2026-09-07-publint-test-subprocess-lifetime.i18n.yaml index 75ddc0220c..336d27a518 100644 --- a/.agents/notes/implemented/testing/2026-09-07-publint-test-subprocess-lifetime.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-07-publint-test-subprocess-lifetime.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-publint-test-subprocess-lifetime.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-07-publint-test-subprocess-lifetime.md -2026-09-07-publint-test-subprocess-lifetime.md: f8b0e0455f44e6cfc7dd1ce120b0edc07e88180a -2026-09-07-publint-test-subprocess-lifetime.zh.md: dd0533752b13f337e5f2453f01ca87f17d6ec3b2 +/agent-note-publint-test-subprocesses-inherit-the-execution-lane-deadline: + en: 762197e4e97b62a1 + zh: a2ac103348f6e692 +/agent-note-publint-test-subprocesses-inherit-the-execution-lane-deadline/problem: + en: a5fb106b97023934 + zh: 537bd40564850192 +/agent-note-publint-test-subprocesses-inherit-the-execution-lane-deadline/decision: + en: 62cc75fa54d44d80 + zh: 72d296ea1d5448bc +/agent-note-publint-test-subprocesses-inherit-the-execution-lane-deadline/alternatives-considered: + en: 5cc52a67c84dd039 + zh: 9fdc5ac07da9a056 +/agent-note-publint-test-subprocesses-inherit-the-execution-lane-deadline/consequences: + en: a2d7dabc61d37634 + zh: 753addcc45383715 diff --git a/.agents/notes/implemented/testing/2026-09-07-pwsh-ci-observable-completion.i18n.yaml b/.agents/notes/implemented/testing/2026-09-07-pwsh-ci-observable-completion.i18n.yaml index e52920e249..d9e1bb9952 100644 --- a/.agents/notes/implemented/testing/2026-09-07-pwsh-ci-observable-completion.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-07-pwsh-ci-observable-completion.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-pwsh-ci-observable-completion.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-07-pwsh-ci-observable-completion.md -2026-09-07-pwsh-ci-observable-completion.md: 2cd42296c14602f1f4aad68b8988f84dabbd5479 -2026-09-07-pwsh-ci-observable-completion.zh.md: 9ea83963be7faa274e53b1b9260222f71553e0f4 +/agent-note-powershell-ci-completion-and-profile-expectations: + en: 30366de41f8f71f6 + zh: d343887adae38ef4 +/agent-note-powershell-ci-completion-and-profile-expectations/problem: + en: 5806986dfd58191c + zh: ac082211e112c2d4 +/agent-note-powershell-ci-completion-and-profile-expectations/decision: + en: f23d0691bc168ad7 + zh: 2873eb08c925f2f6 +/agent-note-powershell-ci-completion-and-profile-expectations/alternatives-considered: + en: 6fde4f1b34fdd5e7 + zh: 6bc1ef73ce0e2645 +/agent-note-powershell-ci-completion-and-profile-expectations/consequences: + en: d486f9db082655db + zh: 01c46ff6b700cb15 diff --git a/.agents/notes/implemented/testing/2026-09-07-subagent-teardown-test-budgets.i18n.yaml b/.agents/notes/implemented/testing/2026-09-07-subagent-teardown-test-budgets.i18n.yaml index 9a305f4c7f..10306946dc 100644 --- a/.agents/notes/implemented/testing/2026-09-07-subagent-teardown-test-budgets.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-07-subagent-teardown-test-budgets.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-07-subagent-teardown-test-budgets.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-07-subagent-teardown-test-budgets.md -2026-09-07-subagent-teardown-test-budgets.md: 372c8b311054b11d86b3057415dd98584d94be9f -2026-09-07-subagent-teardown-test-budgets.zh.md: 8539664280c5fe720f27459fdb2d14c47ad3e780 +/agent-note-subagent-teardown-tests-inherit-their-execution-lane-budgets: + en: b704be92bc9b9b3c + zh: 4154bd2d89177e5d +/agent-note-subagent-teardown-tests-inherit-their-execution-lane-budgets/problem: + en: 5853599207f6b3bb + zh: d58b5e8e19d93a4f +/agent-note-subagent-teardown-tests-inherit-their-execution-lane-budgets/decision: + en: 721ea003ebaef8c7 + zh: e17be423bc4c7568 +/agent-note-subagent-teardown-tests-inherit-their-execution-lane-budgets/alternatives-considered: + en: 3ad30b2574818a61 + zh: d323adddd5065ae4 +/agent-note-subagent-teardown-tests-inherit-their-execution-lane-budgets/consequences: + en: 20d060fe30ada016 + zh: c73937bffbb251c0 diff --git a/.agents/notes/implemented/testing/2026-09-08-ci-completion-observations.i18n.yaml b/.agents/notes/implemented/testing/2026-09-08-ci-completion-observations.i18n.yaml index 297fed6b49..dc92e99d72 100644 --- a/.agents/notes/implemented/testing/2026-09-08-ci-completion-observations.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-08-ci-completion-observations.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-ci-completion-observations.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-08-ci-completion-observations.md -2026-09-08-ci-completion-observations.md: 30145f26fccd1ca7d174d76df738f100827cc32a -2026-09-08-ci-completion-observations.zh.md: a819d6ad45d80b7fce2f67025629d8d6cf9f8344 +/agent-note-ci-fixture-completion-and-isolation: + en: f5c180b0aad40b22 + zh: 89af7791bfbed707 +/agent-note-ci-fixture-completion-and-isolation/problem: + en: b7350054dcefd411 + zh: 61fd5b508f804ca1 +/agent-note-ci-fixture-completion-and-isolation/decision: + en: 8b245a4f4974e855 + zh: 93963695545d13ed +/agent-note-ci-fixture-completion-and-isolation/decision/built-client-import-classification: + en: 443f119bc5d5b49f + zh: b1c53efd3a216d63 +/agent-note-ci-fixture-completion-and-isolation/alternatives-considered: + en: 569976702b273da6 + zh: 3a5e5faba0074398 +/agent-note-ci-fixture-completion-and-isolation/consequences: + en: 168df70afdad308d + zh: 0e77a4741fa8024b diff --git a/.agents/notes/implemented/testing/2026-09-08-ci-readiness-and-completion.i18n.yaml b/.agents/notes/implemented/testing/2026-09-08-ci-readiness-and-completion.i18n.yaml index 77ca3fa1c8..bef8854202 100644 --- a/.agents/notes/implemented/testing/2026-09-08-ci-readiness-and-completion.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-08-ci-readiness-and-completion.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-ci-readiness-and-completion.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-08-ci-readiness-and-completion.md -2026-09-08-ci-readiness-and-completion.md: 1bf4f701f1b66debd982f1b786116e437e35dea4 -2026-09-08-ci-readiness-and-completion.zh.md: ae6d4e0195c66435fba22efae2376f6979ea9f6d +/agent-note-ci-assertions-wait-for-owned-completion: + en: 784e4056f020fab9 + zh: 941e7091a7621c9e +/agent-note-ci-assertions-wait-for-owned-completion/problem: + en: a7fe3958c0c18911 + zh: cce83727500187bc +/agent-note-ci-assertions-wait-for-owned-completion/decision: + en: 2b0ff4ab1d18bd1c + zh: 39556bf95aec3c56 +/agent-note-ci-assertions-wait-for-owned-completion/alternatives-considered: + en: 07ee7017cc6f6e74 + zh: b42f742932edd3f8 +/agent-note-ci-assertions-wait-for-owned-completion/consequences: + en: 70258f58a1e781bb + zh: fabc014ced9872f5 diff --git a/.agents/notes/implemented/testing/2026-09-09-user-patch-hmr-test-delivery.i18n.yaml b/.agents/notes/implemented/testing/2026-09-09-user-patch-hmr-test-delivery.i18n.yaml index 13264740b3..be1357732e 100644 --- a/.agents/notes/implemented/testing/2026-09-09-user-patch-hmr-test-delivery.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-09-user-patch-hmr-test-delivery.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-09-user-patch-hmr-test-delivery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-09-user-patch-hmr-test-delivery.md -2026-09-09-user-patch-hmr-test-delivery.md: 32ee3073dcb67e1f6bed70c515dd9b6990b97d03 -2026-09-09-user-patch-hmr-test-delivery.zh.md: bcd6f261c0ec4428f4f28138e7e62b80141dd981 +/agent-note-user-patch-tests-control-filesystem-event-delivery: + en: c2c70a16f6deea8b + zh: 3b11c81b87910ce7 +/agent-note-user-patch-tests-control-filesystem-event-delivery/problem: + en: 3f8862080b8c3c89 + zh: 0e83c485f02c10f1 +/agent-note-user-patch-tests-control-filesystem-event-delivery/decision: + en: a49b4a6e76725b7e + zh: 9813f60c40a19f83 +/agent-note-user-patch-tests-control-filesystem-event-delivery/alternatives-considered: + en: 5d559ee291e2e15e + zh: 828e7def587d71e8 +/agent-note-user-patch-tests-control-filesystem-event-delivery/consequences: + en: da9f64f4d269cece + zh: 6bbbcc771c5fbcde diff --git a/.agents/notes/implemented/testing/2026-09-10-desktop-local-updater-qualification.i18n.yaml b/.agents/notes/implemented/testing/2026-09-10-desktop-local-updater-qualification.i18n.yaml index 55faf9d686..f61ba057a5 100644 --- a/.agents/notes/implemented/testing/2026-09-10-desktop-local-updater-qualification.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-10-desktop-local-updater-qualification.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-desktop-local-updater-qualification.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-10-desktop-local-updater-qualification.md -2026-09-10-desktop-local-updater-qualification.md: 10c0a384106cc06aaae50d8782b58114ea86fb79 -2026-09-10-desktop-local-updater-qualification.zh.md: 9d554bc5001fc53f60ba9cd0d08b02e975f8261f +/agent-note-qualify-desktop-update-downloads-with-an-isolated-local-server: + en: 71382ca7e306c188 + zh: ee13377b994ff06a +/agent-note-qualify-desktop-update-downloads-with-an-isolated-local-server/problem: + en: a621d24f1336bf19 + zh: 56dc14cda197b301 +/agent-note-qualify-desktop-update-downloads-with-an-isolated-local-server/decision: + en: b8e5f482693b9213 + zh: 4ac670ae629d3fd1 +/agent-note-qualify-desktop-update-downloads-with-an-isolated-local-server/alternatives-considered: + en: f93809633864e337 + zh: 4bd2141c2a36e1ac +/agent-note-qualify-desktop-update-downloads-with-an-isolated-local-server/consequences: + en: 4ef44c91915206b5 + zh: f4ecf7b2d6df4932 diff --git a/.agents/notes/implemented/testing/2026-09-10-hosted-image-test-assumptions.i18n.yaml b/.agents/notes/implemented/testing/2026-09-10-hosted-image-test-assumptions.i18n.yaml index b745447152..72274416f8 100644 --- a/.agents/notes/implemented/testing/2026-09-10-hosted-image-test-assumptions.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-10-hosted-image-test-assumptions.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-hosted-image-test-assumptions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-10-hosted-image-test-assumptions.md -2026-09-10-hosted-image-test-assumptions.md: e6fe4e35848c48462e7bb9c99bc898b6ebc907c9 -2026-09-10-hosted-image-test-assumptions.zh.md: 4fe8bf2a3764b0f95268e20eb379a69c7e44ced6 +/agent-note-hosted-image-assumptions-in-the-coverage-suite: + en: b9e6c590cb18c637 + zh: 02591776cec956ea +/agent-note-hosted-image-assumptions-in-the-coverage-suite/problem: + en: c1299114bcbbbbc2 + zh: 1b38aa9c8b0a4eef +/agent-note-hosted-image-assumptions-in-the-coverage-suite/decision: + en: 00b0e2ef25435ad3 + zh: 9bf59f5ca765a94b +/agent-note-hosted-image-assumptions-in-the-coverage-suite/alternatives-considered: + en: 7cc99ab98600ed3f + zh: c302b579791a403d +/agent-note-hosted-image-assumptions-in-the-coverage-suite/consequences: + en: 96ad46667a025f85 + zh: ba04b1436b82a620 diff --git a/.agents/notes/implemented/testing/2026-09-12-connection-and-compaction-fixture-preconditions.i18n.yaml b/.agents/notes/implemented/testing/2026-09-12-connection-and-compaction-fixture-preconditions.i18n.yaml index efdce8aa1b..52fcc8494f 100644 --- a/.agents/notes/implemented/testing/2026-09-12-connection-and-compaction-fixture-preconditions.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-12-connection-and-compaction-fixture-preconditions.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-12-connection-and-compaction-fixture-preconditions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-12-connection-and-compaction-fixture-preconditions.md -2026-09-12-connection-and-compaction-fixture-preconditions.md: 9b97657c7742bb37a8a70b04350d5e6b43868f6c -2026-09-12-connection-and-compaction-fixture-preconditions.zh.md: bc73a0e84ab4f60b7f3091f60a5217dcc950cb20 +/agent-note-connection-and-compaction-fixture-preconditions: + en: ea762fbdd18bdce3 + zh: 5795a728fd210f69 +/agent-note-connection-and-compaction-fixture-preconditions/problem: + en: 43949801eda059d6 + zh: 83b579735b9d3e3f +/agent-note-connection-and-compaction-fixture-preconditions/decision: + en: 4e7091381ce185cf + zh: 6e36499f5b5e46f9 +/agent-note-connection-and-compaction-fixture-preconditions/alternatives-considered: + en: b8842654dbe80f4c + zh: e4b80e80d89203b0 +/agent-note-connection-and-compaction-fixture-preconditions/consequences: + en: 054ce1f776693cc9 + zh: dd542b1ccb1cc07d diff --git a/.agents/notes/implemented/testing/2026-09-14-desktop-installed-update-journal.i18n.yaml b/.agents/notes/implemented/testing/2026-09-14-desktop-installed-update-journal.i18n.yaml index 6ebebc30d8..ba9ba30f89 100644 --- a/.agents/notes/implemented/testing/2026-09-14-desktop-installed-update-journal.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-14-desktop-installed-update-journal.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-desktop-installed-update-journal.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-14-desktop-installed-update-journal.md -2026-09-14-desktop-installed-update-journal.md: 2a0ecbde408d1207102ba206ada333de6d123711 -2026-09-14-desktop-installed-update-journal.zh.md: 129efa7c123b6945e857e55e3632b18850ceb67d +/agent-note-preserve-installed-desktop-update-evidence-across-restarts: + en: 813f856f3457732c + zh: 4f88103f6402d309 +/agent-note-preserve-installed-desktop-update-evidence-across-restarts/problem: + en: 5401829797ce63d2 + zh: 8a05a7d216aba56d +/agent-note-preserve-installed-desktop-update-evidence-across-restarts/decision: + en: 07386e0ad4b17ea2 + zh: 8424f276161376e4 +/agent-note-preserve-installed-desktop-update-evidence-across-restarts/alternatives-considered: + en: bd3c8ebb1d8e2360 + zh: db38b0725b7eae9c +/agent-note-preserve-installed-desktop-update-evidence-across-restarts/consequences: + en: 08918c2d6d6ec745 + zh: 239edd387dba4a58 diff --git a/.agents/notes/implemented/testing/2026-09-14-desktop-installed-update-materials.i18n.yaml b/.agents/notes/implemented/testing/2026-09-14-desktop-installed-update-materials.i18n.yaml index 0c1184b114..17cae8945a 100644 --- a/.agents/notes/implemented/testing/2026-09-14-desktop-installed-update-materials.i18n.yaml +++ b/.agents/notes/implemented/testing/2026-09-14-desktop-installed-update-materials.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-desktop-installed-update-materials.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-14-desktop-installed-update-materials.md -2026-09-14-desktop-installed-update-materials.md: 1813c6d9bbdf12697e32f7440e4b654a33bb2384 -2026-09-14-desktop-installed-update-materials.zh.md: b92bb70b32e6549b8f2aed48f6aa9b2b8364fe54 +/agent-note-isolate-installed-update-materials-from-releases-and-user-data: + en: 9cb68e389e43373b + zh: c355d3df1f94a1a2 +/agent-note-isolate-installed-update-materials-from-releases-and-user-data/problem: + en: 8d63b992ff6d3161 + zh: 86d333255a5400d3 +/agent-note-isolate-installed-update-materials-from-releases-and-user-data/decision: + en: 7778333c76ab9b5d + zh: fa35b0a12a31ea23 +/agent-note-isolate-installed-update-materials-from-releases-and-user-data/alternatives-considered: + en: c608f186cc94a9d3 + zh: 39750c8347e8bece +/agent-note-isolate-installed-update-materials-from-releases-and-user-data/consequences: + en: e04b056cebbbba29 + zh: 5868709735abda3e diff --git a/.agents/notes/proposed/architecture/2026-07-19-required-cancellation-through-tool-capability-seams.i18n.yaml b/.agents/notes/proposed/architecture/2026-07-19-required-cancellation-through-tool-capability-seams.i18n.yaml index 48b4108c99..88e45a77c2 100644 --- a/.agents/notes/proposed/architecture/2026-07-19-required-cancellation-through-tool-capability-seams.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-07-19-required-cancellation-through-tool-capability-seams.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-required-cancellation-through-tool-capability-seams.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-07-19-required-cancellation-through-tool-capability-seams.md -2026-07-19-required-cancellation-through-tool-capability-seams.md: 722eefc3c79d3c1c589696bc1876d10ccbce77ea -2026-07-19-required-cancellation-through-tool-capability-seams.zh.md: 80d751e22cebd16d878f09ae9a5c15996c337603 +/agent-note-required-cancellation-through-tool-reachable-capability-seams: + en: 7999f4da8ee4fe80 + zh: ea49c90e2bbaacb8 +/agent-note-required-cancellation-through-tool-reachable-capability-seams/problem: + en: c244ddd6aadf87ad + zh: d30d623e9bf25c6b +/agent-note-required-cancellation-through-tool-reachable-capability-seams/proposal: + en: 20ed2d4cacc14f0c + zh: 19ee19bcf3596048 +/agent-note-required-cancellation-through-tool-reachable-capability-seams/proposal/scope-boundary: + en: c9df2c946d26f728 + zh: cc5bcd1710a864ef +/agent-note-required-cancellation-through-tool-reachable-capability-seams/alternatives-considered: + en: 0f2e31037bb1071c + zh: 6c654c553300ceb5 +/agent-note-required-cancellation-through-tool-reachable-capability-seams/acceptance-criteria: + en: a439a907dc6b2457 + zh: a693d1b8bb05b67f +/agent-note-required-cancellation-through-tool-reachable-capability-seams/risks: + en: c071970c88e73cb7 + zh: 58eaf135ac19ecc9 diff --git a/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.i18n.yaml b/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.i18n.yaml index 7d7f43420a..714d3ca25a 100644 --- a/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.i18n.yaml @@ -1,6 +1,49 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-24-domain-kv-storage-and-workspace.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.md -2026-07-24-domain-kv-storage-and-workspace.md: dc14648c703f60b391cf4dba947c3cb0ddeb8ccb -2026-07-24-domain-kv-storage-and-workspace.zh.md: 1cf72809193b40ab540deaa171b8df1b0d39defb +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity: + en: e1792a25ca5d684d + zh: ddb20d72b56eebf8 +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/problem: + en: 9a6abd0305f2e2bb + zh: 7c3f1132c0fa7b56 +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/proposal: + en: 34e5bde1535a2bb1 + zh: 559deb25b2ec50ba +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/proposal/dsh-storage-the-storage-hub: + en: 191afc01a150e4a0 + zh: da3fbc33875a4f60 +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/proposal/dsh-storage-json: + en: a18ec1e534a5488b + zh: 2f5beb445e30554b +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/proposal/dsh-storage-sqlite: + en: 6a26dd7ef357db74 + zh: 951b31136e2415f9 +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/proposal/dsh-domain-the-domain-data-form: + en: d51c71c793c26834 + zh: 3aab9f9695a0e225 +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/proposal/future-work-session-side-deletion-design-settled-not-implemented-this-phase: + en: a3824326587b6539 + zh: 9736e3060bd57651 +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/proposal/dsh-workspace: + en: 71351e042512c03a + zh: 965622f09f135d37 +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/proposal/reuse-and-the-session-backend-migration-outlook: + en: e586acdb16085b91 + zh: 4fae53c5b9e4fd5b +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/proposal/test-matrix: + en: 4f8560110ec03322 + zh: 574d611d6e086e96 +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/proposal/out-of-scope-list: + en: 6a8b96b362f8a742 + zh: 4ba5c96353ae46f5 +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/alternatives-considered: + en: 159649c838437048 + zh: 286e2f61c796cb1c +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/acceptance-criteria: + en: ec4f2e69de32577b + zh: 64a4d049a3b75004 +/agent-note-domain-kv-storage-capability-seam-and-the-workspace-entity/risks: + en: d5d49b31afe6cfab + zh: 19606893bbde5b03 diff --git a/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.i18n.yaml b/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.i18n.yaml index f6a8f29476..7207445070 100644 --- a/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.i18n.yaml @@ -1,6 +1,49 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-27-session-projection-and-command-log.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md -2026-07-27-session-projection-and-command-log.md: fb329a4117fdea8f4aa0e98548982c3197d9c8f6 -2026-07-27-session-projection-and-command-log.zh.md: eb359058a74c6ed53959253ae80f2002cb67a351 +/agent-note-session-projections-and-command-lifecycle-logging: + en: c4b22a24c549feb8 + zh: 4e4921326e0cd13a +/agent-note-session-projections-and-command-lifecycle-logging/problem: + en: 017166a86aa35cad + zh: b6a2e826fbed2474 +/agent-note-session-projections-and-command-lifecycle-logging/proposal: + en: d13f906be5b62374 + zh: 1cf74760f668902a +/agent-note-session-projections-and-command-lifecycle-logging/proposal/whole-value-event-rule: + en: e6c93d89a25f0d03 + zh: 65e1f5842bc74008 +/agent-note-session-projections-and-command-lifecycle-logging/proposal/host-projection-registry-dsh-session-projection-new-package: + en: 6068eb6aba54b102 + zh: 20e91466baf6ad11 +/agent-note-session-projections-and-command-lifecycle-logging/proposal/shipped-consumer-the-subagent-identity-unit: + en: 10093535660c3cae + zh: a7f4ff9e71ee6751 +/agent-note-session-projections-and-command-lifecycle-logging/proposal/wire-projections-block-on-the-history-tail-page: + en: 1a6357e8821e7951 + zh: b4b75959af4f3910 +/agent-note-session-projections-and-command-lifecycle-logging/proposal/push-frame-and-the-client-value-store-domains-write-zero-client-code: + en: e95962f82eefed51 + zh: d2b3dfa8a23c8f0f +/agent-note-session-projections-and-command-lifecycle-logging/proposal/plan-through-the-standard-command-channel-worked-example: + en: be319089ba75cae5 + zh: 2cf0ec8d0ef79564 +/agent-note-session-projections-and-command-lifecycle-logging/proposal/react-useprojection-the-fifth-framework-hook-seat: + en: 7b536bd8a51cc5dc + zh: 1ead63f6358b3799 +/agent-note-session-projections-and-command-lifecycle-logging/proposal/command-lifecycle-in-the-log: + en: a7e04451f3ed417c + zh: fb60c8729200b825 +/agent-note-session-projections-and-command-lifecycle-logging/delivery-plan: + en: 64ad8d08a8ab44e0 + zh: fb0a0f7369d0bd23 +/agent-note-session-projections-and-command-lifecycle-logging/alternatives-considered: + en: e945e84e8360e0c4 + zh: becdeb100a4c5b6b +/agent-note-session-projections-and-command-lifecycle-logging/acceptance-criteria: + en: 9dfcca30fffda225 + zh: 0beddb81d32e0ca7 +/agent-note-session-projections-and-command-lifecycle-logging/risks: + en: f0eb219b4119ca7d + zh: de870016c1623895 diff --git a/.agents/notes/proposed/architecture/2026-07-28-storage-root-and-derived-medium-recovery.i18n.yaml b/.agents/notes/proposed/architecture/2026-07-28-storage-root-and-derived-medium-recovery.i18n.yaml index f8b3f81ba2..db04c28547 100644 --- a/.agents/notes/proposed/architecture/2026-07-28-storage-root-and-derived-medium-recovery.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-07-28-storage-root-and-derived-medium-recovery.i18n.yaml @@ -1,6 +1,28 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-28-storage-root-and-derived-medium-recovery.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-07-28-storage-root-and-derived-medium-recovery.md -2026-07-28-storage-root-and-derived-medium-recovery.md: 3a4124e577b79b6775c40aed0adc63ab0c130dad -2026-07-28-storage-root-and-derived-medium-recovery.zh.md: f8d91402ba682bef616274d1a4c4fe00360271fc +/agent-note-storage-root-placement-and-derived-medium-recovery: + en: 9ebb460b39f06952 + zh: 0fc0480869566600 +/agent-note-storage-root-placement-and-derived-medium-recovery/problem: + en: e94be80df86b1da9 + zh: fe9b9dad3299562e +/agent-note-storage-root-placement-and-derived-medium-recovery/proposal: + en: bd212f50ff01960a + zh: de2c69ef9be74629 +/agent-note-storage-root-placement-and-derived-medium-recovery/proposal/one-global-storage-root-shipped-amended-form-resolved-once-at-construction-still-open: + en: 0d6497184e9ce8a0 + zh: 0e339979075c9a0e +/agent-note-storage-root-placement-and-derived-medium-recovery/proposal/declared-derived-media-reset-instead-of-reject: + en: 11e9dd194e73921f + zh: 48fbb156396dc7ec +/agent-note-storage-root-placement-and-derived-medium-recovery/alternatives-considered: + en: b5fab4b550256e96 + zh: 1d13d4de6b70e2df +/agent-note-storage-root-placement-and-derived-medium-recovery/acceptance-criteria: + en: 9d15489c12c5a23a + zh: 305a74fd2cc75aa1 +/agent-note-storage-root-placement-and-derived-medium-recovery/risks: + en: be70695cbd77824b + zh: 163ffebf285d7e5b diff --git a/.agents/notes/proposed/architecture/2026-07-29-durable-last-activity-index.i18n.yaml b/.agents/notes/proposed/architecture/2026-07-29-durable-last-activity-index.i18n.yaml index 0466c8f8cc..bab183a3a2 100644 --- a/.agents/notes/proposed/architecture/2026-07-29-durable-last-activity-index.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-07-29-durable-last-activity-index.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-29-durable-last-activity-index.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-07-29-durable-last-activity-index.md -2026-07-29-durable-last-activity-index.md: f007f01bf34c830ef9c0093e58ca86f07416d68c -2026-07-29-durable-last-activity-index.zh.md: c3259f47bcf02f6214ea6081730ee1e850c27e77 +/agent-note-record-last-activity-in-the-session-index: + en: f64dc6aee10c755f + zh: a28d8450c78b0c01 +/agent-note-record-last-activity-in-the-session-index/problem: + en: 332469396acd98d4 + zh: c9e4d587628fc0e7 +/agent-note-record-last-activity-in-the-session-index/proposal: + en: 2260380e10b59eb6 + zh: dcf5a7f2d6003021 +/agent-note-record-last-activity-in-the-session-index/alternatives-considered: + en: 9034b95d80405f9c + zh: 573e1dcd10b62344 +/agent-note-record-last-activity-in-the-session-index/acceptance-criteria: + en: ec546e4feceb77a7 + zh: a29c9268e1c189c7 +/agent-note-record-last-activity-in-the-session-index/risks: + en: 9aaf88097b46e9b6 + zh: d16e5bbbe221b139 +/agent-note-record-last-activity-in-the-session-index/related: + en: 3fde35c997f273f8 + zh: 2d063c34cc9fe0bb diff --git a/.agents/notes/proposed/architecture/2026-08-08-semantic-composer-chain-phases.i18n.yaml b/.agents/notes/proposed/architecture/2026-08-08-semantic-composer-chain-phases.i18n.yaml index 2345992ba4..311038880f 100644 --- a/.agents/notes/proposed/architecture/2026-08-08-semantic-composer-chain-phases.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-08-08-semantic-composer-chain-phases.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-08-semantic-composer-chain-phases.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-08-08-semantic-composer-chain-phases.md -2026-08-08-semantic-composer-chain-phases.md: 8dab5afcdd8025467ba2eeb55406d2464376a8fa -2026-08-08-semantic-composer-chain-phases.zh.md: d00332b1552cf83eb969c764a33a56e2f61b1633 +/agent-note-semantic-phases-for-composer-chain-election: + en: b083187ad8ead004 + zh: b22a0dd83c37c557 +/agent-note-semantic-phases-for-composer-chain-election/problem: + en: 45193c3a6f3d29bf + zh: 7f508649dbe65db5 +/agent-note-semantic-phases-for-composer-chain-election/proposal: + en: 9dc3866376b4590b + zh: 93c2208fe9a43d91 +/agent-note-semantic-phases-for-composer-chain-election/alternatives-considered: + en: 966a5082d8c2fe35 + zh: 6a384edcdec8495e +/agent-note-semantic-phases-for-composer-chain-election/acceptance-criteria: + en: 7ecfc42bcf0be41a + zh: 4efae40db6e6768b +/agent-note-semantic-phases-for-composer-chain-election/risks: + en: 06969296bb3bd8d6 + zh: f90e5cc35d52c53a diff --git a/.agents/notes/proposed/architecture/2026-09-06-logical-session-storage-rebuild.i18n.yaml b/.agents/notes/proposed/architecture/2026-09-06-logical-session-storage-rebuild.i18n.yaml index 9fa4bb0ea1..831a010177 100644 --- a/.agents/notes/proposed/architecture/2026-09-06-logical-session-storage-rebuild.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-09-06-logical-session-storage-rebuild.i18n.yaml @@ -1,6 +1,55 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-06-logical-session-storage-rebuild.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-09-06-logical-session-storage-rebuild.md -2026-09-06-logical-session-storage-rebuild.md: 66a7163085e61418f18fcfd6b91c8bfcdde1d626 -2026-09-06-logical-session-storage-rebuild.zh.md: cf37e88f45ed62a9eddc533acca8806a2def3491 +/agent-note-logical-session-and-storage-rebuild: + en: 035f8aa28d4fb486 + zh: 4fa5eef40371cf2f +/agent-note-logical-session-and-storage-rebuild/problem: + en: fe3de6c728124b77 + zh: a28e89b8fee09662 +/agent-note-logical-session-and-storage-rebuild/proposal: + en: 68347f4cef24d57d + zh: e11eaec209be63c6 +/agent-note-logical-session-and-storage-rebuild/stage-1-one-public-logical-session-interface: + en: 27e8e604c508ca73 + zh: 70247d9608e139a4 +/agent-note-logical-session-and-storage-rebuild/stage-1-one-public-logical-session-interface/public-model: + en: add476512bd9ef36 + zh: a8a5225ccd22ec07 +/agent-note-logical-session-and-storage-rebuild/stage-1-one-public-logical-session-interface/stage-1-substages: + en: 9b28d667b2fd1b28 + zh: be44f9f96f698bf2 +/agent-note-logical-session-and-storage-rebuild/stage-1-one-public-logical-session-interface/stage-progress: + en: 4903b4362660063e + zh: ba06aeb34539ef8d +/agent-note-logical-session-and-storage-rebuild/stage-1-one-public-logical-session-interface/invariants: + en: 81fc51ad0abe4f65 + zh: a9dad4cb9d5905a1 +/agent-note-logical-session-and-storage-rebuild/stage-1-one-public-logical-session-interface/enforcement-and-completion: + en: ca6c3e02033b0d01 + zh: 54a89a7e47c2d282 +/agent-note-logical-session-and-storage-rebuild/destination-architecture: + en: e0b4199ec0d5a669 + zh: abc06df82b3f357e +/agent-note-logical-session-and-storage-rebuild/destination-architecture/ownership-rules: + en: cf9d6e20f25929ff + zh: 46c0f13a1f562e0f +/agent-note-logical-session-and-storage-rebuild/destination-architecture/later-stages: + en: d61edd7e232bcb44 + zh: f9065dd60d49bc13 +/agent-note-logical-session-and-storage-rebuild/compatibility-and-non-goals: + en: bf81660f7d4638fa + zh: 4d59310d2e6476fd +/agent-note-logical-session-and-storage-rebuild/references: + en: 32c7669fd961ad1a + zh: 09dca97558a3e7b0 +/agent-note-logical-session-and-storage-rebuild/alternatives-considered: + en: 4bc014b676d93c13 + zh: 1e0a04856da60bb0 +/agent-note-logical-session-and-storage-rebuild/acceptance-criteria: + en: 1a9dfc903efe9627 + zh: f23ff556ffa33f64 +/agent-note-logical-session-and-storage-rebuild/risks: + en: 0916205231867aff + zh: 6efe11a2375d5459 diff --git a/.agents/notes/proposed/architecture/2026-09-10-session-capability-protocols.i18n.yaml b/.agents/notes/proposed/architecture/2026-09-10-session-capability-protocols.i18n.yaml index 70f55ab524..39ee8dfa14 100644 --- a/.agents/notes/proposed/architecture/2026-09-10-session-capability-protocols.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-09-10-session-capability-protocols.i18n.yaml @@ -1,6 +1,46 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-session-capability-protocols.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-09-10-session-capability-protocols.md -2026-09-10-session-capability-protocols.md: 6cdc920745d6c98aa10326d1f8e5a4acec3b523d -2026-09-10-session-capability-protocols.zh.md: a242edd419ecbb36556f85aa2d537fe78f68afff +/agent-note-session-capability-protocols: + en: ca990e74165b25e8 + zh: f6749481ec3787e9 +/agent-note-session-capability-protocols/problem: + en: dc259b9d03444112 + zh: 3f7ea3fc166f4f8d +/agent-note-session-capability-protocols/proposal: + en: 31089a7378fdbbae + zh: e4aa40eb444526d0 +/agent-note-session-capability-protocols/proposal/developer-convention-during-migration: + en: 0756ce3afbe3837a + zh: 22ab431cb95405a7 +/agent-note-session-capability-protocols/proposal/logicalsession: + en: f20d151670c882c5 + zh: 91eeebffb10341b8 +/agent-note-session-capability-protocols/proposal/sessionservice: + en: ab0c6458dc1b1fc6 + zh: bf42ff2c99045342 +/agent-note-session-capability-protocols/proposal/sessionstorage: + en: 2090c7003fe92f52 + zh: 4d84b58cc91b73cc +/agent-note-session-capability-protocols/proposal/sessionprojectionport: + en: 030ee3198b7b9e68 + zh: 4267622d67cfd5a1 +/agent-note-session-capability-protocols/proposal/sessionquery: + en: 6da206b02c1eb698 + zh: 347248e3fa322df9 +/agent-note-session-capability-protocols/proposal/overall-architecture: + en: 68e046f0f22eb8d6 + zh: 851c3034df623b3a +/agent-note-session-capability-protocols/proposal/dependency-rule: + en: 6ce178b8e50dbbf4 + zh: 60e0a37b1caa2d3f +/agent-note-session-capability-protocols/alternatives-considered: + en: 4dd5911de0859b8f + zh: 5ba12aa6ba4effbb +/agent-note-session-capability-protocols/acceptance-criteria: + en: 82bfc842f7a0e82e + zh: 1d7bcd72be514e25 +/agent-note-session-capability-protocols/risks: + en: f8c5864d4518322b + zh: 619ef9e236515bf8 diff --git a/.agents/notes/proposed/architecture/2026-09-10-session-data-compatibility.i18n.yaml b/.agents/notes/proposed/architecture/2026-09-10-session-data-compatibility.i18n.yaml index ecc2f6cbfa..7d4523b550 100644 --- a/.agents/notes/proposed/architecture/2026-09-10-session-data-compatibility.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-09-10-session-data-compatibility.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-session-data-compatibility.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-09-10-session-data-compatibility.md -2026-09-10-session-data-compatibility.md: 5784ca2a3ae3bae91030c177a8eca3c08f93c8af -2026-09-10-session-data-compatibility.zh.md: 39e5e071703653d9a83d38420d929c0b8a310f68 +/agent-note-session-historical-data-compatibility: + en: bcc2d17eb800361c + zh: 8f74cc9e1c9f3729 +/agent-note-session-historical-data-compatibility/problem: + en: d125f39227dc17ee + zh: ab83089486d70796 +/agent-note-session-historical-data-compatibility/proposal: + en: 986dd8097aac4d3d + zh: 986dd8097aac4d3d +/agent-note-session-historical-data-compatibility/proposal/start-with-0-1-5-rc-1-v3: + en: c0f09bb8e2c3aac5 + zh: 4b7c8d3b1d1a0f76 +/agent-note-session-historical-data-compatibility/proposal/effect-on-ordinary-users: + en: 7e8616cc65f825e3 + zh: db9e5a3e1090985e +/agent-note-session-historical-data-compatibility/proposal/invariants-after-provider-replacement: + en: c3a8bb8665ca6d95 + zh: 96a4b52c31fcc19d +/agent-note-session-historical-data-compatibility/alternatives-considered: + en: 8d34713ac1ca54ea + zh: 25b01743baa11434 +/agent-note-session-historical-data-compatibility/acceptance-criteria: + en: abd8b41ca33f4398 + zh: 54865a11723b670f +/agent-note-session-historical-data-compatibility/risks: + en: 2cb87e77f846c8fe + zh: e4e2f7eae02e0a7e diff --git a/.agents/notes/proposed/architecture/2026-09-10-session-developer-transition.i18n.yaml b/.agents/notes/proposed/architecture/2026-09-10-session-developer-transition.i18n.yaml index 5c8fb0f4fb..074a3d3a03 100644 --- a/.agents/notes/proposed/architecture/2026-09-10-session-developer-transition.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-09-10-session-developer-transition.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-session-developer-transition.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-09-10-session-developer-transition.md -2026-09-10-session-developer-transition.md: cde78cbc2005435c48c823b2902da5e9e129d131 -2026-09-10-session-developer-transition.zh.md: a20cb8d4ef0c10fe0abfe25c7189d2f0eb43333c +/agent-note-session-developer-transition-rules: + en: e5554b1d8a98818d + zh: e1ed935f755924b6 +/agent-note-session-developer-transition-rules/problem: + en: bc0c73010718f890 + zh: a8e3ea46366c1c7a +/agent-note-session-developer-transition-rules/proposal: + en: 1f1df17eaf8f96d8 + zh: 1b767d61d3e2e641 +/agent-note-session-developer-transition-rules/proposal/maintenance-rules: + en: 269be7b0b4066b52 + zh: f61684ac468d00ef +/agent-note-session-developer-transition-rules/proposal/common-operation-migrations: + en: 62cc198142f1477f + zh: 37e806f78817e5e3 +/agent-note-session-developer-transition-rules/proposal/how-a-new-contributor-starts: + en: 0fcd7c50d5659978 + zh: 8ada6e3a6f3d6cb3 +/agent-note-session-developer-transition-rules/alternatives-considered: + en: dc22bb7bfbf8cb80 + zh: 8c3bcbe5b1caf20e +/agent-note-session-developer-transition-rules/acceptance-criteria: + en: 630c5d3985fee1e2 + zh: cd107c748ec702ef +/agent-note-session-developer-transition-rules/risks: + en: 4719bc8122ee39fa + zh: 30eaecfd796deba8 diff --git a/.agents/notes/proposed/architecture/2026-09-10-session-refactor-faq.i18n.yaml b/.agents/notes/proposed/architecture/2026-09-10-session-refactor-faq.i18n.yaml index f6433da311..649538063a 100644 --- a/.agents/notes/proposed/architecture/2026-09-10-session-refactor-faq.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-09-10-session-refactor-faq.i18n.yaml @@ -1,6 +1,46 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-10-session-refactor-faq.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-09-10-session-refactor-faq.md -2026-09-10-session-refactor-faq.md: cae6dbaaf0354836c34d1414da16f7b274da382e -2026-09-10-session-refactor-faq.zh.md: b0d5099250d439a133ca80b6f555d78541906367 +/agent-note-session-refactor-faq: + en: e51be5edaac914bc + zh: 2e3ef4006e0ab07d +/agent-note-session-refactor-faq/problem: + en: dd6312b4ffd1f4b4 + zh: 16d132992aaf81fc +/agent-note-session-refactor-faq/proposal: + en: 986dd8097aac4d3d + zh: 986dd8097aac4d3d +/agent-note-session-refactor-faq/proposal/why-logicalsession: + en: f3826d6dba15dd3f + zh: c5f63ae9322dd924 +/agent-note-session-refactor-faq/proposal/is-concrete-session-forbidden-immediately: + en: 129c7ac82e23e811 + zh: 834033794db12916 +/agent-note-session-refactor-faq/proposal/how-do-sessionservice-and-sessionstorage-differ: + en: 2dec5b2809ca1ea8 + zh: d6446f78a2da0e0d +/agent-note-session-refactor-faq/proposal/where-does-projection-fit: + en: 6b2ce6773bdd958b + zh: c59f2e6fcea57417 +/agent-note-session-refactor-faq/proposal/why-no-sessionsearch-or-sessionstats: + en: 49016cb52c419fa0 + zh: 1d7ad3a8d23a7d0c +/agent-note-session-refactor-faq/proposal/must-ordinary-users-migrate: + en: 561adffeb62beb3e + zh: bc11f602e9bc6a87 +/agent-note-session-refactor-faq/proposal/what-is-complete: + en: 7693e479cc3d69f2 + zh: ed827338c03c0c01 +/agent-note-session-refactor-faq/proposal/how-can-i-contribute: + en: 4fb0e060d2a6648b + zh: 03f0039e1bc32437 +/agent-note-session-refactor-faq/alternatives-considered: + en: bd143e9bcef3df2c + zh: c20c997563d10d6a +/agent-note-session-refactor-faq/acceptance-criteria: + en: a78f08bcf0c0af46 + zh: 5aa2b6952969705d +/agent-note-session-refactor-faq/risks: + en: e0db80998e7b18b4 + zh: fd6b75e582d743ed diff --git a/.agents/notes/proposed/architecture/2026-09-14-composer-model-and-draft-editor.i18n.yaml b/.agents/notes/proposed/architecture/2026-09-14-composer-model-and-draft-editor.i18n.yaml index 19ee105187..25000b2e09 100644 --- a/.agents/notes/proposed/architecture/2026-09-14-composer-model-and-draft-editor.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-09-14-composer-model-and-draft-editor.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-14-composer-model-and-draft-editor.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-09-14-composer-model-and-draft-editor.md -2026-09-14-composer-model-and-draft-editor.md: 3f66ab2c73da0a8f66bf43a821cbe5f85363867a -2026-09-14-composer-model-and-draft-editor.zh.md: aa040b0fa68961d4d5884d73791c4986b8bfab50 +/agent-note-two-stage-composer-and-drafteditor-isolation: + en: 28f1ad8c58451112 + zh: f54f43862019e385 +/agent-note-two-stage-composer-and-drafteditor-isolation/problem: + en: 6316522fcd01a9bc + zh: aa6e339e8b528a5b +/agent-note-two-stage-composer-and-drafteditor-isolation/proposal: + en: fbd8d96d050a288c + zh: d312590845174596 +/agent-note-two-stage-composer-and-drafteditor-isolation/proposal/stage-one-five-mechanical-responsibility-extractions: + en: 3add548b95979d3c + zh: c6eab5274037e6b5 +/agent-note-two-stage-composer-and-drafteditor-isolation/proposal/stage-one-five-mechanical-responsibility-extractions/stage-one-invariants: + en: b61469dcd7c9e0fe + zh: 345fca4cb1dc717b +/agent-note-two-stage-composer-and-drafteditor-isolation/proposal/stage-one-five-mechanical-responsibility-extractions/isolation-actually-achieved-in-stage-one: + en: e1e3c2479f2a7e0c + zh: be094599bb90868b +/agent-note-two-stage-composer-and-drafteditor-isolation/proposal/stage-two-behavior-changes-only: + en: 15c72b9d93a8b1bc + zh: a565969f4ec3b00a +/agent-note-two-stage-composer-and-drafteditor-isolation/proposal/stage-two-behavior-changes-only/final-state-ownership: + en: fc9cb7b515ed6fd6 + zh: ca7ac114f93852b9 +/agent-note-two-stage-composer-and-drafteditor-isolation/proposal/stage-two-behavior-changes-only/shared-content-and-synchronization-requirements: + en: 60385537149da946 + zh: 80f4aa1454efdf43 +/agent-note-two-stage-composer-and-drafteditor-isolation/alternatives-considered: + en: e0a41f0e65c4c94c + zh: fac372d2c4c2c740 +/agent-note-two-stage-composer-and-drafteditor-isolation/acceptance-criteria: + en: f9a42d215fc000fa + zh: e6f1735e6ed73279 +/agent-note-two-stage-composer-and-drafteditor-isolation/risks: + en: e01daa84a5d58247 + zh: 41def722300784a8 diff --git a/.agents/notes/proposed/architecture/2026-09-19-timed-user-question-two-settlements.i18n.yaml b/.agents/notes/proposed/architecture/2026-09-19-timed-user-question-two-settlements.i18n.yaml new file mode 100644 index 0000000000..737e671e9a --- /dev/null +++ b/.agents/notes/proposed/architecture/2026-09-19-timed-user-question-two-settlements.i18n.yaml @@ -0,0 +1,43 @@ +# Bilingual-pair consistency record for 2026-09-19-timed-user-question-two-settlements.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-09-19-timed-user-question-two-settlements.md +/agent-note-timed-user-questions-as-two-settlements: + en: 15c55d3b120b8fd4 + zh: 6b86ac34f4a1e9cd +/agent-note-timed-user-questions-as-two-settlements/problem: + en: f665127a9b5b8225 + zh: b19845f62310f3a2 +/agent-note-timed-user-questions-as-two-settlements/proposal: + en: 56ca8c0f97976358 + zh: 69163bb5f064e069 +/agent-note-timed-user-questions-as-two-settlements/proposal/modes-and-scope: + en: d23e622ee4643b48 + zh: 3732c10c12344755 +/agent-note-timed-user-questions-as-two-settlements/proposal/ownership: + en: 0543678ad9d26fc5 + zh: aa6ba207e661c567 +/agent-note-timed-user-questions-as-two-settlements/proposal/foreground-wait-and-claim-lifetime: + en: 447713bbdf1ab4d8 + zh: 2757678ae47822aa +/agent-note-timed-user-questions-as-two-settlements/proposal/durable-state-and-late-answers: + en: b8729d06ab7814ed + zh: acaa8f4174701248 +/agent-note-timed-user-questions-as-two-settlements/proposal/card-state-and-delivery-races: + en: 8c55b693e7a5bca4 + zh: aea6e966ce3667e3 +/agent-note-timed-user-questions-as-two-settlements/proposal/local-countdown-and-panel-actions: + en: 4c0c9ec59fc51217 + zh: 322870eeb49176c7 +/agent-note-timed-user-questions-as-two-settlements/proposal/reply-node-and-grouping: + en: 10323b0e0340a40b + zh: a17fc3a4d4d820a7 +/agent-note-timed-user-questions-as-two-settlements/alternatives-considered: + en: ce8ff9d5bc4b85b7 + zh: 49024fe3a5b194b2 +/agent-note-timed-user-questions-as-two-settlements/acceptance-criteria: + en: 5a993484c73befe9 + zh: 38cd3209c68178c3 +/agent-note-timed-user-questions-as-two-settlements/risks: + en: aae260b0cd95554f + zh: 3d7fbd6cbe9e2d37 diff --git a/.agents/notes/proposed/architecture/2026-09-19-timed-user-question-two-settlements.md b/.agents/notes/proposed/architecture/2026-09-19-timed-user-question-two-settlements.md new file mode 100644 index 0000000000..a4f4bf6e30 --- /dev/null +++ b/.agents/notes/proposed/architecture/2026-09-19-timed-user-question-two-settlements.md @@ -0,0 +1,113 @@ +# Agent Note: Timed user questions as two settlements + +Status: proposed + +English | [中文](2026-09-19-timed-user-question-two-settlements.zh.md) + +## Problem + +A question can block an agent even when useful work does not depend on the answer. Releasing the tool call after a wait must not discard the question: the user may answer after the agent has continued or after reopening the Session. A pending result is neither a skipped answer nor permission to proceed with work that requires approval. + +The foreground tool result and the eventual answer have different lifetimes. A `user-questions/request` waterfall settles once; keeping it alive after returning pending creates a second answer path that outlives its caller. Countdown, focus, and editing also have different owners from durable question state. + +## Proposal + +Keep foreground answers on the existing Remote Event waterfall. A timeout ends that request and returns pending; a later answer uses a business RPC that steers a durable user message. The claim stream controls the foreground wait only. It neither transports answers nor replaces the Remote Event. + +### Modes and scope + +- The default `mode: legacy` retains the blocking schema and `ask()` path. Explicit `mode: timed` adds `timeout`, using the configured default of 120 seconds when omitted. +- A positive integer timeout selects `askTimed()`; `-1` selects blocking `ask()`. A blocking call made with the timed schema still participates in timed-question projection and review; it is not identical to a legacy call. +- Plan review retains `ask()`, its `plan-review` intent, and `BAD_INTENT` validation. This decision does not move plan review to another package. +- Human interaction requires the exact live runtime root when an Agent is supplied. A stale instance fails with `CALLER_NOT_LIVE`; an owned child fails with `DELEGATED_CALLER`. Durable Session lineage does not prevent a resumed runtime root from asking. + +### Ownership + +| Owner | Responsibility | +|---|---| +| `tool-ask-user` | Model schema, timeout validation, service selection, and pending-result text. | +| `UserQuestionService` | Foreground waits and Client claims, unattended deadlines, late-answer validation and steering, and the durable question projection. | +| Gateway and Remote runtime | Existing request delivery, settlement, cancellation, and Remote stream transport; no question-specific timer or event-name branch. | +| `ui-user-questions` | One card per Session and call, answer-channel selection, local countdown and drafts, and the reply Definition and renderer. | +| `ui-chat` | Message-id-based presentation aggregation and ordinary process/Turn folding. | +| Question-specific tool row | Pending/answered presentation and panel actions, composed in `QuestionToolRow` without adding `rowAction` to generic `ToolRow`. | + +The [question service](../../../../packages/interaction/user-questions/README.md), [tool](../../../../packages/interaction/tool-ask-user/README.md), and [questions UI](../../../../packages/client/ui-user-questions/README.md) own their package contracts. + +### Foreground wait and claim lifetime + +`TimedQuestionWait` owns a private cancellation signal, the original Host deadline, and Client claims. The Host runs a timer only while no answer UI holds a claim. Delivery to a transport queue is not a claim. Losing the last claim restores the original deadline, with immediate expiry if it has passed. + +A timed request carries `wait: { callId, timed: true }`. Before attaching its answer channel, the Client opens `attachWait`, a business Remote stream that yields one Host-computed `remainingMs` frame and stays open for the claim's lifetime. Focus, edits, and heartbeats do not travel through this stream. + +The Client retains its claim through delivery of the waterfall outcome to the Host. Returning an answer locally is not delivery: releasing the claim then could let an overdue Host timer beat that answer. The Host closes the claim when the foreground request settles. Explicit delegation releases the claim before `next()`; plugin teardown delegates and cancels its stream. + +Client countdown expiry rejects the waterfall with `ASK_TIMED_OUT`. Unattended Host expiry aborts only the private wait signal with the same business error. `askTimed()` maps only that error to pending, maps parent cancellation to `ASK_ABORTED`, and propagates other failures. `NO_PROVIDER` waits on the same bounded wait lifetime, not a permanently unresolved promise. Foreground completion releases timers, claims, and the wait registry entry. + +### Durable state and late answers + +The `userQuestions` projection reconstructs question state from existing Session events. It recognises the timed schema by the `timeout` parameter recorded in `request/header`; legacy calls are not tracked. A valid `tool/call` opens a question. Its `tool/result` makes it continued for pending or `TOOL_OUTCOME_UNKNOWN`, settles it with a valid answer batch, or removes it for another result or failure. + +A continued question accepts `answer(agent, callId, answer)`. The method returns `false` for an unknown or non-continued call and throws `BAD_ANSWER` unless the batch names each question exactly once. Accepted answers use `agent.steer(createUserMessage(...))`, source `{ kind: 'user-question-reply', callId, outcome: 'answered' }`, and JSON text containing `answer_to_pending_question`, the call id, original questions, and answers. Remote Agent resolution from the Session id resumes a root when needed; the `answer()` body does not own that resume operation. + +The inbox message is the durable reply. `agent/inbox/spliced` settles the question when the message is queued; the later admitted `user/message` is idempotent for that settlement. Settled answer batches remain in the projection so the original tool row can show late answers even though its own result remains pending. Unusable recorded reply text settles with an empty batch. + +No new Session event type or wait-state log is needed. The message-source extension requires the repository's persistence-type acknowledgement. `dismissed` remains readable for historical records but has no producer: hiding a panel does not manufacture a reply. + +### Card state and delivery races + +`QuestionCards` shares one `PendingQuestion` between the live request and the continued projection, keyed by Session and `callId`. A blocking request without a call id has its own per-request card. An open card submits through its waterfall; without that channel it disables submission. A continued card uses the late-answer RPC. + +A waterfall submission has no delivery acknowledgement. The Gateway can discard an outcome that loses a settlement race. The card therefore retains its draft and stays busy until projection reconciliation. If the question becomes continued during submission, the controls re-arm with a resubmit hint; the user can submit the retained draft through RPC. This is not automatic retry or a guarantee that every local submission reaches the model. + +A tool-call-keyed card is removed when its call is absent from the active projection and no waterfall remains. Removal closes the card and clears its draft. Neither a local submission nor a transport cancel frame alone decides that the question is answered. An unkeyed blocking card ends with its waterfall; closing that blocking panel rejects with `ASK_CANCELLED`. + +### Local countdown and panel actions + +The Client computes `Date.now() + remainingMs`. Manual focus on a pristine answer surface pauses its countdown, and blur resumes the preserved remainder. Focus before the claim handshake remains effective when the deadline arrives; blur before the handshake does not create a timer. First edit or Take time freezes the countdown, with that disposition saved beside the browser-local draft. + +Autofocus applies only when the answer channel is ready, no countdown is active, and the card is not locked. Hiding a timed-call panel leaves its claim and countdown running; its tool row can reopen it. A settled call opens a read-only panel from recorded questions and answers, not another answer channel. + +### Reply node and grouping + +The questions UI identifies a late reply from `source.kind`, then parses its recorded JSON for question-and-answer presentation. Pasting identical JSON in an ordinary user message does not identify it as a reply. Unreadable recorded payloads retain their raw-text presentation. + +The ordinary message Definition and the question-reply Definition both match the appended message and retain separate Node Store projections with the same message id. Chat business grouping omits the `turn-trigger` presentation when a `question-reply` with that id is present. The duplicate trigger neither renders nor splits a group; the reply renders once. The same aggregation applies to unscoped historical input. + +The reply participates in ordinary process grouping and whole-Turn folding. It is not independently visible: reading it can require expanding both its Turn and process group. Turn disclosure stays before the group it controls, including a reply that opens the Turn. + +This decision adds no process-role field, independent-layout flag, user-message structure change, or target-local fallback dispatch. The independent-kind rules stay in Chat's existing grouping logic. A node-data-owned declaration of grouping and overlap semantics is deferred infrastructure, not part of the question feature. + +## Alternatives considered + +**Unconditional Host deadline or Gateway-owned question timers.** An unconditional deadline overrides local editing and Take time. Putting the exception into pending Remote Events or branching on the question event in Remote dispatch makes generic transport own business policy. Claims keep that policy in the question service. + +**Keep the waterfall alive after returning pending.** The request outlives the tool caller, and late waterfall answers compete with the RPC. Ending the foreground request gives each settlement one answer path. + +**Delegate every timed request immediately.** Dispatching to an intentionally empty answerer set wastes the existing blocking-answer path and requires special handling of `NO_PROVIDER`. Delegation is for an unavailable answerer, not the timed mode itself. + +**Persist a whole-value wait/focus/edit stream or use Host focus leases.** Durable question status is derivable from tool and inbox events. Focus and editing are local UI state; logging them or synchronising focus leases adds Host state without making multiple Clients share one editing session. + +**Reclassify JSON inside generic `MessageItem`, borrow the relay form, or use the default context row.** Parsing text to identify the business message confuses its source with its content; the relay form describes another agent's message, and a generic context row exposes JSON. A dedicated source, Definition, and renderer own the question presentation. + +**Independent reply layout through generic node metadata.** It broadens a question feature into a conversation-infrastructure change. Ordinary folding and Chat-owned aggregation are sufficient for this decision; independently declared node-data grouping semantics remain a separate design task. + +**A log-only close event or a manufactured dismissal message on panel close.** A log-only close hides the user's decision from the model and adds another durable mechanism. Manufacturing a reply treats hiding the panel as an answer. Panel close therefore leaves a timed question answerable. + +**A dedicated late-reply Session event beside the inbox message.** The inbox splice and admitted user message already record the reply. A third event duplicates the same fact and adds another persistence type. + +## Acceptance criteria + +- Service tests cover claimed and unclaimed waits, last-claim disconnect, cancellation, timeout error mapping, continued-only answers, and exact answer-id validation. +- Projection tests distinguish legacy and timed schemas and cover pending, answered, other failures, resume repair, and duplicate inbox/message settlement. +- Client tests cover claim retention through Host acceptance, focus before handshake, indefinite waits, draft retention, RPC resubmission, and panel hiding/reopening. +- Grouping and browser replay cover one rendered reply with both projections retained, ordinary collapsed placement, disclosure ordering, and the original tool row's read-only late-answer panel. +- Legacy question round trips, cancellation, plan-review intent, and Session remounts retain their existing behavior. Live multi-Client delivery races and real Host restart remain integration coverage gaps beyond isolated lifecycle and projection tests. + +## Risks + +- Take time affects only one Client. Another Client can answer or expire the shared waterfall; local focus does not establish a global hold. +- A terminal claim-stream failure can reject the foreground question rather than produce pending. No unattended-wait fallback is provided for that failure. +- Host and Client clocks need not align, but Client system-clock changes can move expiry and transport latency can delay the local countdown's start. +- The duplicate projections remain stored. Aggregation adds linear scans during structural grouping rebuilds; ordinary text-only streaming updates retain their incremental path. This is an algorithmic bound, not a measured latency claim. +- Unanswered continued questions can remain after reopening a Session. Panel close records nothing, and visibility follows normal folding rather than an always-visible reply guarantee. diff --git a/.agents/notes/proposed/architecture/2026-09-19-timed-user-question-two-settlements.zh.md b/.agents/notes/proposed/architecture/2026-09-19-timed-user-question-two-settlements.zh.md new file mode 100644 index 0000000000..7f2d42f73b --- /dev/null +++ b/.agents/notes/proposed/architecture/2026-09-19-timed-user-question-two-settlements.zh.md @@ -0,0 +1,113 @@ +# Agent Note: 计时用户提问的两次结算 + +Status: proposed + +[English](2026-09-19-timed-user-question-two-settlements.md) | 中文 + +## Problem + +即使还有不依赖回答的工作可做,问题仍可能阻塞 agent(智能体)。等待后放行工具调用不能丢弃问题:用户可能在 agent 继续执行后,或重新打开 Session 后才回答。pending 结果既不是跳过回答,也不是开展需要批准的工作的授权。 + +前台工具结果与最终回答的生命周期不同。`user-questions/request` waterfall(瀑布式事件)只结算一次;返回 pending 后仍保留它,会产生一条活过调用方的第二回答路径。倒计时、聚焦和编辑的归属也不同于持久问题状态。 + +## Proposal + +前台回答继续使用现有 Remote Event waterfall。超时结束该请求并返回 pending;迟到回答通过业务 RPC steer 一条持久用户消息。接手 stream 只控制前台等待,既不传递回答,也不替代 Remote Event。 + +### 模式与范围 + +- 默认 `mode: legacy` 保留阻塞式 schema 和 `ask()` 路径。显式 `mode: timed` 增加 `timeout`,省略时使用配置默认值 120 秒。 +- 正整数超时选择 `askTimed()`;`-1` 选择阻塞式 `ask()`。timed schema 发出的阻塞调用仍参与计时问题投影和答案查看,并不等同于 legacy 调用。 +- 计划评审保留 `ask()`、`plan-review` 意图及 `BAD_INTENT` 校验。本决策不把计划评审迁移到其他包。 +- 提供 Agent 时,人机交互要求它是运行时中确切的存活根实例。陈旧实例以 `CALLER_NOT_LIVE` 失败;被其他 agent 拥有的子实例以 `DELEGATED_CALLER` 失败。持久 Session 的血缘关系不妨碍恢复后的运行时根实例提问。 + +### 职责归属 + +| 归属方 | 职责 | +|---|---| +| `tool-ask-user` | 模型 schema、超时校验、服务选择和 pending 结果文本。 | +| `UserQuestionService` | 前台等待与 Client 接手、无人接手时的 deadline、迟到回答校验与 steering(中途引导),以及持久问题投影。 | +| Gateway 与 Remote 运行时 | 现有请求投递、结算、取消及 Remote stream 传输;不包含问题专属计时器或按事件名分支。 | +| `ui-user-questions` | 每个 Session 和调用的一张卡片、回答通道选择、本地倒计时与草稿,以及回复 Definition 和渲染器。 | +| `ui-chat` | 基于消息 id 的呈现聚合,以及普通过程/轮次折叠。 | +| 问题专用工具行 | pending/已回答呈现与面板操作,在 `QuestionToolRow` 中组合,不向通用 `ToolRow` 添加 `rowAction`。 | + +[问题服务](../../../../packages/interaction/user-questions/README.zh.md)、[工具](../../../../packages/interaction/tool-ask-user/README.zh.md)和[问题 UI](../../../../packages/client/ui-user-questions/README.zh.md)分别拥有各包的约定。 + +### 前台等待与接手生命周期 + +`TimedQuestionWait` 拥有专属取消 signal、原始 Host deadline 和 Client 接手记录。Host 只在没有回答 UI 接手时运行计时器。投递到传输队列不算接手。最后一个接手方离开后恢复原 deadline,已经过期则立即到期。 + +计时请求携带 `wait: { callId, timed: true }`。Client 在挂接回答通道前打开业务 Remote stream `attachWait`,接收一帧由 Host 计算的 `remainingMs`,并在接手期间保持 stream 打开。聚焦、编辑和心跳不经过该 stream。 + +Client 将接手保留到 waterfall 结果交付给 Host。本地返回回答不等于交付:此时释放接手会让已经到期的 Host 计时器抢在回答之前结算。Host 在前台请求结算时关闭接手。显式委托在 `next()` 前释放接手;插件拆卸会委托请求并取消自己的 stream。 + +Client 倒计时到期以 `ASK_TIMED_OUT` 拒绝 waterfall。无人接手时,Host 到期只以同一业务错误中止等待专属 signal。`askTimed()` 只把该错误映射为 pending,把父级取消映射为 `ASK_ABORTED`,其余失败继续传播。`NO_PROVIDER` 等待同一个有界等待生命周期,而不是永不结算的 Promise。前台完成时释放计时器、接手记录及等待注册项。 + +### 持久状态与迟到回答 + +`userQuestions` 投影从现有 Session 事件重建问题状态。它通过 `request/header` 记录的 `timeout` 参数识别 timed schema,不跟踪 legacy 调用。有效的 `tool/call` 打开问题。其 `tool/result` 在 pending 或 `TOOL_OUTCOME_UNKNOWN` 时将问题标为已继续,在有效回答批次时结算并保存答案,其他结果或失败则移除问题。 + +已继续的问题接受 `answer(agent, callId, answer)`。未知或非已继续调用返回 `false`;回答批次没有恰好包含每个问题一次时抛出 `BAD_ANSWER`。接受的回答通过 `agent.steer(createUserMessage(...))` 送入 agent,来源为 `{ kind: 'user-question-reply', callId, outcome: 'answered' }`,JSON 文本包含 `answer_to_pending_question`、调用 id、原问题及答案。Remote 根据 Session id 解析 Agent 时按需恢复根实例;恢复操作不属于 `answer()` 方法体。 + +inbox 消息就是持久回复。`agent/inbox/spliced` 在消息入队时结算问题;随后接纳的 `user/message` 对该结算是幂等的。已结算答案批次保留在投影中,让原工具行即使自身结果仍是 pending,也能显示迟到回答。无法使用的已记录回复文本以空答案批次结算。 + +无需新增 Session 事件类型或等待状态日志。消息来源扩展需要仓库的持久化类型变更确认。`dismissed` 为历史记录保留可读性,但没有生产者:隐藏面板不会伪造回复。 + +### 卡片状态与投递竞争 + +`QuestionCards` 按 Session 和 `callId`,让实时请求与已继续投影共享一个 `PendingQuestion`。没有调用 id 的阻塞请求拥有独立的逐请求卡片。开放卡片通过 waterfall 提交;缺少该通道时禁用提交。已继续卡片使用迟到回答 RPC。 + +waterfall 提交没有送达确认。Gateway 可能丢弃输掉结算竞争的结果,因此卡片保留草稿并保持忙碌,等待投影同步。若提交期间问题变为已继续,控件带重提提示重新可用,用户可以通过 RPC 提交保留的草稿。这不是自动重试,也不保证每次本地提交都能到达模型。 + +按工具调用标识的卡片在调用不属于活动投影且没有 waterfall 时移除。移除会关闭卡片并清理草稿。本地提交和传输取消帧都不能单独决定问题已经回答。无调用标识的阻塞卡片随 waterfall 结束;关闭这种阻塞面板以 `ASK_CANCELLED` 拒绝请求。 + +### 本地倒计时与面板操作 + +Client 计算 `Date.now() + remainingMs`。手动聚焦未编辑的回答区会暂停倒计时,失焦后从保留的剩余时间继续。接手握手前的聚焦在 deadline 到达时仍生效;握手前失焦不会制造计时器。首次编辑或「慢慢回答」冻结倒计时,该状态与浏览器本地草稿一起保存。 + +只有回答通道就绪、没有活动倒计时且卡片未锁定时才自动聚焦。隐藏计时调用的面板会保留接手和倒计时,工具行可以重新打开面板。已结算调用依据记录的问题与答案打开只读面板,不产生另一条回答通道。 + +### 回复节点与分组 + +问题 UI 通过 `source.kind` 识别迟到回复,再解析已记录的 JSON 来呈现问答。普通用户消息粘贴相同 JSON 不会被识别为回复。无法读取的已记录载荷保留原始文本呈现。 + +普通消息 Definition 和问答回复 Definition 都匹配追加的消息,在 Node Store 中保留消息 id 相同的独立投影。存在同 id 的 `question-reply` 时,Chat 业务分组省略 `turn-trigger` 呈现。重复触发节点既不渲染,也不切开分组,回复只显示一次。相同聚合也适用于无轮次归属的历史输入。 + +回复参与普通过程分组和整轮折叠,不保证独立可见:阅读时可能需要展开所属轮次与过程分组。轮次折叠控件始终在所控制的分组之前,包括由回复开启轮次的情况。 + +本决策不添加 process-role 字段、独立布局标记、用户消息结构变更或目标内 fallback 派发。独立 kind 规则保留在 Chat 现有分组逻辑中。由节点 data 声明分组与重叠语义的机制是留待拆分的基础设施,不属于问题功能。 + +## Alternatives considered + +**无条件 Host deadline 或 Gateway 拥有问题计时器。** 无条件 deadline 会覆盖本地编辑和「慢慢回答」。把例外放入 pending Remote Events,或在 Remote 派发中按问题事件分支,会让通用传输拥有业务策略。接手机制将策略留在问题服务中。 + +**返回 pending 后继续保留 waterfall。** 请求活过工具调用方,迟到的 waterfall 回答与 RPC 竞争。结束前台请求让每次结算各有一条回答路径。 + +**立即委托所有计时请求。** 向故意留空的回答方集合派发请求,浪费现有阻塞回答路径,还要求特殊处理 `NO_PROVIDER`。委托表示回答方不可用,不代表计时模式本身。 + +**持久化整值等待/聚焦/编辑流,或使用 Host 聚焦租约。** 持久问题状态可从工具与 inbox 事件推导。聚焦和编辑属于本地 UI 状态;记录它们或同步聚焦租约会增加 Host 状态,却不能让多个 Client 共享同一编辑会话。 + +**在通用 `MessageItem` 内重新分类 JSON、借用 relay form,或使用默认 context 行。** 解析文本来识别业务消息混淆了来源与内容;relay form 表示其他 agent 的消息,通用 context 行则会暴露 JSON。专用来源、Definition 和渲染器拥有问题呈现。 + +**通过通用节点元数据让回复独立布局。** 这会把问题功能扩大为对话基础设施变更。普通折叠与 Chat 内聚合足以满足本决策;由节点 data 独立声明分组语义仍是单独的设计任务。 + +**面板关闭时写仅入日志的关闭事件,或伪造放弃消息。** 仅入日志会让模型看不到用户决定,还增加另一套持久机制。伪造回复则把隐藏面板当成回答。因此关闭面板仍让计时问题保持可回答。 + +**在 inbox 消息之外增加专用迟到回复 Session 事件。** inbox 插入与接纳的用户消息已经记录回复。第三个事件重复同一事实,并增加另一种持久化类型。 + +## Acceptance criteria + +- 服务测试覆盖有人与无人接手、最后接手方断开、取消、超时错误映射、仅接受已继续问题的回答,以及答案 id 的精确校验。 +- 投影测试区分 legacy 与 timed schema,并覆盖 pending、已回答、其他失败、恢复修复及 inbox/消息重复结算。 +- Client 测试覆盖接手保留到 Host 接受结果、握手前聚焦、无限期等待、草稿保留、RPC 重提及面板隐藏/重开。 +- 分组与浏览器回放覆盖保留两个投影但只渲染一次回复、普通折叠位置、折叠控件顺序,以及原工具行的迟到答案只读面板。 +- legacy 问答往返、取消、计划评审意图及 Session 重新挂载保留既有行为。真实多 Client 投递竞争与真实 Host 重启仍是独立生命周期和投影测试之外的集成覆盖缺口。 + +## Risks + +- 「慢慢回答」只影响一个 Client。其他 Client 可以回答或让共享 waterfall 到期,本地聚焦不构成全局暂停。 +- 接手 stream 的终止性失败可能让前台问题失败,而不是产生 pending。不为该失败提供无人接手等待的 fallback。 +- Host 与 Client 时钟不必对齐,但 Client 系统时钟变化可能移动到期时间,传输延迟可能推迟本地倒计时的开始。 +- 重复投影仍保留在存储中。聚合在结构性分组重建时增加线性扫描;普通纯文本 stream 更新保留增量路径。这是算法复杂度界限,不是实测延迟结论。 +- 无人回答的已继续问题可以在重新打开 Session 后继续存在。关闭面板不写记录,可见性遵循普通折叠,而不是保证回复始终可见。 diff --git a/.agents/notes/proposed/bug-fix/2026-08-20-attachment-read-quarantine.i18n.yaml b/.agents/notes/proposed/bug-fix/2026-08-20-attachment-read-quarantine.i18n.yaml index b53d43cdc7..387e34fc96 100644 --- a/.agents/notes/proposed/bug-fix/2026-08-20-attachment-read-quarantine.i18n.yaml +++ b/.agents/notes/proposed/bug-fix/2026-08-20-attachment-read-quarantine.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-20-attachment-read-quarantine.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/bug-fix/2026-08-20-attachment-read-quarantine.md -2026-08-20-attachment-read-quarantine.md: 28e0f26cee2ec1e257fd4d43b4edc4300e2c6f23 -2026-08-20-attachment-read-quarantine.zh.md: 7f4ceae4e1fe9e656ed762de9828e14145976dc3 +/agent-note-quarantine-unreadable-historical-attachments: + en: 044cc37c349ad018 + zh: ba3336ebf923aeeb +/agent-note-quarantine-unreadable-historical-attachments/problem: + en: 8652fbd5afd34170 + zh: b6399f48311b0a7d +/agent-note-quarantine-unreadable-historical-attachments/proposal: + en: 2a7c272551d37bba + zh: cf58b062d716d301 +/agent-note-quarantine-unreadable-historical-attachments/alternatives-considered: + en: bac910fed94331cd + zh: 6e9ea388c407e3a7 +/agent-note-quarantine-unreadable-historical-attachments/acceptance-criteria: + en: 862b6f6077457010 + zh: 0b4fad8dc4cb0f46 +/agent-note-quarantine-unreadable-historical-attachments/risks: + en: 17a076b575e981e9 + zh: 15961b94d93cffac diff --git a/.agents/notes/proposed/feature/2026-06-30-pre-tool-input-rewrite.i18n.yaml b/.agents/notes/proposed/feature/2026-06-30-pre-tool-input-rewrite.i18n.yaml index fff61a1e56..8d5b683f9e 100644 --- a/.agents/notes/proposed/feature/2026-06-30-pre-tool-input-rewrite.i18n.yaml +++ b/.agents/notes/proposed/feature/2026-06-30-pre-tool-input-rewrite.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-30-pre-tool-input-rewrite.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-06-30-pre-tool-input-rewrite.md -2026-06-30-pre-tool-input-rewrite.md: a42b05ac7d2b4d5808807a5810b9e0c4354333a5 -2026-06-30-pre-tool-input-rewrite.zh.md: 8ef07ea7b6ca446b796c3977d5c87a1e7c49917a +/agent-note-pre-tool-input-rewrite-a-consistent-design: + en: 28be5a60d0f8f70d + zh: 2ade899f45347755 +/agent-note-pre-tool-input-rewrite-a-consistent-design/problem: + en: 1e84d54d317750ed + zh: 5436c2f44569ab52 +/agent-note-pre-tool-input-rewrite-a-consistent-design/the-problem-three-readers-of-pre-execution-arguments: + en: bdc0958b87dbd888 + zh: 0364cad8a5727306 +/agent-note-pre-tool-input-rewrite-a-consistent-design/proposal: + en: b08ad378beb60572 + zh: cb6797c7a0021e9d +/agent-note-pre-tool-input-rewrite-a-consistent-design/alternatives-considered: + en: 6119e2aff3b6be5a + zh: 76136ef5249c23eb +/agent-note-pre-tool-input-rewrite-a-consistent-design/alternatives-considered/why-not-mutate-the-execution-object: + en: 4ef997690f716c9a + zh: f73cdc2154aa5596 +/agent-note-pre-tool-input-rewrite-a-consistent-design/acceptance-criteria: + en: 4e2d12fbc5ad21b3 + zh: fe3a0dace0073283 +/agent-note-pre-tool-input-rewrite-a-consistent-design/risks: + en: ed597673c0102d5c + zh: 2c0fafaa9a093fd0 +/agent-note-pre-tool-input-rewrite-a-consistent-design/open-questions: + en: abf5adcd6d2effbd + zh: 5fdb48fefd55e2c0 diff --git a/.agents/notes/proposed/feature/2026-07-06-recallable-compaction.i18n.yaml b/.agents/notes/proposed/feature/2026-07-06-recallable-compaction.i18n.yaml index d324ff433c..0c37e50f9c 100644 --- a/.agents/notes/proposed/feature/2026-07-06-recallable-compaction.i18n.yaml +++ b/.agents/notes/proposed/feature/2026-07-06-recallable-compaction.i18n.yaml @@ -1,6 +1,46 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-06-recallable-compaction.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-07-06-recallable-compaction.md -2026-07-06-recallable-compaction.md: 07b89116b72a1c1aac2d79ee5aa41ff6e5d02a4c -2026-07-06-recallable-compaction.zh.md: 7347cb08c94665a6e5bb88655ec08d04921d08eb +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall: + en: 597e215825c64eb9 + zh: 1986c2ec32437386 +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/problem: + en: 98419c56fc9d4f6f + zh: 30271b2ad21dc596 +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/proposal: + en: d9f2a7ca462c8ee8 + zh: fa029cf95c64e6e6 +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/proposal/frozen-index-checkpoints: + en: 8325d916c340ce7e + zh: 8fa9e02b9736c5de +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/proposal/the-state-checkpoint: + en: 58fa7358424ce606 + zh: 37e3e0d908c9804c +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/proposal/pass-execution: + en: 0bbddf585af7054d + zh: 6a1d4cb86fe1609a +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/proposal/the-recall-tools: + en: 650caf9087704463 + zh: 8b1ba814af60e92e +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/proposal/cache-and-cost: + en: 5478157a8990200d + zh: 248d5a948cd980bf +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/proposal/packaging: + en: be69bf9a59318b82 + zh: 8ba115c958a760ad +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/proposal/relation-to-in-flight-work: + en: 649b2f91f7ec6bf0 + zh: e6868d911560ddbd +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/proposal/follow-ups: + en: ddef3c8ee8af0a71 + zh: 4d242940dbb34e50 +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/alternatives-considered: + en: 927ef2505cfd6596 + zh: 9c84668ec8e7cbdd +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/acceptance-criteria: + en: 05c76d5a5decad92 + zh: dd7f5d352e08942e +/agent-note-recallable-compaction-index-checkpoints-a-state-checkpoint-and-in-session-history-recall/risks: + en: f505f9cf132d577f + zh: e68dfd7273f71b21 diff --git a/.agents/notes/proposed/feature/2026-07-08-interactive-side-sessions.i18n.yaml b/.agents/notes/proposed/feature/2026-07-08-interactive-side-sessions.i18n.yaml index 80b3caab4e..a142187273 100644 --- a/.agents/notes/proposed/feature/2026-07-08-interactive-side-sessions.i18n.yaml +++ b/.agents/notes/proposed/feature/2026-07-08-interactive-side-sessions.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-08-interactive-side-sessions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-07-08-interactive-side-sessions.md -2026-07-08-interactive-side-sessions.md: 53b21497c92a77f075dd146151a6d953ecfc7a8b -2026-07-08-interactive-side-sessions.zh.md: 439d9c4d1a275255f5962028be2bd24d5f829bc6 +/agent-note-interactive-side-sessions-and-merge-back: + en: a200e33a65a4f530 + zh: 47d02d3736310892 +/agent-note-interactive-side-sessions-and-merge-back/problem: + en: 181d0078a702fdf2 + zh: ad1bff4f82fafdf3 +/agent-note-interactive-side-sessions-and-merge-back/proposal: + en: 5fa7d2000db6b265 + zh: a892b74299e0f984 +/agent-note-interactive-side-sessions-and-merge-back/alternatives-considered: + en: de50cab213a61b91 + zh: 85b912193092dfe2 +/agent-note-interactive-side-sessions-and-merge-back/acceptance-criteria: + en: 17d0937a1f28b1ac + zh: 9710ab0af3268da1 +/agent-note-interactive-side-sessions-and-merge-back/risks: + en: 86f12d62580d8d98 + zh: 8c39be21a1e3958f diff --git a/.agents/notes/proposed/feature/2026-08-04-task-surface.i18n.yaml b/.agents/notes/proposed/feature/2026-08-04-task-surface.i18n.yaml index d5cb5514e9..faa5a8965e 100644 --- a/.agents/notes/proposed/feature/2026-08-04-task-surface.i18n.yaml +++ b/.agents/notes/proposed/feature/2026-08-04-task-surface.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-04-task-surface.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-08-04-task-surface.md -2026-08-04-task-surface.md: 749ce9e40eea7aeb7a813dc6b2d4c139cf00ac44 -2026-08-04-task-surface.zh.md: 4a63e671ffe05c80dd8bc8ed3a49ab6ff5c44b7e +/agent-note-task-surface-for-structured-session-interaction: + en: fd53b5c7554236fc + zh: 6ff988716b5624cf +/agent-note-task-surface-for-structured-session-interaction/problem: + en: a4c96dae864a027e + zh: 432e6de734832966 +/agent-note-task-surface-for-structured-session-interaction/proposal: + en: 7f8d02649159a3a6 + zh: f63982864b6ad943 +/agent-note-task-surface-for-structured-session-interaction/declarative-model: + en: 9650ef8f65049b7d + zh: c0925b701a6b681c +/agent-note-task-surface-for-structured-session-interaction/tool-and-presentation-contract: + en: 836a14533a918d95 + zh: 0522d458992c5355 +/agent-note-task-surface-for-structured-session-interaction/submission-contract: + en: 480c434bc0825063 + zh: bbcace61f8d82188 +/agent-note-task-surface-for-structured-session-interaction/lifecycle-and-recovery: + en: 26beff219ebb0ce9 + zh: 664d4c76adf56175 +/agent-note-task-surface-for-structured-session-interaction/package-boundaries-and-dependencies: + en: 02aad87dd24d822f + zh: 9d49b5fa588e5e11 +/agent-note-task-surface-for-structured-session-interaction/delivery-stages: + en: 25d0951356cf412d + zh: 994619aaab7c2348 +/agent-note-task-surface-for-structured-session-interaction/alternatives-considered: + en: 121ceb5920763980 + zh: 7d7c1576faf4f331 +/agent-note-task-surface-for-structured-session-interaction/acceptance-criteria: + en: e5db6c885617dd5d + zh: 0a54a00d2a195bfb +/agent-note-task-surface-for-structured-session-interaction/risks: + en: 84a297fcdef9aaad + zh: a9ce38547d650e55 diff --git a/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.i18n.yaml b/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.i18n.yaml index a928ba5315..540d081a58 100644 --- a/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.i18n.yaml +++ b/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.i18n.yaml @@ -1,6 +1,43 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-desktop-mandatory-update-api.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.md -2026-09-08-desktop-mandatory-update-api.md: f88216065fe09221c7a14805e4d25fb97a259abc -2026-09-08-desktop-mandatory-update-api.zh.md: cb3e631040d221b87979b7fcd379c8881dba36bd +/agent-note-desktop-mandatory-update-api: + en: c0ea3f7826d8e253 + zh: 89feec8209a54f26 +/agent-note-desktop-mandatory-update-api/problem: + en: cc14e499c0f87586 + zh: 4cf849710b782d4b +/agent-note-desktop-mandatory-update-api/proposal: + en: 264c54ffe91f3193 + zh: 005512e1c498ccc1 +/agent-note-desktop-mandatory-update-api/proposal/endpoint-and-access: + en: 6c82820724930bb5 + zh: 5f6a0bbfd6fb6b16 +/agent-note-desktop-mandatory-update-api/proposal/request: + en: fb66b137a600f3a6 + zh: 83f5c74a1716d57c +/agent-note-desktop-mandatory-update-api/proposal/no-mandatory-update: + en: 4814b1bd7002d6ed + zh: 3f0d77beb046e2fc +/agent-note-desktop-mandatory-update-api/proposal/mandatory-update: + en: d3ae240665143695 + zh: 486115cd2fdf35ed +/agent-note-desktop-mandatory-update-api/proposal/errors-and-policy-matching: + en: ce7ab9adf3cbc840 + zh: d6f9734ab54b8f33 +/agent-note-desktop-mandatory-update-api/proposal/policy-publication-and-current-decisions: + en: d4d70e1541b2c2d1 + zh: a1b6e62a05b239be +/agent-note-desktop-mandatory-update-api/proposal/capacity-and-caching: + en: d176fc8d0eb355db + zh: b9f60de3e4f0a3fc +/agent-note-desktop-mandatory-update-api/alternatives-considered: + en: 1b69fd084869fb38 + zh: 90efcd2484f5a175 +/agent-note-desktop-mandatory-update-api/acceptance-criteria: + en: 6708b52f0c474ca7 + zh: 0ce9c9d3aa2e82c7 +/agent-note-desktop-mandatory-update-api/risks: + en: a5689674032b188e + zh: 06b83a878fba55b3 diff --git a/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.md b/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.md index f88216065f..429547c85b 100644 --- a/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.md +++ b/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.md @@ -28,21 +28,23 @@ The query itself must return the complete mandatory response; do not rely on int GET /api/v0/check_client_update?scenario=launch x-client-platform: desktop-win x-client-version: 0.1.3-rc.2 -x-client-bundle-id: com.deepseek.dsh -x-client-locale: zh-CN +x-client-bundle-id: +x-client-locale: zh_CN +x-client-timezone-offset: 28800 x-client-arch: x64 x-client-update-channel: nightly x-client-bundled-dsh-version: 0.1.3-rc.2 ``` -All listed headers are required for Desktop. Values describing installed software come from the application and its release metadata, not editable UI fields. +All listed headers are required on every Desktop request; a required header may still carry an empty value, as `x-client-bundle-id` does. The values describing installed software come from the application and its release metadata, not editable UI fields. | Header | Meaning and allowed values | |---|---| | `x-client-platform` | `desktop-win` or `desktop-mac` | -| `x-client-version` | Full Desktop SemVer, retaining prerelease identifiers; initially equal to bundled dsh | -| `x-client-bundle-id` | Application identity, for example `com.deepseek.dsh`; distinguishes Harness from Chat | -| `x-client-locale` | UI locale, for example `zh-CN`; selects localized content, not region | +| `x-client-version` | Shared client build version, inlined as `DSH_CLIENT_VERSION` at packaging; full SemVer retaining prerelease identifiers, initially equal to the bundled dsh version | +| `x-client-bundle-id` | Platform uses this field to identify the Chat application; the field does not apply to Harness, so Desktop sends it empty | +| `x-client-locale` | `zh_CN` or `en_US`, taken from the active UI language's primary subtag; selects localized content, not region | +| `x-client-timezone-offset` | Whole-second offset from UTC, positive east of Greenwich, sampled from the shell for every request | | `x-client-arch` | Windows `x64`; macOS `x64` or `arm64` | | `x-client-update-channel` | Initially always `nightly`, independent of version suffix | | `x-client-bundled-dsh-version` | Full bundled dsh version from release metadata | @@ -102,7 +104,7 @@ Do not add `mode`, `force_update`, `show_key`, `target_version`, button copy, or Missing required headers, invalid SemVer, and unsupported platform/architecture/channel combinations return explicit parameter errors, not no-force success or a mandatory policy. Prefer the existing business meanings of `biz_code = 1` for a missing version and `biz_code = 2` for an invalid version; final error allocation belongs to the backend. Service failures must not masquerade as success because success may remove an existing block. -Match application identity, platform, architecture, Desktop version, bundled dsh version, and channel using server-owned ranges and precedence. Use complete SemVer, not lexical sorting or truncated prerelease values. Initially the two versions are equal and channel is fixed Nightly; independent revisions and channel switching are deferred. Do not require a downgrade or stop returning `40005` merely because a client has queried or displayed it before. +Match platform, architecture, Desktop version, bundled dsh version, and channel using server-owned ranges and precedence. Use complete SemVer, not lexical sorting or truncated prerelease values. Initially the two versions are equal and channel is fixed Nightly; independent revisions and channel switching are deferred. Do not require a downgrade or stop returning `40005` merely because a client has queried or displayed it before. ### Policy publication and current decisions diff --git a/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.zh.md b/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.zh.md index cb3e631040..e2b992f746 100644 --- a/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.zh.md +++ b/.agents/notes/proposed/feature/2026-09-08-desktop-mandatory-update-api.zh.md @@ -28,21 +28,23 @@ GET /api/v0/check_client_update GET /api/v0/check_client_update?scenario=launch x-client-platform: desktop-win x-client-version: 0.1.3-rc.2 -x-client-bundle-id: com.deepseek.dsh -x-client-locale: zh-CN +x-client-bundle-id: +x-client-locale: zh_CN +x-client-timezone-offset: 28800 x-client-arch: x64 x-client-update-channel: nightly x-client-bundled-dsh-version: 0.1.3-rc.2 ``` -以上 header 对 Desktop 均为必填。描述已安装软件的值来自应用与发布元数据,不来自可编辑 UI 字段。 +以上 header 在每次 Desktop 请求中均为必填;必填 header 的取值可以为空,`x-client-bundle-id` 即如此。描述已安装软件的值来自应用与发布元数据,不来自可编辑 UI 字段。 | Header | 含义与取值 | |---|---| | `x-client-platform` | `desktop-win` 或 `desktop-mac` | -| `x-client-version` | 完整 Desktop SemVer,保留预发布标识;一期等于内置 dsh | -| `x-client-bundle-id` | 应用身份,例如 `com.deepseek.dsh`,区分 Harness 与 Chat | -| `x-client-locale` | UI 语言,例如 `zh-CN`;选择本地化内容,不代表区域 | +| `x-client-version` | 共享的客户端构建版本,在打包时内联为 `DSH_CLIENT_VERSION`;完整 SemVer,保留预发布标识,一期等于内置 dsh 版本 | +| `x-client-bundle-id` | Platform 用该字段标识 Chat 应用;该字段对 Harness 不适用,因此 Desktop 发送空值 | +| `x-client-locale` | `zh_CN` 或 `en_US`,取自当前 UI 语言的主语言子标签;选择本地化内容,不代表区域 | +| `x-client-timezone-offset` | 与 UTC 的整秒偏移,东为正,每次请求时从壳采样 | | `x-client-arch` | Windows 为 `x64`;macOS 为 `x64` 或 `arm64` | | `x-client-update-channel` | 一期固定 `nightly`,独立于版本后缀 | | `x-client-bundled-dsh-version` | 发布元数据中的完整内置 dsh 版本 | @@ -102,7 +104,7 @@ x-client-bundled-dsh-version: 0.1.3-rc.2 缺少必填 header、非法 SemVer 或不支持的平台/架构/通道组合返回明确参数错误,不能伪装为无强制成功或强制策略。优先沿用 `biz_code = 1` 表示缺少版本、`biz_code = 2` 表示版本非法的既有业务含义;最终错误码分配由后端负责。服务异常不得伪装成成功,因为成功可能解除已有阻断。 -按应用身份、平台、架构、Desktop 版本、内置 dsh 版本与通道匹配,由服务端维护版本范围和优先级。使用完整 SemVer,不按字符串排序或截断预发布部分。一期两个版本相等、通道固定 Nightly,独立修订与通道切换延后。不得要求降级,也不得仅因客户端曾查询或展示过就停止返回 `40005`。 +按平台、架构、Desktop 版本、内置 dsh 版本与通道匹配,由服务端维护版本范围和优先级。使用完整 SemVer,不按字符串排序或截断预发布部分。一期两个版本相等、通道固定 Nightly,独立修订与通道切换延后。不得要求降级,也不得仅因客户端曾查询或展示过就停止返回 `40005`。 ### 策略发布与当前判定 diff --git a/.agents/notes/proposed/feature/2026-09-08-desktop-update-extensions.i18n.yaml b/.agents/notes/proposed/feature/2026-09-08-desktop-update-extensions.i18n.yaml index 7119122de4..ce51330f2a 100644 --- a/.agents/notes/proposed/feature/2026-09-08-desktop-update-extensions.i18n.yaml +++ b/.agents/notes/proposed/feature/2026-09-08-desktop-update-extensions.i18n.yaml @@ -1,6 +1,43 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-desktop-update-extensions.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-09-08-desktop-update-extensions.md -2026-09-08-desktop-update-extensions.md: 6c8a2ebe4a38809f6c3a7fb4741b3520111402c6 -2026-09-08-desktop-update-extensions.zh.md: 06096c8b28136ab2e22325857021926e06b3b17e +/agent-note-deferred-desktop-update-extensions: + en: 01b20c9e8c51f739 + zh: 2b2ef6d0d38d3d19 +/agent-note-deferred-desktop-update-extensions/problem: + en: da98b267b01e4829 + zh: 0ae373bd57094e74 +/agent-note-deferred-desktop-update-extensions/proposal: + en: eb4ae06bfef53a90 + zh: f40702aa6a557792 +/agent-note-deferred-desktop-update-extensions/proposal/independent-revisions: + en: 403bd786a8411349 + zh: c44584e8a7e5b74a +/agent-note-deferred-desktop-update-extensions/proposal/stable-subscription-and-channel-switching: + en: f39b1ed0d941d372 + zh: 05b9a006c9ec0d3c +/agent-note-deferred-desktop-update-extensions/proposal/automatic-installation-setting: + en: 758d49f0a7dc6707 + zh: ddb0bfe616eb93bc +/agent-note-deferred-desktop-update-extensions/proposal/next-launch-installation: + en: 606f1eea66d829f7 + zh: d72108d762a58957 +/agent-note-deferred-desktop-update-extensions/proposal/updater-dependency-qualification: + en: c1a508d15bbc37e8 + zh: 63e7648130377fbb +/agent-note-deferred-desktop-update-extensions/proposal/multiple-pending-versions: + en: e6cf3f78703ebd25 + zh: 63e473e8949df81a +/agent-note-deferred-desktop-update-extensions/proposal/cache-invalidation-and-revocation: + en: 22c2d3aa60611f71 + zh: 27c6c0128effac56 +/agent-note-deferred-desktop-update-extensions/alternatives-considered: + en: 699aca5ea4c3e894 + zh: 2306f90a6819d711 +/agent-note-deferred-desktop-update-extensions/acceptance-criteria: + en: cc1a2d1972f483ce + zh: 8f9d654387e76df0 +/agent-note-deferred-desktop-update-extensions/risks: + en: 1422bf65f3ea6e3b + zh: bc6d7c1a39ffbbf5 diff --git a/.agents/notes/proposed/feature/2026-09-08-desktop-update-policy-and-installation.i18n.yaml b/.agents/notes/proposed/feature/2026-09-08-desktop-update-policy-and-installation.i18n.yaml index 838cbee511..11052cfad3 100644 --- a/.agents/notes/proposed/feature/2026-09-08-desktop-update-policy-and-installation.i18n.yaml +++ b/.agents/notes/proposed/feature/2026-09-08-desktop-update-policy-and-installation.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-08-desktop-update-policy-and-installation.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-09-08-desktop-update-policy-and-installation.md -2026-09-08-desktop-update-policy-and-installation.md: fa88a7dd798e050d658969ad586bd86e0ac323df -2026-09-08-desktop-update-policy-and-installation.zh.md: d9dc74f66a72dceeafd119fac9e491b3c2a29aa1 +/agent-note-desktop-update-policy-and-installation: + en: 250865822f42a08a + zh: f7fab178a4835c04 +/agent-note-desktop-update-policy-and-installation/problem: + en: 96e7c7a206e06f15 + zh: 189133653543a98c +/agent-note-desktop-update-policy-and-installation/proposal: + en: 73b06c4b868250d5 + zh: 947419d367f6c7e9 +/agent-note-desktop-update-policy-and-installation/proposal/release-and-backend-qualification: + en: 03612a65e4a65939 + zh: 4d45467930e9f364 +/agent-note-desktop-update-policy-and-installation/proposal/open-product-choices: + en: 1ced7c2ababf429f + zh: 9879fba6f288236c +/agent-note-desktop-update-policy-and-installation/proposal/cdn-and-capacity-qualification: + en: a857e8c566e0cbd2 + zh: 6b4fd99b7482c2b1 +/agent-note-desktop-update-policy-and-installation/alternatives-considered: + en: ff419f29cfc6702b + zh: dc79b9d3d9bef98f +/agent-note-desktop-update-policy-and-installation/acceptance-criteria: + en: db7d20578a44d2ca + zh: 81b71132c9c08725 +/agent-note-desktop-update-policy-and-installation/risks: + en: c518abbbfd98b9ca + zh: 0d325d2b825eee87 diff --git a/.agents/notes/proposed/process/2026-06-11-api-extractor-reports.i18n.yaml b/.agents/notes/proposed/process/2026-06-11-api-extractor-reports.i18n.yaml index 834ddaf3ac..e1f8080e43 100644 --- a/.agents/notes/proposed/process/2026-06-11-api-extractor-reports.i18n.yaml +++ b/.agents/notes/proposed/process/2026-06-11-api-extractor-reports.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-11-api-extractor-reports.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/process/2026-06-11-api-extractor-reports.md -2026-06-11-api-extractor-reports.md: 2aee524596a5b798591fecded539a8d2236a3d96 -2026-06-11-api-extractor-reports.zh.md: e62b6168efac5c8296b55ff8ee0c7861d1849d31 +/agent-note-api-extractor-reports: + en: 5bf55ca547e54ed9 + zh: 62bc2de82f342803 +/agent-note-api-extractor-reports/problem: + en: 1155ed0bd1964b95 + zh: 4d00955e7602b8b4 +/agent-note-api-extractor-reports/proposal: + en: bdf121c8a35a7cf6 + zh: 106d7be6dba363cf +/agent-note-api-extractor-reports/alternatives-considered: + en: 36a7bef28b50f0a1 + zh: 1051720fd8c30f7a +/agent-note-api-extractor-reports/acceptance-criteria: + en: b3dd74eab1781311 + zh: 63fd46fd11656832 +/agent-note-api-extractor-reports/risks: + en: 21838e31d29b87fb + zh: c72c81ef53b090e0 +/agent-note-api-extractor-reports/why-deferred: + en: e2a8a7c13f4db704 + zh: aeae101a9a77d677 diff --git a/.agents/notes/proposed/process/2026-06-11-supply-chain-and-vendor-drift.i18n.yaml b/.agents/notes/proposed/process/2026-06-11-supply-chain-and-vendor-drift.i18n.yaml index adce053a55..d5fe12dd4d 100644 --- a/.agents/notes/proposed/process/2026-06-11-supply-chain-and-vendor-drift.i18n.yaml +++ b/.agents/notes/proposed/process/2026-06-11-supply-chain-and-vendor-drift.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-11-supply-chain-and-vendor-drift.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/process/2026-06-11-supply-chain-and-vendor-drift.md -2026-06-11-supply-chain-and-vendor-drift.md: aecab81292e8d6eb59fe13a5530ba78de9b307a5 -2026-06-11-supply-chain-and-vendor-drift.zh.md: ba55b3b1815c8164650dd4aa5022dd4f98efd6a4 +/agent-note-supply-chain-checks-and-vendor-drift-verification: + en: 14763706c0292472 + zh: bc846b9df1cd559c +/agent-note-supply-chain-checks-and-vendor-drift-verification/problem: + en: 2668c33c520ba25e + zh: 5dbb2e8a25cc50cd +/agent-note-supply-chain-checks-and-vendor-drift-verification/proposal: + en: c9f9e2ebf0e66922 + zh: 2c1ed4bc35bc2d90 +/agent-note-supply-chain-checks-and-vendor-drift-verification/plan: + en: c52921928996b2f0 + zh: 6c0ae36667b1bf44 +/agent-note-supply-chain-checks-and-vendor-drift-verification/alternatives-considered: + en: 39f18421ca3a9c3d + zh: 5923ddb6c420e56f +/agent-note-supply-chain-checks-and-vendor-drift-verification/acceptance-criteria: + en: e770eb9ebced47d1 + zh: df915bb02264be7a +/agent-note-supply-chain-checks-and-vendor-drift-verification/risks: + en: 515f9c9dd5ef7c20 + zh: a8358875334b2c64 diff --git a/.agents/notes/proposed/process/2026-06-20-discover-package-inventory.i18n.yaml b/.agents/notes/proposed/process/2026-06-20-discover-package-inventory.i18n.yaml index f673045a49..1a93b05ba6 100644 --- a/.agents/notes/proposed/process/2026-06-20-discover-package-inventory.i18n.yaml +++ b/.agents/notes/proposed/process/2026-06-20-discover-package-inventory.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-20-discover-package-inventory.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/process/2026-06-20-discover-package-inventory.md -2026-06-20-discover-package-inventory.md: 81674dd4d1e6f1ca15491754fbb35f5262be9581 -2026-06-20-discover-package-inventory.zh.md: 2a782d07ddbefc1d80eef2825220de179428377b +/agent-note-discover-package-inventories-instead-of-maintaining-static-lists: + en: 3e6f3d4389b83ace + zh: dc84644418444fe6 +/agent-note-discover-package-inventories-instead-of-maintaining-static-lists/problem: + en: 3331c27d7f05a293 + zh: d3f87bd458a65f1d +/agent-note-discover-package-inventories-instead-of-maintaining-static-lists/proposal: + en: ce955aa355c15117 + zh: 4d6f464bd5336981 +/agent-note-discover-package-inventories-instead-of-maintaining-static-lists/acceptance-criteria: + en: 99944a56114596df + zh: ec13f47fb2deef94 +/agent-note-discover-package-inventories-instead-of-maintaining-static-lists/risks: + en: e2876e76daf10637 + zh: 01126163c6f15960 diff --git a/.agents/notes/proposed/process/2026-07-13-human-review-skill-maintenance.i18n.yaml b/.agents/notes/proposed/process/2026-07-13-human-review-skill-maintenance.i18n.yaml index 25abf497a8..766efdc8d0 100644 --- a/.agents/notes/proposed/process/2026-07-13-human-review-skill-maintenance.i18n.yaml +++ b/.agents/notes/proposed/process/2026-07-13-human-review-skill-maintenance.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-13-human-review-skill-maintenance.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/process/2026-07-13-human-review-skill-maintenance.md -2026-07-13-human-review-skill-maintenance.md: b741c8b595fcd36613cb246af483863d1e056697 -2026-07-13-human-review-skill-maintenance.zh.md: b43e05c79b60056f3f38eabb00dd5af9a3611c6e +/agent-note-periodic-human-review-maintenance-for-dsh-code-review: + en: 7c3dc085ce13a5e9 + zh: e24659d5088e7e46 +/agent-note-periodic-human-review-maintenance-for-dsh-code-review/problem: + en: 7525ad5821b12c44 + zh: 7daef3ed8aa176e9 +/agent-note-periodic-human-review-maintenance-for-dsh-code-review/proposal: + en: ea478f77c2f26d85 + zh: dc6208e15615d5af +/agent-note-periodic-human-review-maintenance-for-dsh-code-review/proposal/acquisition-contract: + en: a95dea3f6b37af6f + zh: 29cfc8f03a8b487b +/agent-note-periodic-human-review-maintenance-for-dsh-code-review/proposal/adoption-evidence: + en: f61dfd9e11b1e5a5 + zh: c87f245097c39fc7 +/agent-note-periodic-human-review-maintenance-for-dsh-code-review/proposal/dual-reviewer-classification-and-drafting: + en: fe1f6987e5a7d4f7 + zh: 74d990935316e69b +/agent-note-periodic-human-review-maintenance-for-dsh-code-review/proposal/reviewer-adapter-protocol: + en: baa824361e643e80 + zh: 15d5efb0a1ca2c11 +/agent-note-periodic-human-review-maintenance-for-dsh-code-review/proposal/promotion-contract: + en: dd6810cf423430bc + zh: 0c81e470f64af150 +/agent-note-periodic-human-review-maintenance-for-dsh-code-review/proposal/where-the-mechanism-lives: + en: 2f9ffbf8619445a9 + zh: 1dd0144e9a00d8fe +/agent-note-periodic-human-review-maintenance-for-dsh-code-review/alternatives-considered: + en: 1673a2138ddd34c2 + zh: 81c91a50ea0703d6 +/agent-note-periodic-human-review-maintenance-for-dsh-code-review/acceptance-criteria: + en: a9354faa1dc793a3 + zh: f0b8da665facaecc +/agent-note-periodic-human-review-maintenance-for-dsh-code-review/risks: + en: b26ffb43c1c35b3a + zh: c2c8b81a8317cd55 diff --git a/.agents/notes/proposed/process/2026-07-26-remove-packed-session-fixture-migrator.i18n.yaml b/.agents/notes/proposed/process/2026-07-26-remove-packed-session-fixture-migrator.i18n.yaml index 282663d336..de3a6b948b 100644 --- a/.agents/notes/proposed/process/2026-07-26-remove-packed-session-fixture-migrator.i18n.yaml +++ b/.agents/notes/proposed/process/2026-07-26-remove-packed-session-fixture-migrator.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-26-remove-packed-session-fixture-migrator.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/process/2026-07-26-remove-packed-session-fixture-migrator.md -2026-07-26-remove-packed-session-fixture-migrator.md: 0a29ef98828ac07d291392d637b0508937c9a9a6 -2026-07-26-remove-packed-session-fixture-migrator.zh.md: aa9aece710587cef6c84ad9cf078821a2506deb1 +/agent-note-remove-the-packed-session-fixture-branch-migrator: + en: 0a308bd6231fb8ad + zh: c72bd0f6f327fadd +/agent-note-remove-the-packed-session-fixture-branch-migrator/problem: + en: 26671139b244f2ad + zh: fb2bbcc283b6f108 +/agent-note-remove-the-packed-session-fixture-branch-migrator/proposal: + en: 6e9555d667a64807 + zh: 7d7d59ae0f8859c9 +/agent-note-remove-the-packed-session-fixture-branch-migrator/alternatives-considered: + en: 7066942e7b78faba + zh: 6174e50357d868c5 +/agent-note-remove-the-packed-session-fixture-branch-migrator/acceptance-criteria: + en: 2ea0da4f97ecec97 + zh: 308aed4607df56af +/agent-note-remove-the-packed-session-fixture-branch-migrator/risks: + en: ee7d26eb7287179b + zh: 96f2cf320cc1adc8 diff --git a/.agents/notes/proposed/process/2026-08-20-audience-first-documentation-quality.i18n.yaml b/.agents/notes/proposed/process/2026-08-20-audience-first-documentation-quality.i18n.yaml index 5f57698abb..e1371258e1 100644 --- a/.agents/notes/proposed/process/2026-08-20-audience-first-documentation-quality.i18n.yaml +++ b/.agents/notes/proposed/process/2026-08-20-audience-first-documentation-quality.i18n.yaml @@ -1,6 +1,52 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-20-audience-first-documentation-quality.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/process/2026-08-20-audience-first-documentation-quality.md -2026-08-20-audience-first-documentation-quality.md: 9e0c4a61408449100b79148a571cd740e4044040 -2026-08-20-audience-first-documentation-quality.zh.md: 0b6f1da54380f1d2d44afbe948131233def513cd +/agent-note-audience-first-documentation-quality-criteria: + en: 5fd84aa1a097f80f + zh: 073d973331b00ca4 +/agent-note-audience-first-documentation-quality-criteria/problem: + en: 86ee1c395115b7d2 + zh: 7fea995569331599 +/agent-note-audience-first-documentation-quality-criteria/problem/semantic-correctness-can-pass-without-a-current-owner: + en: d752be65975937fa + zh: f0c9a94ccff8e059 +/agent-note-audience-first-documentation-quality-criteria/problem/reader-success-is-implicit-rather-than-testable: + en: 9d7c94e84fdeea18 + zh: e315ae5d470d576b +/agent-note-audience-first-documentation-quality-criteria/problem/generated-accuracy-and-retrieval-quality-are-conflated: + en: ebca610981ca8519 + zh: df367b6ad77db2bd +/agent-note-audience-first-documentation-quality-criteria/problem/the-standard-has-no-room-for-its-next-rule: + en: 08014cdc897e21c2 + zh: b3fdc5236ee7144f +/agent-note-audience-first-documentation-quality-criteria/problem/baseline: + en: 43bd2079e17f92a0 + zh: 7f0553e1417eb759 +/agent-note-audience-first-documentation-quality-criteria/proposal: + en: 1f28c04d5002af94 + zh: 4d4dfea99fc6aee2 +/agent-note-audience-first-documentation-quality-criteria/proposal/prototype-rules: + en: 6ee5714bc0b33cda + zh: 587bd85f6f712868 +/agent-note-audience-first-documentation-quality-criteria/proposal/criteria-by-document-job: + en: 9abbe4f2d5038284 + zh: 45d30352d9cce4b5 +/agent-note-audience-first-documentation-quality-criteria/proposal/generated-reference-entry-and-detail-layers: + en: 2641ca1307c3308f + zh: 15fd0415d40a9190 +/agent-note-audience-first-documentation-quality-criteria/proposal/enforcement-slices: + en: c2f6617cf8b3bab4 + zh: b9ad3dae2fc50ddf +/agent-note-audience-first-documentation-quality-criteria/proposal/non-goals: + en: e8633d73b0273bfd + zh: 516e6d805158d303 +/agent-note-audience-first-documentation-quality-criteria/alternatives-considered: + en: 5f09627b84bf112b + zh: b0f1845df90e5f1a +/agent-note-audience-first-documentation-quality-criteria/acceptance-criteria: + en: 696ff7205b3362d0 + zh: a62a50cf3ceadac6 +/agent-note-audience-first-documentation-quality-criteria/risks: + en: b920900d3ff05073 + zh: 05b2a0271b825260 diff --git a/.agents/notes/proposed/process/2026-08-27-port-tool-owned-render.i18n.yaml b/.agents/notes/proposed/process/2026-08-27-port-tool-owned-render.i18n.yaml index 542aa17c63..38917672a7 100644 --- a/.agents/notes/proposed/process/2026-08-27-port-tool-owned-render.i18n.yaml +++ b/.agents/notes/proposed/process/2026-08-27-port-tool-owned-render.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-27-port-tool-owned-render.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/process/2026-08-27-port-tool-owned-render.md -2026-08-27-port-tool-owned-render.md: 4ab27142fdc2d13d7d152c21c2f246e340fb4711 -2026-08-27-port-tool-owned-render.zh.md: fe8a018235db59b6f3bf80eae45d3a25181f37ec +/agent-note-port-tool-owned-render-into-current-dsh-apis: + en: a13180eec1968793 + zh: e47a83ddb329de88 +/agent-note-port-tool-owned-render-into-current-dsh-apis/problem: + en: 3a3ceea534efabd1 + zh: f13f8531d1819b8a +/agent-note-port-tool-owned-render-into-current-dsh-apis/proposal: + en: a51c0e6f23d8d4d4 + zh: 1eecd0ed06685c40 +/agent-note-port-tool-owned-render-into-current-dsh-apis/alternatives-considered: + en: a2364e3fca0a06e5 + zh: a76370082e218154 +/agent-note-port-tool-owned-render-into-current-dsh-apis/acceptance-criteria: + en: 5e2815d18df000f9 + zh: 97845472646b1881 +/agent-note-port-tool-owned-render-into-current-dsh-apis/risks: + en: 4fa51a62af0a3fc5 + zh: d6f555a8a5d9120c diff --git a/.agents/notes/proposed/simplification/2026-09-17-defer-office-background-scheduling.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-17-defer-office-background-scheduling.i18n.yaml index 35fe5b54d9..0374d8ce64 100644 --- a/.agents/notes/proposed/simplification/2026-09-17-defer-office-background-scheduling.i18n.yaml +++ b/.agents/notes/proposed/simplification/2026-09-17-defer-office-background-scheduling.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-17-defer-office-background-scheduling.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-09-17-defer-office-background-scheduling.md -2026-09-17-defer-office-background-scheduling.md: 82311022a015671b9fb4cf3a0f3eba2714f325cd -2026-09-17-defer-office-background-scheduling.zh.md: ada0146f204fa40e71d48251c231c1b68c5fa5a1 +/agent-note-defer-office-background-scheduling-until-a-consumer-needs-it: + en: 9966b1c4fdb2585b + zh: 4eb24c283facf38d +/agent-note-defer-office-background-scheduling-until-a-consumer-needs-it/problem: + en: bb725ab25ff39f86 + zh: d198514119b31a61 +/agent-note-defer-office-background-scheduling-until-a-consumer-needs-it/proposal: + en: e33db390dbbcc86c + zh: 890df8891260103a +/agent-note-defer-office-background-scheduling-until-a-consumer-needs-it/alternatives-considered: + en: 597346036314c907 + zh: 91661d961623c7cd +/agent-note-defer-office-background-scheduling-until-a-consumer-needs-it/acceptance-criteria: + en: b475d4e83972fa02 + zh: 43de8f23a9346708 +/agent-note-defer-office-background-scheduling-until-a-consumer-needs-it/risks: + en: 4c2324c00381cbc7 + zh: dfe6d1068ac7560c diff --git a/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.i18n.yaml index c959db81ed..3b2501788a 100644 --- a/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.i18n.yaml +++ b/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-config-only-hmr.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-09-19-config-only-hmr.md -2026-09-19-config-only-hmr.md: a5f447a8a426e9f2831a1292cae1132acab99023 -2026-09-19-config-only-hmr.zh.md: 24651aa310994b3fec4d925a84fe5d88ae6a5851 +/agent-note-limit-dsh-hmr-to-live-profile-configuration: + en: c46e2d07a9e6143f + zh: f75300d70300c324 +/agent-note-limit-dsh-hmr-to-live-profile-configuration/problem: + en: e81dd5edb54b05ad + zh: 601b28ef74134ac1 +/agent-note-limit-dsh-hmr-to-live-profile-configuration/proposal: + en: 15a88d4c7db728e2 + zh: 6fb1a28c03930a5e +/agent-note-limit-dsh-hmr-to-live-profile-configuration/alternatives-considered: + en: 9ca293c37f4df4af + zh: c8e1a8815e1c9d3f +/agent-note-limit-dsh-hmr-to-live-profile-configuration/acceptance-criteria: + en: ea1dbf4681f60fcf + zh: fa7b9f7888bfc24f +/agent-note-limit-dsh-hmr-to-live-profile-configuration/risks: + en: de00ca4e66cff7d0 + zh: fb82e77bd554c1f6 diff --git a/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.i18n.yaml index e582498d41..30d37e8252 100644 --- a/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.i18n.yaml +++ b/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-omit-fs-payload-invariant.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.md -2026-09-19-omit-fs-payload-invariant.md: e91fa1784aa99869e3d457f7fc25a330fbc43088 -2026-09-19-omit-fs-payload-invariant.zh.md: ba81baed5f7d7051ef22218d9d59180ac87c8a21 +/agent-note-omit-the-filesystem-payload-only-invariant-companion: + en: 6385aa079529c4f4 + zh: 602b99cea351125c +/agent-note-omit-the-filesystem-payload-only-invariant-companion/problem: + en: 4568d53b3ef69254 + zh: 66c9aea2ae3645e7 +/agent-note-omit-the-filesystem-payload-only-invariant-companion/proposal: + en: 2bfceaa480b6645d + zh: 3ad1060bf91ded74 +/agent-note-omit-the-filesystem-payload-only-invariant-companion/alternatives-considered: + en: d12fd1577a308af3 + zh: 56271794646f5a87 +/agent-note-omit-the-filesystem-payload-only-invariant-companion/acceptance-criteria: + en: 253009b93ce34c5b + zh: 2268e0303bd025d6 +/agent-note-omit-the-filesystem-payload-only-invariant-companion/risks: + en: 70c52f193d72d02d + zh: f30844e865ac4c27 diff --git a/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.i18n.yaml index 46510688ef..47b5014e29 100644 --- a/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.i18n.yaml +++ b/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-provider-only-instruction-reads.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.md -2026-09-19-provider-only-instruction-reads.md: 26d004c136cff8deb155007cf8d7743bc8bba95a -2026-09-19-provider-only-instruction-reads.zh.md: 82f3451f96578f1ee596bf9291a1a3c935d5f698 +/agent-note-read-instruction-files-only-through-a-filesystem-provider: + en: 522a0143262cd96a + zh: 667e48df6cd37c61 +/agent-note-read-instruction-files-only-through-a-filesystem-provider/problem: + en: 5426489eed9b447e + zh: 97132891bfff4b41 +/agent-note-read-instruction-files-only-through-a-filesystem-provider/proposal: + en: 1f6d8ce78f5ab682 + zh: c71c97c0268ac165 +/agent-note-read-instruction-files-only-through-a-filesystem-provider/alternatives-considered: + en: c942573554ef1d63 + zh: 7af89ae9434f7521 +/agent-note-read-instruction-files-only-through-a-filesystem-provider/acceptance-criteria: + en: ea8f9800cfbea9e6 + zh: a3c07d3a09d0fff4 +/agent-note-read-instruction-files-only-through-a-filesystem-provider/risks: + en: f8b63ab7c6a924ab + zh: 753472b8491105f0 diff --git a/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.i18n.yaml index 6360d57daa..51801755e1 100644 --- a/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.i18n.yaml +++ b/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-prune-stream-visibility-helpers.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.md -2026-09-19-prune-stream-visibility-helpers.md: e44716fe15eb0ff09020ff4417b1dd9f4e9c29f4 -2026-09-19-prune-stream-visibility-helpers.zh.md: 60d010f260a6cadc99a15bde164bb0717dd7502a +/agent-note-prune-unused-stream-visibility-helpers: + en: 5d82ce82cac8a687 + zh: 4cfc68fceb215e35 +/agent-note-prune-unused-stream-visibility-helpers/problem: + en: da5bf344b0d704c1 + zh: 6826b064d8b66373 +/agent-note-prune-unused-stream-visibility-helpers/proposal: + en: b6cec09bd23a2f5a + zh: ac348bbe47ea7cc9 +/agent-note-prune-unused-stream-visibility-helpers/alternatives-considered: + en: 1a190cf86a9f7ec9 + zh: 2a30aa235c69bdc7 +/agent-note-prune-unused-stream-visibility-helpers/acceptance-criteria: + en: ee2de1dbabc60983 + zh: d01c9f1e399266af +/agent-note-prune-unused-stream-visibility-helpers/risks: + en: 466ed8d1fb426011 + zh: 1c0765622c9fdf32 diff --git a/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.i18n.yaml index 3920961bcf..df72997d92 100644 --- a/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.i18n.yaml +++ b/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-python-sdk-directional-client.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.md -2026-09-19-python-sdk-directional-client.md: 287126d65cc9e81e240c2b18081b2935c107760a -2026-09-19-python-sdk-directional-client.zh.md: caf9b7c73a00b8865b6d189fe512f96afb20dad9 +/agent-note-remove-the-python-sdk-s-unused-reverse-rpc-direction: + en: 29c6b53f7f81bfd8 + zh: 94139164373cda91 +/agent-note-remove-the-python-sdk-s-unused-reverse-rpc-direction/problem: + en: e8779fc70adce0e4 + zh: 288565d427fe65ae +/agent-note-remove-the-python-sdk-s-unused-reverse-rpc-direction/proposal: + en: 508671a9a29a8f2a + zh: 750587c118eb7450 +/agent-note-remove-the-python-sdk-s-unused-reverse-rpc-direction/alternatives-considered: + en: 2fb93911daacf365 + zh: 4c2e2599283cab94 +/agent-note-remove-the-python-sdk-s-unused-reverse-rpc-direction/acceptance-criteria: + en: bbfd9485fbe4e523 + zh: 283486f66c96b447 +/agent-note-remove-the-python-sdk-s-unused-reverse-rpc-direction/risks: + en: d0a75f4fa88d4bf7 + zh: 9a7635d8040d8068 diff --git a/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.i18n.yaml index d11c6bed98..9b077fc6d1 100644 --- a/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.i18n.yaml +++ b/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-retire-app-bin-boot-helpers.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.md -2026-09-19-retire-app-bin-boot-helpers.md: c67013bfae8569d0f750b3c8be5e56c57a2a66aa -2026-09-19-retire-app-bin-boot-helpers.zh.md: 5ef68ff3d8666e8b74d36c50eacbcf5048a4438a +/agent-note-retire-app-boot-helpers-used-only-by-fixtures: + en: db7c1d105d67279e + zh: 299512664ce8a27f +/agent-note-retire-app-boot-helpers-used-only-by-fixtures/problem: + en: f617e973b4e5c136 + zh: 90a32c3023bd4bbb +/agent-note-retire-app-boot-helpers-used-only-by-fixtures/proposal: + en: 9887763c3f2362ad + zh: 00a5fdaf4ea5f438 +/agent-note-retire-app-boot-helpers-used-only-by-fixtures/alternatives-considered: + en: 3fdc33ab9299103d + zh: 79f42a6b79d90b8a +/agent-note-retire-app-boot-helpers-used-only-by-fixtures/acceptance-criteria: + en: a8cedd0cdfe6526d + zh: cb08fcd8117f9ddf +/agent-note-retire-app-boot-helpers-used-only-by-fixtures/risks: + en: caf3a0c07667e4ae + zh: 41195542888a3e83 diff --git a/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.i18n.yaml index 625e054ecf..1f094f2d6f 100644 --- a/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.i18n.yaml +++ b/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-retire-prompt-registry-change-event.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.md -2026-09-19-retire-prompt-registry-change-event.md: 1103675525e30c7f6c345a1fe92f07cbd0bcce4a -2026-09-19-retire-prompt-registry-change-event.zh.md: a49df2eebad7134b7b038ee2e6ab54610bd4c635 +/agent-note-retire-the-prompt-registry-change-event: + en: 081a6a1f8f256c6e + zh: c49dd9c0e7e42f24 +/agent-note-retire-the-prompt-registry-change-event/problem: + en: 22259f002f329483 + zh: d5a9c78a80af5187 +/agent-note-retire-the-prompt-registry-change-event/proposal: + en: dba84cfd3aa5f719 + zh: d3f6eece6f2f8148 +/agent-note-retire-the-prompt-registry-change-event/alternatives-considered: + en: 768edcebf26d1af4 + zh: 7c009a2f1513061e +/agent-note-retire-the-prompt-registry-change-event/acceptance-criteria: + en: 1ca375eac1e970f7 + zh: 741e1d56ec2bc89b +/agent-note-retire-the-prompt-registry-change-event/risks: + en: 0a86fce4d2962eef + zh: cecb538a90fdd5ea diff --git a/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.i18n.yaml index bed94c3f36..06790c6cff 100644 --- a/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.i18n.yaml +++ b/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-shell-env-key-declarations.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.md -2026-09-19-shell-env-key-declarations.md: 7b74e55e6b8602cb488d16040d57fe41d16e14da -2026-09-19-shell-env-key-declarations.zh.md: 03d7ed9fdee1c1181c529c2b2dd26ceb7c791ef2 +/agent-note-keep-shell-environment-declarations-focused-on-key-ownership: + en: 45ac68010d497bfd + zh: 388e4f51893c4615 +/agent-note-keep-shell-environment-declarations-focused-on-key-ownership/problem: + en: ff308f45fc6f5242 + zh: 025b58883a3e175b +/agent-note-keep-shell-environment-declarations-focused-on-key-ownership/proposal: + en: ffd78167917dfa4b + zh: dbcb1004009ea9f5 +/agent-note-keep-shell-environment-declarations-focused-on-key-ownership/alternatives-considered: + en: 476de18c44f2ad86 + zh: a0a15da6c5e7fbf7 +/agent-note-keep-shell-environment-declarations-focused-on-key-ownership/acceptance-criteria: + en: 3196e83f9ae22f45 + zh: 0766bf5914672572 +/agent-note-keep-shell-environment-declarations-focused-on-key-ownership/risks: + en: 55e2677a8d48d759 + zh: ff97043cc6a6a31b diff --git a/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.i18n.yaml index 676a701835..5cb6a84212 100644 --- a/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.i18n.yaml +++ b/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-09-19-trim-session-query-convenience-api.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.md -2026-09-19-trim-session-query-convenience-api.md: 1a3d558c9be5e16b5e9e84a59a9731b55174114c -2026-09-19-trim-session-query-convenience-api.zh.md: 63c3ae309edee8366eae4d5db10cc59f0b72e843 +/agent-note-trim-unused-sessionquery-convenience-methods: + en: 0639096a41a3eeb4 + zh: f5ff6ed78687b440 +/agent-note-trim-unused-sessionquery-convenience-methods/problem: + en: 62f49ae402951c28 + zh: 95985e67cbb5b6ac +/agent-note-trim-unused-sessionquery-convenience-methods/proposal: + en: 3848c7dcdbf70815 + zh: d2ae878e6057afc8 +/agent-note-trim-unused-sessionquery-convenience-methods/alternatives-considered: + en: 431cc99fec52f696 + zh: ee5bcfe54f7f703c +/agent-note-trim-unused-sessionquery-convenience-methods/acceptance-criteria: + en: 44741d711dff0e30 + zh: be1e6f9547dabc74 +/agent-note-trim-unused-sessionquery-convenience-methods/risks: + en: 2095fdf1f2beaa26 + zh: 0152ac808e52fd08 diff --git a/.agents/notes/proposed/testing/2026-06-11-deterministic-and-stress-testing.i18n.yaml b/.agents/notes/proposed/testing/2026-06-11-deterministic-and-stress-testing.i18n.yaml index b6e4d8e0cd..76b8746242 100644 --- a/.agents/notes/proposed/testing/2026-06-11-deterministic-and-stress-testing.i18n.yaml +++ b/.agents/notes/proposed/testing/2026-06-11-deterministic-and-stress-testing.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-11-deterministic-and-stress-testing.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/testing/2026-06-11-deterministic-and-stress-testing.md -2026-06-11-deterministic-and-stress-testing.md: d4264663178829c6e6e309ce940926bd94778755 -2026-06-11-deterministic-and-stress-testing.zh.md: 2d349682caa4f57b6d0d093d1b48c24ae431a5a5 +/agent-note-deterministic-tests-the-replay-invariant-fixture-and-race-stress: + en: 542fbe788af50a46 + zh: ac3cd25980079e57 +/agent-note-deterministic-tests-the-replay-invariant-fixture-and-race-stress/problem: + en: f53f96fa64894350 + zh: cb24d89ce7ed6d23 +/agent-note-deterministic-tests-the-replay-invariant-fixture-and-race-stress/proposal: + en: 634037df9edd48bd + zh: 5b0533bfbe315e89 +/agent-note-deterministic-tests-the-replay-invariant-fixture-and-race-stress/plan: + en: 35540eefb6f19904 + zh: 7212368b41786ffc +/agent-note-deterministic-tests-the-replay-invariant-fixture-and-race-stress/acceptance-criteria: + en: e88b12f0cdc2748a + zh: 3a918218fe6e89a7 +/agent-note-deterministic-tests-the-replay-invariant-fixture-and-race-stress/risks: + en: 072c15d39395fbde + zh: a21a7a21a7879f56 diff --git a/.agents/notes/proposed/testing/2026-06-11-mutation-testing.i18n.yaml b/.agents/notes/proposed/testing/2026-06-11-mutation-testing.i18n.yaml index d31176617a..c1c40758be 100644 --- a/.agents/notes/proposed/testing/2026-06-11-mutation-testing.i18n.yaml +++ b/.agents/notes/proposed/testing/2026-06-11-mutation-testing.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-11-mutation-testing.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/testing/2026-06-11-mutation-testing.md -2026-06-11-mutation-testing.md: 591d9012644a19ee2c67a916b63092d79f78db1f -2026-06-11-mutation-testing.zh.md: a8e786ab6566d12762c55bc559b436a13f3b32b2 +/agent-note-mutation-testing-as-the-coverage-counterweight: + en: 521fac2a2df2498e + zh: 9a508486144b2e74 +/agent-note-mutation-testing-as-the-coverage-counterweight/problem: + en: f67a5e8beb51c898 + zh: 9f997eaf27491ea4 +/agent-note-mutation-testing-as-the-coverage-counterweight/proposal: + en: 4aa172d4d1c7e419 + zh: dae8a42d5693e509 +/agent-note-mutation-testing-as-the-coverage-counterweight/plan: + en: e5b6fbdf1fbdde82 + zh: e3d050014107519f +/agent-note-mutation-testing-as-the-coverage-counterweight/acceptance-criteria: + en: 3671f37e25e586f7 + zh: e6af9b37fe92f775 +/agent-note-mutation-testing-as-the-coverage-counterweight/risks: + en: b1c2fce21adc8388 + zh: b9c2292f55c3292b diff --git a/.agents/notes/rejected/architecture/2026-06-16-typed-event-schemas.i18n.yaml b/.agents/notes/rejected/architecture/2026-06-16-typed-event-schemas.i18n.yaml index 9a28742fb7..a1a2f350fc 100644 --- a/.agents/notes/rejected/architecture/2026-06-16-typed-event-schemas.i18n.yaml +++ b/.agents/notes/rejected/architecture/2026-06-16-typed-event-schemas.i18n.yaml @@ -1,6 +1,40 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-16-typed-event-schemas.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/architecture/2026-06-16-typed-event-schemas.md -2026-06-16-typed-event-schemas.md: 5912c39016acb4bc44089af16bf46edffe3023d0 -2026-06-16-typed-event-schemas.zh.md: 67d0c1be31e56ae6f109b5cc4402629c2b6f868f +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern: + en: 63685a0c0afc3f07 + zh: 8f7e06562771ee1d +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern/problem: + en: 6bea9eb883f324d2 + zh: 2bef9b9fa5233d09 +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern/why-this-is-not-a-persistence-change: + en: 42d48e48d694d3de + zh: f556f4624b55a480 +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern/blast-radius-measured: + en: ec70e76b82ba21b5 + zh: 25fb4a60f8da5cb5 +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern/alternatives-considered: + en: 6119e2aff3b6be5a + zh: 76136ef5249c23eb +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern/alternatives-considered/a-status-quo-merge-extensible-types-isjsonvalue-at-the-durable-boundary: + en: d5ea1b3124b341a7 + zh: 766ed3689efc1802 +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern/alternatives-considered/b-header-closed-shape-validation-only-schemastery-events-stay-opaque: + en: 5120fc56473696d1 + zh: 611d6f53efa282f0 +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern/alternatives-considered/c-runtime-schema-registry-for-the-whole-vocabulary-zod-or-schemastery: + en: db3cebf2efcf1fcd + zh: 631a39e8900c0e1d +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern/proposal: + en: 33078a5945dc2aa3 + zh: 32baff49e47e9823 +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern/acceptance-criteria: + en: 37626ef8a2dcd7e0 + zh: 0b215089ce58e65d +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern/risks: + en: 79e720cfffe60257 + zh: b4aea0d52f3ee072 +/agent-note-runtime-schemas-for-the-event-vocabulary-zod-vs-the-merge-extensible-map-pattern/open-questions: + en: afc8275e1598eb34 + zh: f3684ee3aba33cf1 diff --git a/.agents/notes/rejected/architecture/2026-07-25-client-settings-locale-theme.i18n.yaml b/.agents/notes/rejected/architecture/2026-07-25-client-settings-locale-theme.i18n.yaml index 76a82753fc..0d568431e3 100644 --- a/.agents/notes/rejected/architecture/2026-07-25-client-settings-locale-theme.i18n.yaml +++ b/.agents/notes/rejected/architecture/2026-07-25-client-settings-locale-theme.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-25-client-settings-locale-theme.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/architecture/2026-07-25-client-settings-locale-theme.md -2026-07-25-client-settings-locale-theme.md: e7f4b64ab0d44492435b63a066abca9d0ae1394d -2026-07-25-client-settings-locale-theme.zh.md: 9edd7395afd48fd7088e0c64d74d1c704a584b15 +/agent-note-client-settings-locale-and-theme-layering: + en: ebeba4110da742d5 + zh: 3cfc57b1eb553185 +/agent-note-client-settings-locale-and-theme-layering/problem: + en: 4cec7e053c53607b + zh: 3796b79366e7ea58 +/agent-note-client-settings-locale-and-theme-layering/proposal: + en: 3dd489ca0eab19bd + zh: a57d5dd4d2496f04 +/agent-note-client-settings-locale-and-theme-layering/proposal/first-phase-registration-surfaces: + en: 7a4890dffd207a66 + zh: 4353be1cf48bf68d +/agent-note-client-settings-locale-and-theme-layering/proposal/slot-topology: + en: bc2aba013c52fca5 + zh: 734e5ef05792bdf9 +/agent-note-client-settings-locale-and-theme-layering/proposal/slot-declarations-are-first-class-injectable-waits: + en: 9df71cdd33cd691d + zh: 9ac3eba3d89192d9 +/agent-note-client-settings-locale-and-theme-layering/proposal/service-contracts: + en: 30c49423999492e5 + zh: bce71328fdd946c5 +/agent-note-client-settings-locale-and-theme-layering/alternatives-considered: + en: 258859f30f0b9784 + zh: 70d48285033c3d8f +/agent-note-client-settings-locale-and-theme-layering/acceptance-criteria: + en: 9ff6ce8ea22dab22 + zh: c8dd20442b50df21 +/agent-note-client-settings-locale-and-theme-layering/risks: + en: fb649d6c5a86bc09 + zh: cb5520268d365ca9 diff --git a/.agents/notes/rejected/architecture/2026-08-08-cordis-web-dynamic-packages.i18n.yaml b/.agents/notes/rejected/architecture/2026-08-08-cordis-web-dynamic-packages.i18n.yaml index d2969612cb..ede08a7406 100644 --- a/.agents/notes/rejected/architecture/2026-08-08-cordis-web-dynamic-packages.i18n.yaml +++ b/.agents/notes/rejected/architecture/2026-08-08-cordis-web-dynamic-packages.i18n.yaml @@ -1,6 +1,73 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-08-cordis-web-dynamic-packages.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/architecture/2026-08-08-cordis-web-dynamic-packages.md -2026-08-08-cordis-web-dynamic-packages.md: e6c7b9135198ae4f3c21f0b5116e99c521ede185 -2026-08-08-cordis-web-dynamic-packages.zh.md: 269f0f279f5415c6506bb509bfb54c3b819637d6 +/agent-note-cordis-host-client-dynamic-plugin-runtime: + en: f89118c354fe715d + zh: dcee1e4dd9bbb250 +/agent-note-cordis-host-client-dynamic-plugin-runtime/problem: + en: 19617f888995a1ec + zh: e4abb5efa2b77571 +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal: + en: 986dd8097aac4d3d + zh: 986dd8097aac4d3d +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/core-principles: + en: 400bacbc13cc4ca2 + zh: efb84f4257ebf13c +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/package-responsibilities-and-dependency-direction: + en: 60b7a0c8880e579c + zh: d85388f9e9d34589 +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/domain-objects: + en: fb29437ba7cc624a + zh: 2c2322991e282f7c +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/domain-objects/plugin: + en: 84d17d0aa91fa20c + zh: 354cf1a6531e2353 +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/domain-objects/package: + en: 950f4e014a7fa6df + zh: 9641809a80ddbb9f +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/domain-objects/plugin-run: + en: f5cc71352e3f2eea + zh: 6933e78a031bb3e1 +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/domain-objects/version-pointers: + en: 0d17a946a46eb645 + zh: 0d82d5287cd227af +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/host-authority-and-persistence: + en: 02a605a63f0b9d06 + zh: 3918b603de86ad4b +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/define-run-and-version-switching: + en: dce63bf4526ae240 + zh: 32898ea25290fd35 +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/client-approval-and-authorization: + en: d3c874acd464c5da + zh: 04ffde8db6a0daa9 +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/client-activation-orchestration: + en: 58708703b5069952 + zh: c378e4398b8d8063 +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/package-private-client-to-host-communication: + en: 02f6557f8f3f1155 + zh: 33e2f26f371f20b6 +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/dynamic-code-guard-and-lifecycle: + en: 601f8cc278c10286 + zh: 31aa97d5c66b086c +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/inspect-providers-and-catalogs: + en: 8febbabca425cce7 + zh: 078461769a69719f +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/model-guidance-layers: + en: 879ad6fef8ca4ae7 + zh: 38ec8d838628bacd +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/pluginid-and-tool-ui: + en: 03c501a6503961fc + zh: 4e5b6633a393f8ca +/agent-note-cordis-host-client-dynamic-plugin-runtime/proposal/errors-and-model-feedback: + en: ec2d9dedbe2cd9d5 + zh: 005260a95cda020c +/agent-note-cordis-host-client-dynamic-plugin-runtime/alternatives-considered: + en: ef5f387f4019d7ad + zh: 4d5da887bafc5f22 +/agent-note-cordis-host-client-dynamic-plugin-runtime/acceptance-criteria: + en: 3a4b3100f19377d6 + zh: c36d31e04f7d4b2d +/agent-note-cordis-host-client-dynamic-plugin-runtime/risks: + en: 3ec21c3758ab98a8 + zh: e949a28f8e38042c diff --git a/.agents/notes/rejected/process/2026-06-11-architectural-conformance.i18n.yaml b/.agents/notes/rejected/process/2026-06-11-architectural-conformance.i18n.yaml index 1d03942760..0e5a8660a4 100644 --- a/.agents/notes/rejected/process/2026-06-11-architectural-conformance.i18n.yaml +++ b/.agents/notes/rejected/process/2026-06-11-architectural-conformance.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-11-architectural-conformance.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/process/2026-06-11-architectural-conformance.md -2026-06-11-architectural-conformance.md: 631b032235aba3ecd0045cdfc72e719265efc867 -2026-06-11-architectural-conformance.zh.md: 74af5a377c0f80a6c53ecf2a1a8935c1e2f92f4c +/agent-note-architectural-conformance-dependency-rules-and-the-adapter-kit: + en: 708fe0c94db3e25a + zh: 07437d3cb67a9240 +/agent-note-architectural-conformance-dependency-rules-and-the-adapter-kit/problem: + en: 2d5d19405f22920b + zh: 8ca48379706cbe35 +/agent-note-architectural-conformance-dependency-rules-and-the-adapter-kit/proposal: + en: 81d30d5657ece906 + zh: 1e7c61e5b9229ef6 +/agent-note-architectural-conformance-dependency-rules-and-the-adapter-kit/plan: + en: 56bb9b7b97ba6bf5 + zh: 2e3f0a70ce391029 +/agent-note-architectural-conformance-dependency-rules-and-the-adapter-kit/acceptance-criteria: + en: 2953797008c6c120 + zh: 42fd01df8a2a8f0b +/agent-note-architectural-conformance-dependency-rules-and-the-adapter-kit/risks: + en: 09eb0e6924573fe0 + zh: 60ca8648ec25afca diff --git a/.agents/notes/rejected/process/2026-08-04-artifact-first-npm-baseline-publication.i18n.yaml b/.agents/notes/rejected/process/2026-08-04-artifact-first-npm-baseline-publication.i18n.yaml index c0c61084e3..e0c297bfc5 100644 --- a/.agents/notes/rejected/process/2026-08-04-artifact-first-npm-baseline-publication.i18n.yaml +++ b/.agents/notes/rejected/process/2026-08-04-artifact-first-npm-baseline-publication.i18n.yaml @@ -1,6 +1,37 @@ -# 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: +# Bilingual-pair consistency record for 2026-08-04-artifact-first-npm-baseline-publication.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/process/2026-08-04-artifact-first-npm-baseline-publication.md -2026-08-04-artifact-first-npm-baseline-publication.md: 1c317176521afd2e11707f954520039a3f229a44 -2026-08-04-artifact-first-npm-baseline-publication.zh.md: c2822ed0b572b60fe23cab7c5dc1ebfbe02230f7 +/agent-note-artifact-first-npm-baseline-publication: + en: d0656ef5ec966473 + zh: 3d7930c502e0fa0a +/agent-note-artifact-first-npm-baseline-publication/problem: + en: 262109304a235ff0 + zh: 0399026e9afa9403 +/agent-note-artifact-first-npm-baseline-publication/proposal: + en: e3324fac080bfa55 + zh: 89e385b4d37df216 +/agent-note-artifact-first-npm-baseline-publication/current-implementation-boundary: + en: 49678acc335339b1 + zh: fdebfb169e49d34d +/agent-note-artifact-first-npm-baseline-publication/publication-payload-contract: + en: 6ad6a8829fe06538 + zh: 70e1507b7c85cb8a +/agent-note-artifact-first-npm-baseline-publication/artifact-plane-integration-test: + en: 129d1df710a8c8f7 + zh: 208002598644da1b +/agent-note-artifact-first-npm-baseline-publication/publication-and-recovery: + en: f45f84678f8184ae + zh: 5f87157df6e828b5 +/agent-note-artifact-first-npm-baseline-publication/github-actions-integration: + en: c376aca1e297c9d2 + zh: 2902f72e6d16e9ae +/agent-note-artifact-first-npm-baseline-publication/alternatives-considered: + en: d3b5794ac85b0a19 + zh: 222d054cbb7c8354 +/agent-note-artifact-first-npm-baseline-publication/acceptance-criteria: + en: fc56f357e3ef7cc5 + zh: ba108d552935f6bc +/agent-note-artifact-first-npm-baseline-publication/risks: + en: 7939117bb1674385 + zh: 9768d75303b04bc1 diff --git a/.agents/notes/rejected/simplification/2026-06-20-drop-durable-step-boundaries.i18n.yaml b/.agents/notes/rejected/simplification/2026-06-20-drop-durable-step-boundaries.i18n.yaml index bd6f2c6d48..088c91091b 100644 --- a/.agents/notes/rejected/simplification/2026-06-20-drop-durable-step-boundaries.i18n.yaml +++ b/.agents/notes/rejected/simplification/2026-06-20-drop-durable-step-boundaries.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-20-drop-durable-step-boundaries.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/simplification/2026-06-20-drop-durable-step-boundaries.md -2026-06-20-drop-durable-step-boundaries.md: c5c4f269a378e334c4dc509d1288146d77d9a520 -2026-06-20-drop-durable-step-boundaries.zh.md: 2ee8abb3a57ed1a702530e9952d2d776c90554a4 +/agent-note-drop-durable-step-boundary-events: + en: 0b9830ce816f2850 + zh: 5e937fff837261f4 +/agent-note-drop-durable-step-boundary-events/problem: + en: d9011152056a58c3 + zh: 5989ef2a4f6bf5ab +/agent-note-drop-durable-step-boundary-events/proposal: + en: 3ef7c3e871cde268 + zh: fd762265542e0614 +/agent-note-drop-durable-step-boundary-events/acceptance-criteria: + en: 05d9927015af73ae + zh: a32f893355f95797 +/agent-note-drop-durable-step-boundary-events/what-we-give-up: + en: 280d1d43670d7b99 + zh: 92a21a61242694c1 diff --git a/.agents/notes/rejected/simplification/2026-06-20-fold-session-persistence-interface.i18n.yaml b/.agents/notes/rejected/simplification/2026-06-20-fold-session-persistence-interface.i18n.yaml index 47d6125e0d..7e9de72fc1 100644 --- a/.agents/notes/rejected/simplification/2026-06-20-fold-session-persistence-interface.i18n.yaml +++ b/.agents/notes/rejected/simplification/2026-06-20-fold-session-persistence-interface.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-20-fold-session-persistence-interface.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/simplification/2026-06-20-fold-session-persistence-interface.md -2026-06-20-fold-session-persistence-interface.md: 58c6aa8f5b3b77f146e18d285ebf3fe1e36b0778 -2026-06-20-fold-session-persistence-interface.zh.md: 9fb53d16fced3d17ee0a76a05df04628ac9d8c95 +/agent-note-fold-the-persistence-interface-into-dsh-session: + en: ec1120bc953f18db + zh: 905c9fcee9a2ab8c +/agent-note-fold-the-persistence-interface-into-dsh-session/problem: + en: 132b1c96f4d271a0 + zh: 52f235f23160cb1b +/agent-note-fold-the-persistence-interface-into-dsh-session/proposal: + en: 8eecfc7bd6c83608 + zh: 658fc8e8eac425b7 +/agent-note-fold-the-persistence-interface-into-dsh-session/acceptance-criteria: + en: a141343494939ee4 + zh: 2b9a95f1aadd319f +/agent-note-fold-the-persistence-interface-into-dsh-session/what-we-give-up: + en: 595671143eb17f28 + zh: a6f019fb64ba3a90 diff --git a/.agents/notes/rejected/simplification/2026-06-20-truncate-interrupted-turns.i18n.yaml b/.agents/notes/rejected/simplification/2026-06-20-truncate-interrupted-turns.i18n.yaml index d460dbd142..d1a8821362 100644 --- a/.agents/notes/rejected/simplification/2026-06-20-truncate-interrupted-turns.i18n.yaml +++ b/.agents/notes/rejected/simplification/2026-06-20-truncate-interrupted-turns.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-06-20-truncate-interrupted-turns.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/simplification/2026-06-20-truncate-interrupted-turns.md -2026-06-20-truncate-interrupted-turns.md: c4b0084de537927a27829eb78990c6559bd1df7d -2026-06-20-truncate-interrupted-turns.zh.md: ad6c85fc62077be45b1f3bb55c31cf4b4a7fd1d1 +/agent-note-truncate-interrupted-final-turns-on-load: + en: 71d2ea22bb13721d + zh: 8c215ff52de9ba0d +/agent-note-truncate-interrupted-final-turns-on-load/problem: + en: d96af2be3caa1b54 + zh: 02cb84c44916fab9 +/agent-note-truncate-interrupted-final-turns-on-load/proposal: + en: 764ee72b3b2b654a + zh: 92ea690926ff99a4 +/agent-note-truncate-interrupted-final-turns-on-load/acceptance-criteria: + en: 5aeb3cf919f6d9c7 + zh: 8cc171e48d5c0761 +/agent-note-truncate-interrupted-final-turns-on-load/what-we-give-up: + en: 583aa8d003225c57 + zh: 2d90befccf8be0ca +/agent-note-truncate-interrupted-final-turns-on-load/related: + en: a2af11959bf10ac3 + zh: 402cf5f0c4f019d8 diff --git a/.agents/notes/rejected/simplification/2026-07-04-prune-dead-core-spine-api.i18n.yaml b/.agents/notes/rejected/simplification/2026-07-04-prune-dead-core-spine-api.i18n.yaml index 52d12170a2..810e07aad4 100644 --- a/.agents/notes/rejected/simplification/2026-07-04-prune-dead-core-spine-api.i18n.yaml +++ b/.agents/notes/rejected/simplification/2026-07-04-prune-dead-core-spine-api.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-04-prune-dead-core-spine-api.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/simplification/2026-07-04-prune-dead-core-spine-api.md -2026-07-04-prune-dead-core-spine-api.md: 35130b1af2a2245ff575604466e098dcae7776cc -2026-07-04-prune-dead-core-spine-api.zh.md: d2782b733b76a29b48f74e81d4a76a0f90575fdb +/agent-note-prune-dead-public-api-and-result-fields: + en: 787501dcdb05bf03 + zh: cf13583535e5a444 +/agent-note-prune-dead-public-api-and-result-fields/problem: + en: 277564591633536c + zh: ddfbc0231a04b51d +/agent-note-prune-dead-public-api-and-result-fields/problem/grouped-helper-export-inventory: + en: 84cb62303daf31bf + zh: 3478dd10d2a761fc +/agent-note-prune-dead-public-api-and-result-fields/proposal: + en: 414aca8de0a22c38 + zh: 9458a8db0cea11e7 +/agent-note-prune-dead-public-api-and-result-fields/alternatives-considered: + en: e8eecc41540c8d67 + zh: 60110bcdfaba5dad +/agent-note-prune-dead-public-api-and-result-fields/acceptance-criteria: + en: ef426fe8180fdfe8 + zh: 7e7f4cdb5d2ce655 +/agent-note-prune-dead-public-api-and-result-fields/risks: + en: c88948f52999d392 + zh: 3b1b98c54d082ae1 diff --git a/.agents/notes/rejected/simplification/2026-07-12-prune-unused-skill-registry-api.i18n.yaml b/.agents/notes/rejected/simplification/2026-07-12-prune-unused-skill-registry-api.i18n.yaml index fdadd105b9..334f3c3c9b 100644 --- a/.agents/notes/rejected/simplification/2026-07-12-prune-unused-skill-registry-api.i18n.yaml +++ b/.agents/notes/rejected/simplification/2026-07-12-prune-unused-skill-registry-api.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-12-prune-unused-skill-registry-api.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/simplification/2026-07-12-prune-unused-skill-registry-api.md -2026-07-12-prune-unused-skill-registry-api.md: 23fb0163296a1cf6cd8700ad745f60e52371a3b1 -2026-07-12-prune-unused-skill-registry-api.zh.md: e1496aab7bc77dc04600a95bea8a5db3f8955053 +/agent-note-prune-unused-skill-registry-api: + en: ff5d0311e8e1e032 + zh: a5c7ab3f62dc41b3 +/agent-note-prune-unused-skill-registry-api/problem: + en: dcd820314b04d01c + zh: c2131cbda05d276c +/agent-note-prune-unused-skill-registry-api/proposal: + en: 803833583cc47fe4 + zh: f9cc914a2b1acb07 +/agent-note-prune-unused-skill-registry-api/alternatives-considered: + en: b8f81e90df8b47c2 + zh: 04d7b9c5fef53f6d +/agent-note-prune-unused-skill-registry-api/acceptance-criteria: + en: 601e07918e345279 + zh: 36f81302639503b5 +/agent-note-prune-unused-skill-registry-api/risks: + en: 81cbe6895b2dd805 + zh: a52ce97e9e47d177 diff --git a/.agents/notes/rejected/simplification/2026-07-19-fold-compaction-package-split.i18n.yaml b/.agents/notes/rejected/simplification/2026-07-19-fold-compaction-package-split.i18n.yaml index d524222cb5..7f181e0cc6 100644 --- a/.agents/notes/rejected/simplification/2026-07-19-fold-compaction-package-split.i18n.yaml +++ b/.agents/notes/rejected/simplification/2026-07-19-fold-compaction-package-split.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-fold-compaction-package-split.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/simplification/2026-07-19-fold-compaction-package-split.md -2026-07-19-fold-compaction-package-split.md: 17d2ff5b8b663131eb3548dbf32d9489ca174f6b -2026-07-19-fold-compaction-package-split.zh.md: a981e0096516d51481360f95a0d72720a9023c5e +/agent-note-fold-the-single-compaction-backend-into-its-service-package: + en: 22e69a4c9159be12 + zh: c68cd8f8f536dc03 +/agent-note-fold-the-single-compaction-backend-into-its-service-package/problem: + en: 272d8d731bdf45b7 + zh: 7502a76b7d3cd367 +/agent-note-fold-the-single-compaction-backend-into-its-service-package/proposal: + en: 4db8bc2ee4039e44 + zh: e1a8c9714d1c4de0 +/agent-note-fold-the-single-compaction-backend-into-its-service-package/alternatives-considered: + en: 0c7f4bd4b7745c96 + zh: 9bf5a98dd485dbbd +/agent-note-fold-the-single-compaction-backend-into-its-service-package/acceptance-criteria: + en: 40a7d8d774a68237 + zh: 004e8b40effa2f8d +/agent-note-fold-the-single-compaction-backend-into-its-service-package/risks: + en: 899ebc22beb60647 + zh: ae23733b92c2ae36 diff --git a/.agents/notes/rejected/simplification/2026-07-19-make-jsonrpc-directional.i18n.yaml b/.agents/notes/rejected/simplification/2026-07-19-make-jsonrpc-directional.i18n.yaml index 1f91fccbb3..a90825c6c8 100644 --- a/.agents/notes/rejected/simplification/2026-07-19-make-jsonrpc-directional.i18n.yaml +++ b/.agents/notes/rejected/simplification/2026-07-19-make-jsonrpc-directional.i18n.yaml @@ -1,6 +1,25 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-19-make-jsonrpc-directional.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/simplification/2026-07-19-make-jsonrpc-directional.md -2026-07-19-make-jsonrpc-directional.md: 0a4660bbf12ab6a71f08547b69458bd25881bd64 -2026-07-19-make-jsonrpc-directional.zh.md: 706a342d6ef32c00d014033b314cbbe82314ce30 +/agent-note-make-json-rpc-completion-and-transport-directional: + en: ee6e55930abd711c + zh: 8f42bc9a2ae73653 +/agent-note-make-json-rpc-completion-and-transport-directional/problem: + en: d464014520aeb2ba + zh: 8d5b916ec1e52ae2 +/agent-note-make-json-rpc-completion-and-transport-directional/proposal: + en: 1877df56f4a6c009 + zh: 88945feba13fd7f2 +/agent-note-make-json-rpc-completion-and-transport-directional/implementation-plan: + en: 98d36962531961b4 + zh: 732397d5ac3e9da5 +/agent-note-make-json-rpc-completion-and-transport-directional/alternatives-considered: + en: aa128111a837e3ce + zh: e2e70c0e7ca577f4 +/agent-note-make-json-rpc-completion-and-transport-directional/acceptance-criteria: + en: c003617f26b1b309 + zh: a0c92fd01a820b9d +/agent-note-make-json-rpc-completion-and-transport-directional/risks: + en: 2a4ab79704013a71 + zh: 17722ca6beff0536 diff --git a/.agents/notes/rejected/simplification/2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.i18n.yaml b/.agents/notes/rejected/simplification/2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.i18n.yaml index 5f4b4e03cb..2dc7fcd734 100644 --- a/.agents/notes/rejected/simplification/2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.i18n.yaml +++ b/.agents/notes/rejected/simplification/2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/simplification/2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.md -2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.md: d925222c6c1f07707815353caa15b2ff51212e7f -2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.zh.md: 34128c671e898d7a6729ca3fa132585c7b53bdbe +/agent-note-use-node-timers-promises-for-hand-rolled-cancellable-sleeps: + en: 375b81101ea10ffd + zh: 4e63456174643d83 +/agent-note-use-node-timers-promises-for-hand-rolled-cancellable-sleeps/problem: + en: 88cc75cbfeb9bb8d + zh: 945620a5e6c4982d +/agent-note-use-node-timers-promises-for-hand-rolled-cancellable-sleeps/proposal: + en: dc6c2a587810f627 + zh: 42f5e2e23cc2d1e2 +/agent-note-use-node-timers-promises-for-hand-rolled-cancellable-sleeps/alternatives-considered: + en: 1897b5c8c6179b6a + zh: e39724cb2160c679 +/agent-note-use-node-timers-promises-for-hand-rolled-cancellable-sleeps/acceptance-criteria: + en: 47f2700d922cfed9 + zh: 78ee3b0e20ac9f86 +/agent-note-use-node-timers-promises-for-hand-rolled-cancellable-sleeps/risks: + en: a63132fb74c49961 + zh: 166a88d947d555e3 diff --git a/.agents/notes/rejected/simplification/2026-07-26-dependency-swaps-rejected-by-nih-audit.i18n.yaml b/.agents/notes/rejected/simplification/2026-07-26-dependency-swaps-rejected-by-nih-audit.i18n.yaml index 5b19f5d40c..0b54901ab4 100644 --- a/.agents/notes/rejected/simplification/2026-07-26-dependency-swaps-rejected-by-nih-audit.i18n.yaml +++ b/.agents/notes/rejected/simplification/2026-07-26-dependency-swaps-rejected-by-nih-audit.i18n.yaml @@ -1,6 +1,16 @@ -# 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: +# Bilingual-pair consistency record for 2026-07-26-dependency-swaps-rejected-by-nih-audit.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/rejected/simplification/2026-07-26-dependency-swaps-rejected-by-nih-audit.md -2026-07-26-dependency-swaps-rejected-by-nih-audit.md: 1ea01d96c5e817440c1daca871603d9cec78c06a -2026-07-26-dependency-swaps-rejected-by-nih-audit.zh.md: d7140b88a75d1af045fd32e4b1048554071d68e8 +/agent-note-dependency-swaps-rejected-by-the-2026-07-nih-audit: + en: 4c5b109a95f79af5 + zh: f6d451c5d5ddae94 +/agent-note-dependency-swaps-rejected-by-the-2026-07-nih-audit/problem: + en: 7b7248fc12313b69 + zh: a55e2c3376c401a7 +/agent-note-dependency-swaps-rejected-by-the-2026-07-nih-audit/proposal: + en: 0a8ed95bec08cf62 + zh: 06de9cab1c862ac4 +/agent-note-dependency-swaps-rejected-by-the-2026-07-nih-audit/alternatives-considered: + en: 229a0110ca47384e + zh: 3f86f858d56190c5 diff --git a/.agents/skills/agent-experience/SKILL.md b/.agents/skills/agent-experience/SKILL.md index bd169f1ae2..3ad20ad5cb 100644 --- a/.agents/skills/agent-experience/SKILL.md +++ b/.agents/skills/agent-experience/SKILL.md @@ -1,6 +1,6 @@ --- name: agent-experience -description: Use when designing agent tools, skills, context loading, or multi-step workflows to make information discoverable and use context efficiently. +description: Use when writing or changing a model-facing tool definition (name, description, parameter schema, or its system-prompt section), and when designing skills, context loading, or multi-step workflows, to make information discoverable and use context efficiently. metadata: date: "2026-09-11" --- @@ -11,3 +11,11 @@ metadata: - **Prefer bounded outputs:** return concise results with identifiers or paths for retrieving details; avoid dumping entire logs or documents. - **Use locality:** include a bounded amount of likely needed adjacent context with an operation’s result. For example, deliver a thread reply with a few preceding messages. Mark omissions and truncation explicitly, and provide a way to retrieve more. - **Evaluate total work:** saving context is useful only if it does not cause more searches, repeated reads, or mistakes. + +## Tool definitions + +- **Delete obvious constraints.** Omit rules the model learns from the call result, such as a missing file failing to read or a failed send not being delivered. +- **Describe behavior, not implementation.** State what the tool does and returns; omit internal mechanisms, output markers the model sees in results, and enforcement details. +- **Put parameter rules on the parameter.** Defaults, ranges, pairing, and when-to-set rules belong in that parameter's description or schema; a description that varies with configuration usually means the varying part belongs to a parameter. +- **Say each fact once.** Do not repeat the tool definition in its system-prompt section, a parameter description in the tool description, or one tool's rules in another tool. +- **Measure the change.** Compare first-turn prompt tokens before and after a tool-definition change. diff --git a/.agents/skills/dsh-doc/references/metadata-links-i18n.md b/.agents/skills/dsh-doc/references/metadata-links-i18n.md index 31f44bc79a..19ee5dde40 100644 --- a/.agents/skills/dsh-doc/references/metadata-links-i18n.md +++ b/.agents/skills/dsh-doc/references/metadata-links-i18n.md @@ -70,7 +70,7 @@ Line equality is a structural check, not proof of faithful meaning. Review still ## Bilingual consistency records -Keep the `*.i18n.yaml` sidecar for every bilingual pair. `verify-translation-pairing` consumes its Git blob hashes for last-confirmed-text recovery, verifies structure and exact line alignment, supports automatic merging, records generated regions, and seals archives. Re-record it with `pnpm run verify-translation-pairing --write ` after either language changes. Do not copy content hashes into README frontmatter: independent edits would change the same header line and turn otherwise mergeable prose into an owner-file conflict. +Keep the `*.i18n.yaml` sidecar for every bilingual pair. It records a hash pair per heading section, excluding fenced code blocks and generated regions, so edits to different sections merge with Git's default text merge; generated data belongs in generated regions that the generator writes into both pages; `verify-translation-pairing` compares those entries with the current contents and verifies structure. Re-record it with `pnpm run verify-translation-pairing --write ` after either language changes. Do not copy content hashes into README frontmatter: independent edits would change the same header line and turn otherwise mergeable prose into an owner-file conflict. ## Dev Note diff --git a/.agents/skills/dsh-translate-docs/SKILL.md b/.agents/skills/dsh-translate-docs/SKILL.md index 5e5ec7d871..6ff2650c74 100644 --- a/.agents/skills/dsh-translate-docs/SKILL.md +++ b/.agents/skills/dsh-translate-docs/SKILL.md @@ -39,7 +39,7 @@ When translations need to be written from scratch, the orchestrating agent does ### Sources of truth (read, don't re-summarize) -- **[docs/i18n/README.md](../../../docs/i18n/README.md)** — the pairing contract: the three-file pair (`foo.md`, `foo.zh.md`, `foo.i18n.yaml`), the consistency record's both-side blob hashes, the language-switcher lines, scope, and exclusions. +- **[docs/i18n/README.md](../../../docs/i18n/README.md)** — the pairing contract: the three-file pair (`foo.md`, `foo.zh.md`, `foo.i18n.yaml`), the consistency record's per-section hashes, the language-switcher lines, scope, and exclusions. - **[docs/i18n/translation-rules.md](../../../docs/i18n/translation-rules.md)** — how to translate: faithfulness, structure preservation, terminology discipline, typography (MUST/SHOULD levels). - **[docs/i18n/terminology.md](../../../docs/i18n/terminology.md)** — the terminology table, binding in both directions. Load it BEFORE translating, not when a term feels uncertain; the terms you don't notice are the ones that drift. - **[docs/i18n/translation-prompt.md](../../../docs/i18n/translation-prompt.md)** — the automated pipeline's calibrated machine-consumed template. Agents using this skill do not render it; the terminology table is the only repository file the automated renderer injects, while this skill and `translation-rules.md` remain binding for agent-authored translations. @@ -64,7 +64,7 @@ When translations need to be written from scratch, the orchestrating agent does ## Finish the pair 1. Switcher: `[English](foo.md) | 中文` immediately after the Chinese file's H1, `English | [中文](foo.zh.md)` after the English file's H1 — add both if this is a new pair, except that a generator-owned English source stays byte-identical to generator output and omits its switcher while the Chinese counterpart still links back. -2. Record consistency: `pnpm run verify-translation-pairing --write ` recomputes and records both sides' full blob hashes in `foo.i18n.yaml`. The yaml diff in your PR is the reviewable statement "I confirmed these two say the same thing" — only run it after you actually have. +2. Record consistency: `pnpm run verify-translation-pairing --write ` recomputes and records the per-section hashes in `foo.i18n.yaml`. The yaml diff in your PR is the reviewable statement "I confirmed these two say the same thing" — only run it after you actually have. 3. No manifest entry is needed for an ordinary document: every in-scope source requires a pair. Change [scripts/translation-pairing.manifest.json](../../../scripts/translation-pairing.manifest.json) only when the owning policy documents a genuine generated, instructional, or bilingual-by-construction exclusion. 4. Before the PR: the touched pairs are green under the scoped check; `pnpm run doc-sync` (which includes the corpus-wide pairing check plus `verify-md-wrap`/`verify-md-links`) runs once at PR level per [dsh-pre-push-checks](../dsh-pre-push-checks/SKILL.md), not inside each translation task. 5. Keep the PR reviewable: state which pairs are new versus minimally updated and list 「待定术语」 prominently. diff --git a/.gitattributes b/.gitattributes index ed321c2b18..e878c9db19 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,10 +8,6 @@ *.pdf binary -# Pairing records are generated from the three confirmed owner-blob pairs. -# The worktree-local installer registers the fail-closed driver command. -*.i18n.yaml merge=dsh-translation-pairing - # The persistence catalog is the readable projection of these generated schemas. docs/persistence-schema.json linguist-generated=true docs/persistence-changes/*.schema.json linguist-generated=true diff --git a/.github/issue-management/README.i18n.yaml b/.github/issue-management/README.i18n.yaml index beaf888252..0d62118377 100644 --- a/.github/issue-management/README.i18n.yaml +++ b/.github/issue-management/README.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .github/issue-management/README.md -README.md: 49e91859f4b22fda13d0e93c6e6ea492272f6951 -README.zh.md: 8424f90cd2e3a59ba1212f64f3f1081a984b55f8 +/: + en: d5e0fd5da06b95ab + zh: db4281526c40cc1d +/issue-management: + en: 44fb5f74b6908794 + zh: cc25f420bac7d40b +/issue-management/summary: + en: b3f6f5f011516611 + zh: 7e6c83caf28ea807 +/issue-management/table-of-contents: + en: cff988027897ee0d + zh: 36a444b895dfdc48 +/issue-management/pull-request-policy: + en: ad11184112771cc8 + zh: cc8c112a76dcf62e +/issue-management/lifecycle-events: + en: 62bca299f0a5e213 + zh: 8853e01a9e3776ec +/issue-management/configuration-and-limitations: + en: 3ef00734bb83737f + zh: 9d91319c953496dd +/issue-management/module-ownership: + en: e83f694e0be99e69 + zh: 85fb201f86af2ce8 +/issue-management/verification: + en: b52fe10bcb063600 + zh: 3362170645a58eff +/issue-management/dev-note: + en: b75c8458928b72b9 + zh: 003ba4e17b4b5269 diff --git a/.github/preview-sizing/README.i18n.yaml b/.github/preview-sizing/README.i18n.yaml index cd5241c300..d2372d8529 100644 --- a/.github/preview-sizing/README.i18n.yaml +++ b/.github/preview-sizing/README.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .github/preview-sizing/README.md -README.md: 142854e582523eb1ed48924a73fbe29ea6164bf6 -README.zh.md: a71325189dc7966df87e14bbb591af3c76a3d498 +/pr-preview-runner-sizing: + en: 3c780cfadb127740 + zh: 07de037f824d70c6 +/pr-preview-runner-sizing/summary: + en: a6a48d1e702098d2 + zh: 69b246b95e09e638 +/pr-preview-runner-sizing/table-of-contents: + en: 0395d2bbce9a9532 + zh: a05a2ed9b0eb8476 +/pr-preview-runner-sizing/comparison-requirements: + en: 2374f332d040ece2 + zh: 7f914fb83cfb5caa +/pr-preview-runner-sizing/publication-semantics: + en: 25ee2f4b26ef7770 + zh: 788b7fb4bee6e159 +/pr-preview-runner-sizing/dev-note: + en: 85ac56719e30a350 + zh: f53f31c1b8553cc0 diff --git a/BRAND_GUIDELINES.i18n.yaml b/BRAND_GUIDELINES.i18n.yaml index c7147b4425..2f7eb7ceab 100644 --- a/BRAND_GUIDELINES.i18n.yaml +++ b/BRAND_GUIDELINES.i18n.yaml @@ -1,6 +1,7 @@ -# 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: +# Bilingual-pair consistency record for BRAND_GUIDELINES.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write BRAND_GUIDELINES.md -BRAND_GUIDELINES.md: 900cf7bcec70ff78c6f55ed535897239cd4648df -BRAND_GUIDELINES.zh.md: 94b239b6f6f4021f52da233cbefd23b4cc11f675 +/deepseek-harness-brand-asset-usage-guidelines: + en: 23933888033edf18 + zh: eaa5afb9e2cb4d25 diff --git a/CONTRIBUTING.i18n.yaml b/CONTRIBUTING.i18n.yaml index a7dabc2fff..eaafcdccad 100644 --- a/CONTRIBUTING.i18n.yaml +++ b/CONTRIBUTING.i18n.yaml @@ -1,6 +1,7 @@ -# 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: +# Bilingual-pair consistency record for CONTRIBUTING.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write CONTRIBUTING.md -CONTRIBUTING.md: 9f30e23a6d9567db7d6097cb82e481b16dda299e -CONTRIBUTING.zh.md: 35eb0b87fc4d9af11bef616039570dc5e6a1b309 +/contributing: + en: 08d2f421ff3617f4 + zh: 9d060d70ad186dc5 diff --git a/README.i18n.yaml b/README.i18n.yaml index ce6f75b18d..7f314d80ef 100644 --- a/README.i18n.yaml +++ b/README.i18n.yaml @@ -1,6 +1,34 @@ -# 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: +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write README.md -README.md: 423bccd7d9352dbc48f1705f37d35642e74f5b41 -README.zh.md: c760f87e4ac3b7dbb7bb55d733e31db5ab379836 +/deepseek-harness: + en: f68c4f080ce55ff2 + zh: 88a76d7f7f0b260e +/deepseek-harness/developer-preview: + en: 4ef4d8a71ac143f0 + zh: 1bfc3149ba8e5543 +/deepseek-harness/run: + en: 4e0248e4c6474fc6 + zh: eb2fb8d78c7d6bc0 +/deepseek-harness/run/run-from-npm: + en: e22005cd42e6cbad + zh: 0f536f4208df1d60 +/deepseek-harness/run/run-from-source: + en: 819e3f7c144d0d64 + zh: de815f040975dba7 +/deepseek-harness/community-and-support: + en: 42848f543aff6e02 + zh: d46a07bdc6f36629 +/deepseek-harness/contributing: + en: cabc2d3e9f8898bd + zh: 83b6d238bae29ce3 +/deepseek-harness/development: + en: 803ca2b11b497bed + zh: 8b4071eb0e7783ef +/deepseek-harness/citation: + en: 6704e9e5a8d49a91 + zh: 85c9cdd8d56f8e9d +/deepseek-harness/license: + en: 926995344fc1c72b + zh: c92fab5abf85932f diff --git a/SAFETY.i18n.yaml b/SAFETY.i18n.yaml index 6010fd783e..148ee39597 100644 --- a/SAFETY.i18n.yaml +++ b/SAFETY.i18n.yaml @@ -1,6 +1,19 @@ -# 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: +# Bilingual-pair consistency record for SAFETY.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write SAFETY.md -SAFETY.md: 2b76f00e0619ee69553afdc507df361080f4d3ac -SAFETY.zh.md: 6f7dae47b3e47ddfb155adb9c8c868b516d75360 +/safety: + en: a374f70c56b3f221 + zh: a07f7a9ba9af40fc +/safety/experimental-status: + en: 39a995a6c819f73e + zh: e577df19392736ac +/safety/sandbox-limitations: + en: a2b6cf1311f3abb6 + zh: c3694663312f4d6c +/safety/responsible-use: + en: ca3e9da7c0b360fe + zh: c0a6891a197d48cd +/safety/no-warranty-or-liability: + en: 71a2989f530f2018 + zh: e90e55f11068a91f diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 862299b9a2..3f325012a0 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -43,6 +43,7 @@ External packages installed for runtime use or distributed inside the prebuilt b | [`@fortune-sheet/react`](https://github.com/ruilisi/fortune-sheet) | MIT | | [`@joplin/turndown-plugin-gfm`](https://github.com/laurent22/joplin-turndown-plugin-gfm) | MIT | | [`@jridgewell/gen-mapping`](https://github.com/jridgewell/sourcemaps) | MIT | +| [`@js-temporal/polyfill`](https://github.com/js-temporal/temporal-polyfill) | ISC | | [`@lexical/history`](https://github.com/facebook/lexical) | MIT | | [`@lexical/plain-text`](https://github.com/facebook/lexical) | MIT | | [`@lexical/text`](https://github.com/facebook/lexical) | MIT | diff --git a/apps/cli/README.i18n.yaml b/apps/cli/README.i18n.yaml index 7e395f72d5..b5afe5cdf1 100644 --- a/apps/cli/README.i18n.yaml +++ b/apps/cli/README.i18n.yaml @@ -1,6 +1,22 @@ -# 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: +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write apps/cli/README.md -README.md: 4eb113a6155433cb69f949d9e461ccfbd0142e7c -README.zh.md: 6a0e8a38a70d2ad551b4e91619545b3def09f2ec +/deepseek-ai-dsh: + en: ebdc75fa0da18801 + zh: 5c6cd2554b8f8a98 +/deepseek-ai-dsh/entry-modes: + en: 093936b9e1a59bea + zh: 12be7d2d931d9671 +/deepseek-ai-dsh/app-arguments: + en: cc03e6b75206661b + zh: 99e41f4143198352 +/deepseek-ai-dsh/profiles: + en: 79cad979b0f7895c + zh: b0f922a4b43accf8 +/deepseek-ai-dsh/optional-overlays: + en: 3a40ddc44e55f79c + zh: 8d3949132e1ef93c +/deepseek-ai-dsh/development: + en: 99a36e4f7ea3f9c7 + zh: 07ca2934de700caa diff --git a/apps/cli/README.md b/apps/cli/README.md index 4eb113a615..1ebada88ae 100644 --- a/apps/cli/README.md +++ b/apps/cli/README.md @@ -36,6 +36,8 @@ dsh --help # the launcher's own help A profile directory holds a `package.json` (out-of-tree plugin dependencies plus the profile manifest `dsh.profile` with its ordered `bundles` list) and a `cordis.patch.yml` (the user's own patch layer). `dsh-hmr`, when enabled in YAML, watches the profile manifest and both profile and home patch files, then recomposes all layers through one serialized reload. Without HMR, changes apply on restart. Edits arriving during watcher registration use the same nonfatal reload reporting as later edits. [Plugin Manager](../../packages/boot/plugin-manager/README.md) shares package operations and the profile write lock with `dsh plugin`; package updates retain disabled bundle selections. CLI package commands inherit authentication variables and terminal descriptors, including interactive build approval; service calls retain their scrubbed environment and captured diagnostics. +Installation and profile startup enforce declared DSH peer ranges against the same runtime version shown by `dsh --version`. Incompatible plugins require an explicitly acknowledged exact-version exemption. The [plugin manager's compatibility reference](../../packages/boot/plugin-manager/README.md#version-compatibility-and-exemptions) documents `version-exemptions`, `allow-version`, `revoke-version`, persistence, and risks. + The tree composes over an empty root: - each bundle's patch in `dsh.profile.bundles` order - then the profile's `cordis.patch.yml`, then the home-level `$DSH_HOME/cordis.patch.yml` @@ -49,7 +51,7 @@ The [CLI behavior reference](reference/README.md) owns exact layer precedence, f ## Optional overlays -`config/examples/` ships opt-in overlays for GitHub review webhooks, session-local Schedule, memory MCP servers, and runtime Cordis tools. They are never part of a default profile; the [user guides](../../docs/user/guide/index.md) and [developer practice guides](../../docs/user/develop/practice/index.md) own setup and safety instructions. +`config/examples/` ships opt-in overlays for GitHub review webhooks, memory MCP servers, and runtime Cordis tools. They are never part of a default profile; the [user guides](../../docs/user/guide/index.md) and [developer practice guides](../../docs/user/develop/practice/index.md) own setup and safety instructions. ## Development diff --git a/apps/cli/README.zh.md b/apps/cli/README.zh.md index 6a0e8a38a7..ac8f61a24a 100644 --- a/apps/cli/README.zh.md +++ b/apps/cli/README.zh.md @@ -36,6 +36,8 @@ dsh --help # the launcher's own help profile 目录包含一个 `package.json`,其中记录树外插件依赖,以及 profile manifest(元数据清单)`dsh.profile`、其中按顺序排列的 `bundles` 列表;还包含一个 `cordis.patch.yml`,其中保存用户自己的 patch 层。在 YAML 中启用的 `dsh-hmr` 监视 profile manifest、profile 与 home 级 patch 文件,再通过统一串行重载重新组合所有层。未启用 HMR 时,更改在重启后生效。监听器注册期间发生的编辑与后续编辑使用相同的非致命重载错误报告。[插件管理器](../../packages/boot/plugin-manager/README.zh.md) 与 `dsh plugin` 共享包操作和 profile 写锁;更新依赖会保留已停用的组合包选择。CLI 包操作继承认证环境和终端描述符,支持交互式构建批准;service 调用保留清理后的环境并捕获诊断。 +安装和 profile 启动会按声明的 DSH peer 范围,检查与 `dsh --version` 显示值相同的运行时版本。不兼容插件需要用户明确确认精确版本豁免。[插件管理器的兼容性参考](../../packages/boot/plugin-manager/README.zh.md#version-compatibility-and-exemptions)说明 `version-exemptions`、`allow-version`、`revoke-version`、持久化规则与风险。 + 配置树以空根为起点,依次叠加以下配置层: - `dsh.profile.bundles` 中各组合包的 patch - profile 自身的 `cordis.patch.yml`,然后是 home 级的 `$DSH_HOME/cordis.patch.yml` @@ -49,7 +51,7 @@ profile 目录包含一个 `package.json`,其中记录树外插件依赖,以 ## 可选覆盖层 -`config/examples/` 交付 GitHub 评审 webhook、会话内 Schedule、记忆 MCP 服务器与运行时 Cordis 工具的可选覆盖层。它们绝不属于默认 profile;设置与安全说明由[用户指南](../../docs/user/guide/index.zh.md)和[开发实战指南](../../docs/user/develop/practice/index.zh.md)负责。 +`config/examples/` 交付 GitHub 评审 webhook、记忆 MCP 服务器与运行时 Cordis 工具的可选覆盖层。它们绝不属于默认 profile;设置与安全说明由[用户指南](../../docs/user/guide/index.zh.md)和[开发实战指南](../../docs/user/develop/practice/index.zh.md)负责。 ## 开发 diff --git a/apps/cli/composition.md b/apps/cli/composition.md index 81097704db..e72a1f0ce6 100644 --- a/apps/cli/composition.md +++ b/apps/cli/composition.md @@ -190,8 +190,10 @@ flowchart LR cfg --> plugin_dsh_base_agent_loop plugin_dsh_base_fs_sandbox["fs-sandbox
@deepseek-ai/dsh-fs-sandbox"] cfg --> plugin_dsh_base_fs_sandbox - plugin_dsh_base_llm_deepseek["llm-deepseek
@deepseek-ai/dsh-llm-deepseek"] + plugin_dsh_base_llm_deepseek["llm-deepseek
@deepseek-ai/dsh-llm-deepseek-api-key"] cfg --> plugin_dsh_base_llm_deepseek + plugin_dsh_base_llm_deepseek_account["llm-deepseek-account
@deepseek-ai/dsh-llm-deepseek-account"] + cfg --> plugin_dsh_base_llm_deepseek_account ``` | Plugin id | Package / module | @@ -287,7 +289,8 @@ flowchart LR | `system-prompt` | `@deepseek-ai/dsh-system-prompt` | | `agent-loop` | `@deepseek-ai/dsh-agent-loop` | | `fs-sandbox` | `@deepseek-ai/dsh-fs-sandbox` | -| `llm-deepseek` | `@deepseek-ai/dsh-llm-deepseek` | +| `llm-deepseek` | `@deepseek-ai/dsh-llm-deepseek-api-key` | +| `llm-deepseek-account` | `@deepseek-ai/dsh-llm-deepseek-account` | Source config: [`packages/bundle/base/cordis.patch.yml`](../../packages/bundle/base/cordis.patch.yml). diff --git a/apps/cli/config/examples/schedule/cordis.yml b/apps/cli/config/examples/schedule/cordis.yml deleted file mode 100644 index 04fe85214d..0000000000 --- a/apps/cli/config/examples/schedule/cordis.yml +++ /dev/null @@ -1,12 +0,0 @@ -# Opt-in Schedule patch over the shipped Web composition. The owner observes -# only roots published after this overlay loads. - -- insert: - - id: time-context - name: '@deepseek-ai/dsh-time-context' - - - id: schedule - name: '@deepseek-ai/dsh-schedule' - -- id: ui-schedule - disabled: false diff --git a/apps/cli/package.json b/apps/cli/package.json index b433c2407f..8b9dbbac17 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -1,7 +1,7 @@ { "name": "@deepseek-ai/dsh", "description": "dsh CLI: profile launch, plugin management, and configuration inspection", - "version": "0.1.7-alpha.2", + "version": "0.1.7-rc.2", "publishConfig": { "access": "public" }, @@ -99,7 +99,8 @@ "@deepseek-ai/dsh-plugin-manager": "workspace:*", "@deepseek-ai/dsh-atomic-write": "workspace:*", "@deepseek-ai/dsh-agent-preset": "workspace:*", - "@deepseek-ai/dsh-experimental-voice-input-bundle": "workspace:*" + "@deepseek-ai/dsh-experimental-voice-input-bundle": "workspace:*", + "@deepseek-ai/dsh-experimental-auto-review": "workspace:*" }, "devDependencies": { "@agentclientprotocol/sdk": "1.4.0", @@ -120,6 +121,8 @@ "@deepseek-ai/dsh-host-webserver": "workspace:*", "@deepseek-ai/dsh-llm": "workspace:*", "@deepseek-ai/dsh-llm-deepseek": "workspace:*", + "@deepseek-ai/dsh-llm-deepseek-api-key": "workspace:*", + "@deepseek-ai/dsh-llm-deepseek-account": "workspace:*", "@deepseek-ai/dsh-llm-mock-server": "workspace:*", "@deepseek-ai/dsh-llm-pi-ai": "workspace:*", "@deepseek-ai/dsh-llm-replay": "workspace:*", @@ -127,6 +130,7 @@ "@deepseek-ai/dsh-plugin-package-inventory-deepseek": "workspace:*", "@deepseek-ai/dsh-sandbox-local": "workspace:*", "@deepseek-ai/dsh-sandbox-policy": "workspace:*", + "@deepseek-ai/dsh-sdk-client": "workspace:*", "@deepseek-ai/dsh-session": "workspace:*", "@deepseek-ai/dsh-session-checkpoint-policy": "workspace:*", "@deepseek-ai/dsh-session-log-deepseek": "workspace:*", diff --git a/apps/cli/reference/README.i18n.yaml b/apps/cli/reference/README.i18n.yaml index 3d7319ec04..96646ef29a 100644 --- a/apps/cli/reference/README.i18n.yaml +++ b/apps/cli/reference/README.i18n.yaml @@ -1,6 +1,31 @@ -# 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: +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write apps/cli/reference/README.md -README.md: 094d8ba5bfaa851429adbfa872105550e8b63fe2 -README.zh.md: 2bd6abde1cb854ec9598f8f7cc10cc0a7538d2f9 +/dsh-cli-behavior-reference: + en: d25712a65d21ab45 + zh: b1c57b706bc64085 +/dsh-cli-behavior-reference/profile-boot: + en: e3a159750f5f9ed3 + zh: e02d9004fcc239f9 +/dsh-cli-behavior-reference/profile-boot/app-arguments: + en: 241e5525aa09a33b + zh: 398f853143097154 +/dsh-cli-behavior-reference/profile-boot/config-schema-dump: + en: a356f8a68f3b3685 + zh: c718713b5d709295 +/dsh-cli-behavior-reference/startup-diagnostics: + en: d6368bf97a02bd57 + zh: 2ab7888a108961ce +/dsh-cli-behavior-reference/plugin-management: + en: 9980ff1600fa9460 + zh: cc66ba45e27b5540 +/dsh-cli-behavior-reference/web-profile: + en: 12bba432c07573bf + zh: ab6b365cfb95003f +/dsh-cli-behavior-reference/shared-deployment-behavior: + en: 24e3da3716d261fe + zh: 060611966db4ca69 +/dsh-cli-behavior-reference/source-execution: + en: 05c2b23790f7b296 + zh: 51f809020fb230a1 diff --git a/apps/cli/src/bin.ts b/apps/cli/src/bin.ts index e52c7c8202..20f5867e23 100644 --- a/apps/cli/src/bin.ts +++ b/apps/cli/src/bin.ts @@ -6,29 +6,17 @@ /* v8 ignore file -- built-bin acceptance exercises this self-executing dispatch. */ -import { readFileSync } from 'node:fs' -import { fileURLToPath } from 'node:url' -import { loadLayeredEnv, StartupError } from '@deepseek-ai/dsh-app-boot' +import { getDshRuntimeVersion, loadLayeredEnv, StartupError } from '@deepseek-ai/dsh-app-boot' import { resolveDshHome } from '@deepseek-ai/dsh-home-paths' import { parseDshArgs } from './args.ts' import { reportStartupFailure } from './startup-diagnostics.ts' -// Both the source tree (apps/cli/src) and the bundled bin (apps/cli/lib) sit -// one directory under apps/cli, so the checked-in manifest resolves with the -// same relative hop from either artifact. -function readVersion(): string { - const manifest = JSON.parse( - readFileSync(fileURLToPath(new URL('../package.json', import.meta.url)), 'utf8'), - ) as { version?: unknown } - return typeof manifest.version === 'string' ? manifest.version : '0.0.0' -} - /** * Run the public dsh command-line interface. * @returns a promise that settles when the selected command mode finishes. */ export async function runCli(): Promise { - const version = readVersion() + const version = getDshRuntimeVersion() const invocation = parseDshArgs(process.argv.slice(2), version) switch (invocation.mode) { diff --git a/apps/cli/src/dump-config-schema.ts b/apps/cli/src/dump-config-schema.ts index 874cd56f8c..1d92f2dfca 100644 --- a/apps/cli/src/dump-config-schema.ts +++ b/apps/cli/src/dump-config-schema.ts @@ -35,7 +35,7 @@ export async function runDumpConfigSchema( // Trusted module diagnostics must not precede the JSON document on stdout. process.stdout.write = process.stderr.write.bind(process.stderr) try { - dump = await generateConfigSchema(NAME, loaded, layers.map(layer => layer.patches), INSTALL_ANCHOR) + dump = await generateConfigSchema(loaded, layers.map(layer => layer.patches), INSTALL_ANCHOR) } finally { process.stdout.write = stdoutWrite } diff --git a/apps/cli/src/plugin.ts b/apps/cli/src/plugin.ts index 12a0dbc443..8f60bf8bfc 100644 --- a/apps/cli/src/plugin.ts +++ b/apps/cli/src/plugin.ts @@ -1,23 +1,83 @@ -/** dsh plugin forwards pnpm through the shared profile package operations. */ -import { runPluginCommand } from '@deepseek-ai/dsh-plugin-manager/operations' +/** Profile package management and explicit, exact-version compatibility approvals. */ +import { runPluginCommand, setProfileVersionExemption } from '@deepseek-ai/dsh-plugin-manager/operations' import { INSTALL_ANCHOR } from './profile-boot.ts' -import { resolveProfileDir } from '@deepseek-ai/dsh-app-boot' +import { DEFAULT_PROFILE_BUNDLES, initProfile, PROFILE_TEMPLATES, readProfileCompatibility, resolveProfileDir } from '@deepseek-ai/dsh-app-boot' +import { withFileLock } from '@deepseek-ai/dsh-atomic-write' +import { existsSync } from 'node:fs' +import { mkdir } from 'node:fs/promises' import { join } from 'node:path' +/** Parse only DSH-owned commands; all other arguments remain pnpm's responsibility. */ +async function versionCommand(profile: string, args: readonly string[]): Promise { + const [command, ...rest] = args + if (command !== 'allow-version' && command !== 'revoke-version' && command !== 'version-exemptions') return undefined + try { + let packageVersion: string | undefined + let runtimeVersion: string | undefined + let acceptRisk = false + const argumentsIterator = rest.values() + for (const argument of argumentsIterator) { + if (argument === '--accept-risk' && command === 'allow-version' && !acceptRisk) acceptRisk = true + else if (argument === '--dsh-version' && runtimeVersion === undefined) runtimeVersion = argumentsIterator.next().value + else if (argument.startsWith('--dsh-version=') && runtimeVersion === undefined) runtimeVersion = argument.slice('--dsh-version='.length) + else if (!argument.startsWith('-') && packageVersion === undefined) packageVersion = argument + else throw new Error(`unexpected argument ${JSON.stringify(argument)}`) + } + if (command === 'version-exemptions' && rest.length > 0) throw new Error('usage: dsh plugin version-exemptions') + let request: { packageVersion: string; runtimeVersion: string } | undefined + if (command !== 'version-exemptions') { + if (packageVersion === undefined || runtimeVersion === undefined) { + throw new Error(`usage: dsh plugin ${command} --dsh-version ${command === 'allow-version' ? ' --accept-risk' : ''}`) + } + request = { packageVersion, runtimeVersion } + } + if (command === 'allow-version') { + process.stderr.write('dsh: warning: allowing incompatible plugin versions can break the application or corrupt data. Approval applies only to the exact package and DSH versions.\n') + } + const dir = resolveProfileDir(profile) + await mkdir(dir, { recursive: true }) + await withFileLock(join(dir, 'package.json'), async () => { + if (!existsSync(join(dir, 'package.json'))) initProfile(dir, PROFILE_TEMPLATES[profile]?.bundles ?? DEFAULT_PROFILE_BUNDLES) + if (request === undefined) { + const { exemptions, warnings } = readProfileCompatibility(dir) + for (const warning of warnings) process.stderr.write(`dsh: warning: ${warning}\n`) + process.stdout.write(JSON.stringify(exemptions, undefined, 2) + '\n') + } else { + await setProfileVersionExemption(dir, request.packageVersion, request.runtimeVersion, command === 'allow-version', acceptRisk) + process.stdout.write(`dsh: ${command === 'allow-version' ? 'allowed' : 'revoked'} ${request.packageVersion} for DSH ${request.runtimeVersion}\n`) + } + }, { waitMs: 120000 }) + return 0 + } catch (error) { + process.stderr.write(`dsh: ${String(error)}\n`) + return 1 + } +} + /** Run package management for a profile. * @param profile Profile name. - * @param args Pnpm arguments relative to the invoking directory. - * @returns Pnpm exit code. + * @param args DSH exemption command or pnpm arguments relative to the invoking directory. + * @returns Zero on success; nonzero on invalid approval or package-manager failure. */ export async function runPlugin(profile: string, args: readonly string[]): Promise { + const versionResult = await versionCommand(profile, args) + if (versionResult !== undefined) return versionResult + const dir = resolveProfileDir(profile) + if (existsSync(join(dir, 'package.json'))) { + for (const warning of readProfileCompatibility(dir).warnings) process.stderr.write(`dsh: warning: ${warning}\n`) + } const result = await runPluginCommand({ profile, installAnchor: INSTALL_ANCHOR, cwd: process.cwd() }, args, { execution: 'cli', outputBytes: 16384, lockWaitMs: 120000, + lookupTimeoutMs: 120000, onOutput: (text, stream) => { process[stream].write(text) }, }) if (result.exitCode === 127) process.stderr.write('dsh: pnpm was not found; install pnpm and make it available on PATH.\n') - if (result.exitCode !== 0) process.stderr.write(`dsh: pnpm failed; diagnostics: ${result.logPath}\n`) + for (const { name, version, runtimeVersion } of result.incompatible ?? []) { + process.stderr.write(`dsh: to accept the risk, run: dsh plugin --profile ${profile} allow-version ${name}@${version} --dsh-version ${runtimeVersion} --accept-risk\n`) + } + if (result.exitCode !== 0) process.stderr.write(`dsh: plugin command failed; diagnostics: ${result.logPath}\n`) if (result.exitCode !== 0 && args.some(argument => /^git\+|^github:|\.git(?:#|$)/.test(argument))) { process.stderr.write(`dsh: git-hosted plugins build on install via their prepare script, which pnpm blocks until allowed — add the exact key pnpm printed above under allowBuilds in ${join(resolveProfileDir(profile), 'pnpm-workspace.yaml')}, then re-run\n`) } diff --git a/apps/cli/src/profile-boot.ts b/apps/cli/src/profile-boot.ts index 9e40d01f70..b795f627ca 100644 --- a/apps/cli/src/profile-boot.ts +++ b/apps/cli/src/profile-boot.ts @@ -23,6 +23,7 @@ import { installFailLoud, loadOverlayPatches, loadProfile, + reportSkippedBundles, PluginPackages, PROFILE_PATCH_FILENAME, PROFILE_TEMPLATES, @@ -166,6 +167,7 @@ export function initializeProfileFromDefault( export function prepareProfile(name: string, userLayer = true, fromDefaultProfile?: string): Profile { if (fromDefaultProfile !== undefined) initializeProfileFromDefault(name, fromDefaultProfile) const profile = loadProfile(NAME, name, INSTALL_ANCHOR, undefined, { userLayer }) + reportSkippedBundles(NAME, profile) writeFileSync(join(profile.dir, PROFILE_ROOT_FILENAME), PROFILE_ROOT_CONFIG) return profile } diff --git a/apps/cli/tests/built-bin.e2e.ts b/apps/cli/tests/built-bin.e2e.ts index 874e216499..b26b3e538c 100644 --- a/apps/cli/tests/built-bin.e2e.ts +++ b/apps/cli/tests/built-bin.e2e.ts @@ -1246,7 +1246,7 @@ describe.skipIf(!existsSync(dshBin))('dsh BUILT bin (node lib/bin.js, no tsx)', ['deepseek-llm-api-extensions', '@deepseek-ai/dsh-deepseek-llm-api-extensions'], ['session-log-deepseek', '@deepseek-ai/dsh-session-log-deepseek'], ['plugin-package-inventory-deepseek', '@deepseek-ai/dsh-plugin-package-inventory-deepseek'], - ['llm-deepseek', '@deepseek-ai/dsh-llm-deepseek'], + ['llm-deepseek', '@deepseek-ai/dsh-llm-deepseek-api-key'], ['sandbox', '@deepseek-ai/dsh-sandbox-local'], ['session-projection', '@deepseek-ai/dsh-session-projection'], ['sandbox-policy', '@deepseek-ai/dsh-sandbox-policy'], diff --git a/apps/cli/tests/desktop-host.e2e.ts b/apps/cli/tests/desktop-host.e2e.ts index 57afeb20c4..e486354a33 100644 --- a/apps/cli/tests/desktop-host.e2e.ts +++ b/apps/cli/tests/desktop-host.e2e.ts @@ -28,7 +28,7 @@ it.each([false, true])('settles startup after parent IPC disconnect (boot failur } writeFileSync(join(root, 'package.json'), '{"type":"module"}') writeFileSync(join(modules, 'dsh-app-boot', 'package.json'), '{"type":"module","exports":"./index.js"}') - writeFileSync(join(modules, 'dsh-app-boot', 'index.js'), 'export const loadProfileDirectory = () => ({}); export const loadLayeredEnv = () => ({})') + writeFileSync(join(modules, 'dsh-app-boot', 'index.js'), 'export const loadProfileDirectory = () => ({ skippedBundles: [] }); export const reportSkippedBundles = () => {}; export const loadLayeredEnv = () => ({})') writeFileSync(join(modules, 'dsh', 'package.json'), '{"type":"module","exports":{"./profile-boot":"./profile-boot.js"}}') writeFileSync(join(modules, 'dsh', 'profile-boot.js'), ` import { writeFileSync } from 'node:fs'; diff --git a/apps/cli/tests/plugin-compatibility.expected.e2e.ts b/apps/cli/tests/plugin-compatibility.expected.e2e.ts new file mode 100644 index 0000000000..a002bb2514 --- /dev/null +++ b/apps/cli/tests/plugin-compatibility.expected.e2e.ts @@ -0,0 +1,69 @@ +/** Published CLI acceptance for actual pnpm installation, restart checks, and explicit exemptions. */ +import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { fileURLToPath } from 'node:url' +import { execa } from 'execa' +import { expect, it, onTestFinished } from 'vitest' + +const bin = fileURLToPath(new URL('../lib/bin.js', import.meta.url)) +const version = (JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) as { version: string }).version + +it('refuses incompatible installation and startup until an exact risk exemption is granted', async () => { + const home = mkdtempSync(join(tmpdir(), 'dsh-compatibility-cli-')) + onTestFinished(() => { rmSync(home, { recursive: true, force: true }) }) + const profile = join(home, 'profiles', 'compatibility') + const source = join(home, 'fixture-plugin') + mkdirSync(profile, { recursive: true }) + mkdirSync(source) + const profileFile = join(profile, 'package.json') + const initial = { name: 'compatibility-profile', private: true, dependencies: {}, dsh: { profile: { bundles: [] } } } + writeFileSync(profileFile, JSON.stringify(initial)) + writeFileSync(join(profile, 'pnpm-workspace.yaml'), 'packages:\n - .\nnodeLinker: hoisted\nautoInstallPeers: false\n') + writeFileSync(join(source, 'package.json'), JSON.stringify({ + name: 'compatibility-fixture', version: '1.0.0', type: 'module', + peerDependencies: { '@deepseek-ai/dsh': '999.0.0' }, dsh: { bundle: { patch: './cordis.patch.yml' } }, + })) + writeFileSync(join(source, 'cordis.patch.yml'), '- insert:\n - id: compatibility-fixture\n name: ./index.mjs\n') + writeFileSync(join(source, 'index.mjs'), 'process.stdout.write("PLUGIN_IMPORTED\\n"); export function apply() { process.stdout.write("PLUGIN_STARTED\\n") }\n') + const run = async (args: string[]) => { + const result = await execa(process.execPath, [bin, ...args], { + cwd: home, env: { ...process.env, DSH_HOME: home }, extendEnv: false, reject: false, timeout: 60_000, + }) + expect(result.timedOut).toBe(false) + expect(result.signal).toBeUndefined() + return result + } + const plugin = (args: string[]) => run(['plugin', '--profile', 'compatibility', ...args]) + const refused = await plugin(['add', source, '--offline', '--ignore-scripts']) + expect(refused.exitCode).toBe(1) + expect(refused.stderr).toContain('crashes or data loss') + expect(JSON.parse(readFileSync(profileFile, 'utf8'))).toEqual(initial) + expect(existsSync(join(profile, 'compatibility.json'))).toBe(false) + // The named package is checked before installation, so a refused one never lands on disk. + expect(refused.stderr).toContain('nothing was installed') + expect(existsSync(join(profile, 'node_modules', 'compatibility-fixture'))).toBe(false) + + // A package installed outside DSH still goes through the independent startup check. + cpSync(source, join(profile, 'node_modules', 'compatibility-fixture'), { recursive: true }) + writeFileSync(profileFile, JSON.stringify({ ...initial, + dependencies: { 'compatibility-fixture': `file:${source}` }, dsh: { profile: { bundles: ['compatibility-fixture'] } }, + })) + const deniedStartup = await run(['--profile', 'compatibility']) + expect(deniedStartup.stdout).not.toContain('PLUGIN_IMPORTED') + expect(deniedStartup.stderr).toContain('incompatible') + const missingConsent = await plugin(['allow-version', 'compatibility-fixture@1.0.0', '--dsh-version', version]) + expect(missingConsent.exitCode).toBe(1) + const granted = await plugin(['allow-version', 'compatibility-fixture@1.0.0', '--dsh-version', version, '--accept-risk']) + expect(granted.exitCode).toBe(0) + expect(granted.stderr).toContain('break the application or corrupt data') + // The exemption is profile metadata of its own; the dependency manifest and bundle list stay untouched. + expect(JSON.parse(readFileSync(join(profile, 'compatibility.json'), 'utf8'))).toEqual({ 'compatibility-fixture@1.0.0': [version] }) + expect(JSON.parse(readFileSync(profileFile, 'utf8'))).not.toHaveProperty('dsh.profile.versionExemptions') + expect((await plugin(['add', source, '--offline', '--ignore-scripts'])).exitCode).toBe(0) + const admittedStartup = await run(['--profile', 'compatibility']) + expect(admittedStartup.exitCode).toBe(0) + expect(admittedStartup.stdout).toContain('PLUGIN_STARTED') + expect((await plugin(['revoke-version', 'compatibility-fixture@1.0.0', '--dsh-version', version])).exitCode).toBe(0) + expect((await run(['--profile', 'compatibility'])).stdout).not.toContain('PLUGIN_IMPORTED') +}) diff --git a/apps/cli/tests/plugin.spec.ts b/apps/cli/tests/plugin.spec.ts new file mode 100644 index 0000000000..1a69b62693 --- /dev/null +++ b/apps/cli/tests/plugin.spec.ts @@ -0,0 +1,104 @@ +/** Explicit CLI exemptions use the profile lock and never become pnpm arguments. */ +import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { expect, it, onTestFinished, vi } from 'vitest' +import { getDshRuntimeVersion, readProfileVersionExemptions } from '@deepseek-ai/dsh-app-boot' +import { runPluginCommand } from '@deepseek-ai/dsh-plugin-manager/operations' +import { runPlugin } from '../src/plugin.ts' + +vi.mock('../src/profile-boot.ts', () => ({ INSTALL_ANCHOR: '/installation/package.json' })) +vi.mock('@deepseek-ai/dsh-plugin-manager/operations', async importOriginal => ({ + ...await importOriginal(), + runPluginCommand: vi.fn(), +})) + +function fixture() { + const home = mkdtempSync(join(tmpdir(), 'cli-version-exemptions-')) + vi.stubEnv('DSH_HOME', home) + const stdout = vi.spyOn(process.stdout, 'write').mockImplementation(() => true) + const stderr = vi.spyOn(process.stderr, 'write').mockImplementation(() => true) + onTestFinished(() => { + vi.restoreAllMocks() + vi.unstubAllEnvs() + vi.mocked(runPluginCommand).mockReset() + rmSync(home, { recursive: true, force: true }) + }) + return { dir: join(home, 'profiles', 'test'), stdout, stderr } +} + +it('requires explicit acknowledgement, grants only the exact pair, lists and revokes it without pnpm', async () => { + const { dir, stdout, stderr } = fixture() + const runtime = getDshRuntimeVersion() + expect(await runPlugin('test', ['allow-version', '@example/plugin@1.2.3', '--dsh-version', runtime, '--accept-risk'])).toBe(0) + expect(stderr.mock.calls.map(call => call[0]).join('')).toMatchInlineSnapshot(` + "dsh: warning: allowing incompatible plugin versions can break the application or corrupt data. Approval applies only to the exact package and DSH versions. + " + `) + expect(stderr.mock.invocationCallOrder[0]).toBeLessThan(stdout.mock.invocationCallOrder[0]!) + expect(readProfileVersionExemptions(dir)).toEqual({ '@example/plugin@1.2.3': [runtime] }) + expect(JSON.parse(readFileSync(join(dir, 'compatibility.json'), 'utf8'))).toEqual({ '@example/plugin@1.2.3': [runtime] }) + expect(await runPlugin('test', ['version-exemptions'])).toBe(0) + expect(stdout).toHaveBeenLastCalledWith(JSON.stringify({ '@example/plugin@1.2.3': [runtime] }, undefined, 2) + '\n') + expect(await runPlugin('test', ['revoke-version', '@example/plugin@1.2.3', `--dsh-version=${runtime}`])).toBe(0) + expect(readProfileVersionExemptions(dir)).toEqual({}) + expect(runPluginCommand).not.toHaveBeenCalled() +}) + +it.each([ + ['allow-version', 'plugin@1.2.3', '--dsh-version', 'CURRENT'], + ['allow-version', 'plugin@1.2.3', '--accept-risk'], + ['allow-version', 'plugin@^1.2.3', '--dsh-version', 'CURRENT', '--accept-risk'], + ['allow-version', 'plugin@1.2.3', '--dsh-version', '999.0.0', '--accept-risk'], + ['allow-version', 'plugin@1.2.3', '--dsh-version', 'CURRENT', '--accept-risk=false'], + ['allow-version', 'plugin@1.2.3', '--dsh-version', 'CURRENT', '--accept-risk', '--accept-risk'], + ['revoke-version', 'plugin@1.2.3'], + ['version-exemptions', 'extra'], +])('rejects malformed or unacknowledged exemption command %j', async (...arguments_) => { + const { dir, stderr } = fixture() + const args = arguments_.map(value => value === 'CURRENT' ? getDshRuntimeVersion() : value) + expect(await runPlugin('test', args)).toBe(1) + expect(stderr).toHaveBeenCalled() + expect(existsSync(join(dir, 'compatibility.json'))).toBe(false) + expect(runPluginCommand).not.toHaveBeenCalled() +}) + +it('uses shipped profile defaults when listing a missing profile', async () => { + fixture() + expect(await runPlugin('web', ['version-exemptions'])).toBe(0) + expect(runPluginCommand).not.toHaveBeenCalled() +}) + +it.each([0, 1])('forwards ordinary pnpm output and exit status %s', async (exitCode) => { + const { stdout, stderr } = fixture() + vi.mocked(runPluginCommand).mockImplementation(async (_context, _args, options) => { + options.onOutput?.('pnpm output', 'stdout') + return { exitCode, output: '', truncated: false, logPath: '/profile/log' } + }) + expect(await runPlugin('test', ['list'])).toBe(exitCode) + expect(stdout).toHaveBeenCalledWith('pnpm output') + if (exitCode === 0) expect(stderr).not.toHaveBeenCalled() + else expect(stderr).toHaveBeenCalledWith('dsh: plugin command failed; diagnostics: /profile/log\n') +}) + +it('names the exact grant command for each package a compatibility check refused', async () => { + const { stderr } = fixture() + vi.mocked(runPluginCommand).mockResolvedValue({ + exitCode: 1, output: '', truncated: false, logPath: '/profile/log', + incompatible: [{ name: '@example/plugin', version: '1.2.3', runtimeVersion: '0.1.0', peers: { '@deepseek-ai/dsh': '^9.0.0' } }], + }) + expect(await runPlugin('test', ['add', '@example/plugin'])).toBe(1) + expect(stderr.mock.calls.map(call => call[0])).toEqual([ + 'dsh: to accept the risk, run: dsh plugin --profile test allow-version @example/plugin@1.2.3 --dsh-version 0.1.0 --accept-risk\n', + 'dsh: plugin command failed; diagnostics: /profile/log\n', + ]) +}) + +it('forwards all other commands unchanged and retains package diagnostics', async () => { + const { stderr } = fixture() + vi.mocked(runPluginCommand).mockResolvedValue({ exitCode: 127, output: '', truncated: false, logPath: '/profile/log' }) + const args = ['add', 'github:example/plugin'] + expect(await runPlugin('test', args)).toBe(127) + expect(runPluginCommand).toHaveBeenCalledWith(expect.objectContaining({ profile: 'test' }), args, expect.objectContaining({ execution: 'cli' })) + expect(stderr.mock.calls.map(call => call[0]).join('')).toContain('pnpm was not found') +}) diff --git a/apps/cli/tests/profiles/acp/tests/fixtures/control-surface/cordis.yml b/apps/cli/tests/profiles/acp/tests/fixtures/control-surface/cordis.yml index a74e909b1b..fa96b68772 100644 --- a/apps/cli/tests/profiles/acp/tests/fixtures/control-surface/cordis.yml +++ b/apps/cli/tests/profiles/acp/tests/fixtures/control-surface/cordis.yml @@ -1,7 +1,7 @@ # Keyless generic ACP v1 control-surface patch over `dsh --profile acp`. - id: llm-deepseek - name: '@deepseek-ai/dsh-llm-deepseek' + name: '@deepseek-ai/dsh-llm-deepseek-api-key' disabled: true - id: acp diff --git a/apps/cli/tests/profiles/acp/tests/fixtures/image-offload.cordis.yml b/apps/cli/tests/profiles/acp/tests/fixtures/image-offload.cordis.yml index aec25ed875..21a9ead728 100644 --- a/apps/cli/tests/profiles/acp/tests/fixtures/image-offload.cordis.yml +++ b/apps/cli/tests/profiles/acp/tests/fixtures/image-offload.cordis.yml @@ -2,7 +2,7 @@ # local provider endpoint is supplied by the snapshot test; the real attachment # store and ACP bridge carry two uploaded images into one model request. - id: llm-deepseek - name: '@deepseek-ai/dsh-llm-deepseek' + name: '@deepseek-ai/dsh-llm-deepseek-api-key' config: apiKeyEnv: DSH_SNAPSHOT_API_KEY baseURL: !!js process.env.DSH_SNAPSHOT_BASE_URL diff --git a/apps/cli/tests/profiles/headless/credentials-snapshot.patch.yml b/apps/cli/tests/profiles/headless/credentials-snapshot.patch.yml index 79757baa74..8293d9919f 100644 --- a/apps/cli/tests/profiles/headless/credentials-snapshot.patch.yml +++ b/apps/cli/tests/profiles/headless/credentials-snapshot.patch.yml @@ -9,6 +9,9 @@ - id: llm-deepseek disabled: true +- id: llm-deepseek-account + disabled: true + - id: agent-loop config: agents: @@ -24,6 +27,6 @@ - insert: - id: llm-deepseek-keyless - name: '@deepseek-ai/dsh-llm-deepseek' + name: '@deepseek-ai/dsh-llm-deepseek-api-key' config: baseURL: 'http://127.0.0.1:9' diff --git a/apps/cli/tests/profiles/headless/tests/expected/semantic-checkpoint/session.expected.jsonl b/apps/cli/tests/profiles/headless/tests/expected/semantic-checkpoint/session.expected.jsonl index e915da38b3..3db7f52dd3 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/semantic-checkpoint/session.expected.jsonl +++ b/apps/cli/tests/profiles/headless/tests/expected/semantic-checkpoint/session.expected.jsonl @@ -1,11 +1,11 @@ -{"type":"session","version":3,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","isSeeded":false,"delegationDepth":0} +{"type":"session","version":4,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","isSeeded":false,"delegationDepth":0} {"type":"turn/start","data":{"turn":1}} {"type":"step/start","data":{"turn":1,"step":1}} -{"type":"system/message","data":{"turn":1,"step":1,"message":{"role":"system","content":[],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"} +{"type":"system/message","data":{"turn":1,"step":1,"message":{"role":"system","content":[],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"} {"type":"user/message","data":{"content":[{"type":"text","text":"Perform one side-effecting remote mutation."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} {"type":"assistant/message","data":{"turn":1,"step":1,"stream":[],"message":{"role":"assistant","content":[{"type":"tool-call","id":"unknown-outcome-call","name":"write_remote","arguments":"{\"value\":1}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"}},"surfaceOp":"append"} {"type":"tool/call","data":{"turn":1,"step":1,"callId":"unknown-outcome-call","name":"write_remote","arguments":"{\"value\":1}"}} -{"type":"tool/result","data":{"turn":1,"step":1,"message":{"id":"interrupted-tool-result-unknown-outcome-call-6","role":"user","source":{"kind":"tool","callId":"unknown-outcome-call"},"content":[{"type":"tool-result","toolCallId":"unknown-outcome-call","isError":true,"content":[{"type":"text","text":"The tool call was interrupted after it was recorded, but no result was durably recorded. Its outcome is unknown. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly."}]}]},"error":{"name":"ToolOutcomeUnknownError","code":"TOOL_OUTCOME_UNKNOWN"}},"surfaceOp":"append","sourceEventSeqs":[5]} +{"type":"tool/result","data":{"turn":1,"step":1,"message":{"id":"interrupted-tool-result-unknown-outcome-call-6","role":"tool","toolCallId":"unknown-outcome-call","isError":true,"source":{"kind":"tool","callId":"unknown-outcome-call"},"content":[{"type":"text","text":"The tool call was interrupted after it was recorded, but no result was durably recorded. Its outcome is unknown. Decide whether to retry from the tool semantics: retry only if the operation is read-only or idempotent; if it may have side effects, first verify external state or ask the user. Do not retry blindly."}]},"error":{"name":"ToolOutcomeUnknownError","code":"TOOL_OUTCOME_UNKNOWN"}},"surfaceOp":"append","sourceEventSeqs":[5]} {"type":"step/end","data":{"turn":1,"step":1}} {"type":"turn/end","data":{"turn":1,"reason":{"kind":"interrupted"}}} {"type":"session/end-seed","data":{}} @@ -16,10 +16,10 @@ {"type":"turn/start","data":{"turn":2}} {"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","data":{"turn":2,"step":1}} -{"type":"system/message","data":{"turn":2,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"sourceEventSeqs":[2],"surfaceOp":{"op":"replace","startSeq":2,"endSeq":2}} +{"type":"system/message","data":{"turn":2,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"sourceEventSeqs":[2],"surfaceOp":{"op":"replace","startSeq":2,"endSeq":2}} {"type":"user/message","data":{"content":[{"type":"text","text":"Continue safely from the interrupted operation."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} -{"type":"user/message","data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} -{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"tools":"{{tools}}"},"reason":"initial"}} +{"type":"user/message","data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"runtime-context","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} +{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"tools":"{{tools}}"},"reason":"initial","startsSeries":true}} {"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} {"type":"session/title","data":{"title":"Perform one side-effecting remote mutati","messageSeqs":[3],"source":{"kind":"fallback"}}} {"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"I will verify the external state before deciding whether to retry the side-effecting operation."}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":0,"index":0,"dt":[],"texts":["I will verify the external state before deciding whether to retry the side-effecting operation."]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"I will verify the external state before deciding whether to retry the side-effecting operation."}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"} diff --git a/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/parent.expected.jsonl b/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/parent.expected.jsonl index a359220fbb..b210549cfa 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/parent.expected.jsonl +++ b/apps/cli/tests/profiles/headless/tests/expected/subagent-diagnostic/parent.expected.jsonl @@ -1,7 +1,7 @@ -{"type":"session","version":3,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","isSeeded":false,"delegationDepth":0} +{"type":"session","version":4,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","isSeeded":false,"delegationDepth":0} {"type":"turn/start","data":{"turn":1}} {"type":"step/start","data":{"turn":1,"step":1}} -{"type":"system/message","data":{"turn":1,"step":1,"message":{"role":"system","content":[],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"} +{"type":"system/message","data":{"turn":1,"step":1,"message":{"role":"system","content":[],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"} {"type":"user/message","data":{"content":[{"type":"text","text":"Start a background job."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} {"type":"step/end","data":{"turn":1,"step":1}} {"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}} @@ -14,15 +14,15 @@ {"type":"turn/start","data":{"turn":2}} {"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","data":{"turn":2,"step":1}} -{"type":"system/message","data":{"turn":2,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"sourceEventSeqs":[2],"surfaceOp":{"op":"replace","startSeq":2,"endSeq":2}} +{"type":"system/message","data":{"turn":2,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"sourceEventSeqs":[2],"surfaceOp":{"op":"replace","startSeq":2,"endSeq":2}} {"type":"user/message","data":{"content":[{"type":"text","text":"Call list_agents once and report what it shows."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} -{"type":"user/message","data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} -{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"tools":"{{tools}}"},"reason":"initial"}} +{"type":"user/message","data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"runtime-context","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} +{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"tools":"{{tools}}"},"reason":"initial","startsSeries":true}} {"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} {"type":"session/title","data":{"title":"Start a background job.","messageSeqs":[3],"source":{"kind":"fallback"}}} {"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"list-once","name":"list_agents","arguments":"{}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":0,"index":0,"dt":[],"id":"list-once","name":"list_agents","args":["{}"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"list-once","name":"list_agents","arguments":"{}"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"} {"type":"tool/call","data":{"turn":2,"step":1,"callId":"list-once","name":"list_agents","arguments":"{}"}} -{"type":"tool/result","data":{"turn":2,"step":1,"message":{"source":{"kind":"tool","callId":"list-once"},"content":[{"type":"tool-result","toolCallId":"list-once","content":[{"type":"text","text":"{{sessionId}} [inactive] — descriptorless child"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[22],"surfaceOp":"append"} +{"type":"tool/result","data":{"turn":2,"step":1,"message":{"role":"tool","source":{"kind":"tool","callId":"list-once"},"toolCallId":"list-once","content":[{"type":"text","text":"{{sessionId}} [inactive] — descriptorless child"}],"isError":false,"id":"{{sessionId}}"}},"sourceEventSeqs":[22],"surfaceOp":"append"} {"type":"step/end","data":{"turn":2,"step":1}} {"type":"step/start","data":{"turn":2,"step":2}} {"type":"assistant/message","data":{"turn":2,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"The catalogued subagent is ready. PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":0,"index":0,"dt":[],"texts":["The catalogued subagent is ready. PARENT_DONE"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"The catalogued subagent is ready. PARENT_DONE"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"} diff --git a/apps/cli/tests/profiles/headless/tests/expected/subagent-inheritance/parent.expected.jsonl b/apps/cli/tests/profiles/headless/tests/expected/subagent-inheritance/parent.expected.jsonl index 44d31a36ab..f4077c4510 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/subagent-inheritance/parent.expected.jsonl +++ b/apps/cli/tests/profiles/headless/tests/expected/subagent-inheritance/parent.expected.jsonl @@ -1,7 +1,7 @@ -{"type":"session","version":3,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","isSeeded":false,"delegationDepth":0} +{"type":"session","version":4,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","isSeeded":false,"delegationDepth":0} {"type":"turn/start","data":{"turn":1}} {"type":"step/start","data":{"turn":1,"step":1}} -{"type":"system/message","data":{"turn":1,"step":1,"message":{"role":"system","content":[],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"} +{"type":"system/message","data":{"turn":1,"step":1,"message":{"role":"system","content":[],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"} {"type":"user/message","data":{"content":[{"type":"text","text":"Tighten this session to read-only."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} {"type":"sandbox/mode","data":{"mode":"read-only"}} {"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash","reasoningEffort":"low"}},"reason":"initial"}} @@ -14,16 +14,17 @@ {"type":"turn/start","data":{"turn":2}} {"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","data":{"turn":2,"step":1}} -{"type":"system/message","data":{"turn":2,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"sourceEventSeqs":[2],"surfaceOp":{"op":"replace","startSeq":2,"endSeq":2}} +{"type":"system/message","data":{"turn":2,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"sourceEventSeqs":[2],"surfaceOp":{"op":"replace","startSeq":2,"endSeq":2}} {"type":"user/message","data":{"content":[{"type":"text","text":"Delegate the write probe to a subagent."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} -{"type":"user/message","data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} -{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash","reasoningEffort":"low"},"tools":"{{tools}}"},"reason":"resume"}} +{"type":"user/message","data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"runtime-context","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} +{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash","reasoningEffort":"low"},"tools":["bash","create_goal","edit","exit_plan_mode","get_goal","glob","grep","interrupt_agent","job_kill","job_list","job_output","list_agents","read","read_image","send_message","skill","subagent","subagent_fork","todo_write","update_goal","web_fetch","web_search","workflow","write"]},"reason":"resume","startsSeries":true}} +{"type":"developer/message","data":{"turn":2,"step":1,"message":{"source":{"kind":"tool-registry"},"content":[{"type":"tool-addition","toolName":"bash"},{"type":"tool-addition","toolName":"create_goal"},{"type":"tool-addition","toolName":"edit"},{"type":"tool-addition","toolName":"exit_plan_mode"},{"type":"tool-addition","toolName":"get_goal"},{"type":"tool-addition","toolName":"glob"},{"type":"tool-addition","toolName":"grep"},{"type":"tool-addition","toolName":"interrupt_agent"},{"type":"tool-addition","toolName":"job_kill"},{"type":"tool-addition","toolName":"job_list"},{"type":"tool-addition","toolName":"job_output"},{"type":"tool-addition","toolName":"list_agents"},{"type":"tool-addition","toolName":"read"},{"type":"tool-addition","toolName":"read_image"},{"type":"tool-addition","toolName":"send_message"},{"type":"tool-addition","toolName":"skill"},{"type":"tool-addition","toolName":"subagent"},{"type":"tool-addition","toolName":"subagent_fork"},{"type":"tool-addition","toolName":"todo_write"},{"type":"tool-addition","toolName":"update_goal"},{"type":"tool-addition","toolName":"web_fetch"},{"type":"tool-addition","toolName":"web_search"},{"type":"tool-addition","toolName":"workflow"},{"type":"tool-addition","toolName":"write"}],"role":"developer","id":"{{sessionId}}"},"headerSeq":18},"surfaceOp":"append"} {"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} {"type":"session/title","data":{"title":"Tighten this session to read-only.","messageSeqs":[3],"source":{"kind":"fallback"}}} {"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"delegate-write","name":"subagent","arguments":"{\"description\": \"Delegated write probe\", \"prompt\": \"Use the write tool exactly once with file_path set to exactly the relative path inherited.txt and content escaped. If the write is denied, reply with the single word CHILD_DENIED and the denial marker line; do not retry and do not request escalation. If it succeeds, reply CHILD_WROTE.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":0,"index":0,"dt":[],"id":"delegate-write","name":"subagent","args":["{\"description\": \"Delegated write probe\", \"prompt\": \"Use the write tool exactly once with file_path set to exactly the relative path inherited.txt and content escaped. If the write is denied, reply with the single word CHILD_DENIED and the denial marker line; do not retry and do not request escalation. If it succeeds, reply CHILD_WROTE.\"}"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"delegate-write","name":"subagent","arguments":"{\"description\": \"Delegated write probe\", \"prompt\": \"Use the write tool exactly once with file_path set to exactly the relative path inherited.txt and content escaped. If the write is denied, reply with the single word CHILD_DENIED and the denial marker line; do not retry and do not request escalation. If it succeeds, reply CHILD_WROTE.\"}"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"} {"type":"tool/call","data":{"turn":2,"step":1,"callId":"delegate-write","name":"subagent","arguments":"{\"description\": \"Delegated write probe\", \"prompt\": \"Use the write tool exactly once with file_path set to exactly the relative path inherited.txt and content escaped. If the write is denied, reply with the single word CHILD_DENIED and the denial marker line; do not retry and do not request escalation. If it succeeds, reply CHILD_WROTE.\"}"}} {"type":"subagent/catalog","data":{"version":0,"childId":"{{sessionId}}","childCreatedAt":0,"mode":"one-shot","label":"Delegated write probe"}} -{"type":"tool/result","data":{"turn":2,"step":1,"message":{"source":{"kind":"tool","callId":"delegate-write"},"content":[{"type":"tool-result","toolCallId":"delegate-write","content":[{"type":"text","text":"CHILD_DENIED [sandbox: file access denied under read-only mode]"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[22],"surfaceOp":"append"} +{"type":"tool/result","data":{"turn":2,"step":1,"message":{"role":"tool","source":{"kind":"tool","callId":"delegate-write"},"toolCallId":"delegate-write","content":[{"type":"text","text":"CHILD_DENIED [sandbox: file access denied under read-only mode]"}],"isError":false,"id":"{{sessionId}}"}},"sourceEventSeqs":[23],"surfaceOp":"append"} {"type":"step/end","data":{"turn":2,"step":1}} {"type":"step/start","data":{"turn":2,"step":2}} {"type":"assistant/message","data":{"turn":2,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"The delegated child was denied by the sandbox. PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":0,"index":0,"dt":[],"texts":["The delegated child was denied by the sandbox. PARENT_DONE"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"The delegated child was denied by the sandbox. PARENT_DONE"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"} diff --git a/apps/cli/tests/profiles/headless/tests/expected/workspace-context-resume/offline-edit/session.expected.jsonl b/apps/cli/tests/profiles/headless/tests/expected/workspace-context-resume/offline-edit/session.expected.jsonl index 4e2b7ae5a5..7dc7407bff 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/workspace-context-resume/offline-edit/session.expected.jsonl +++ b/apps/cli/tests/profiles/headless/tests/expected/workspace-context-resume/offline-edit/session.expected.jsonl @@ -1,7 +1,7 @@ -{"type":"session","version":3,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","isSeeded":false,"delegationDepth":0} +{"type":"session","version":4,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","isSeeded":false,"delegationDepth":0} {"type":"turn/start","data":{"turn":1}} {"type":"step/start","data":{"turn":1,"step":1}} -{"type":"system/message","data":{"turn":1,"step":1,"message":{"role":"system","content":[],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"} +{"type":"system/message","data":{"turn":1,"step":1,"message":{"role":"system","content":[],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"} {"type":"user/message","data":{"content":[{"type":"text","text":"Remember the workspace instruction."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} {"type":"user/message","data":{"content":[{"type":"text","text":"\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nOld workspace instruction.\n"}],"source":{"kind":"agent-instructions","form":"instructions","baseline":true,"baselineIdentity":"{\"projectRoot\":\"\",\"projectRootMarkers\":[\".git\"],\"maxBytes\":65536,\"maxSourceBytes\":1048576,\"instructionFileCandidates\":[\"AGENTS.md\",\"CLAUDE.md\"],\"localInstructionFileCandidates\":[\"AGENTS.local.md\",\"CLAUDE.local.md\"]}","changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"ba65bdb41810f4d0129129dcbd6cadcd643c069d"}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} {"type":"step/end","data":{"turn":1,"step":1}} @@ -14,11 +14,11 @@ {"type":"turn/start","data":{"turn":2}} {"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","data":{"turn":2,"step":1}} -{"type":"system/message","data":{"turn":2,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"sourceEventSeqs":[2],"surfaceOp":{"op":"replace","startSeq":2,"endSeq":2}} +{"type":"system/message","data":{"turn":2,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"sourceEventSeqs":[2],"surfaceOp":{"op":"replace","startSeq":2,"endSeq":2}} {"type":"user/message","data":{"content":[{"type":"text","text":"Acknowledge the current workspace instruction."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} {"type":"user/message","data":{"content":[{"type":"text","text":"\nUpdated instructions from: AGENTS.md\n\nThis file changed after it was loaded. Use the following content instead of the previously loaded instructions from this file.\n\nNew workspace instruction after offline edit.\n\n"}],"source":{"kind":"agent-instructions","form":"instructions","changes":[{"action":"replace","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"d8375b516f158718bd3463bc8eb7ed42c011b29f"}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} -{"type":"user/message","data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} -{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"tools":"{{tools}}"},"reason":"initial"}} +{"type":"user/message","data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"runtime-context","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} +{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"tools":"{{tools}}"},"reason":"initial","startsSeries":true}} {"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} {"type":"session/title","data":{"title":"Remember the workspace instruction.","messageSeqs":[3],"source":{"kind":"fallback"}}} {"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"RESUME_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":0,"index":0,"dt":[],"texts":["RESUME_DONE"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"RESUME_DONE"}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"} diff --git a/apps/cli/tests/profiles/headless/tests/expected/workspace-context-resume/precedence-change/session.expected.jsonl b/apps/cli/tests/profiles/headless/tests/expected/workspace-context-resume/precedence-change/session.expected.jsonl index 71d92dd690..76af22df23 100644 --- a/apps/cli/tests/profiles/headless/tests/expected/workspace-context-resume/precedence-change/session.expected.jsonl +++ b/apps/cli/tests/profiles/headless/tests/expected/workspace-context-resume/precedence-change/session.expected.jsonl @@ -1,7 +1,7 @@ -{"type":"session","version":3,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","isSeeded":false,"delegationDepth":0} +{"type":"session","version":4,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","isSeeded":false,"delegationDepth":0} {"type":"turn/start","data":{"turn":1}} {"type":"step/start","data":{"turn":1,"step":1}} -{"type":"system/message","data":{"turn":1,"step":1,"message":{"role":"system","content":[],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"} +{"type":"system/message","data":{"turn":1,"step":1,"message":{"role":"system","content":[],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"surfaceOp":"append"} {"type":"user/message","data":{"content":[{"type":"text","text":"Remember the workspace instruction."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} {"type":"user/message","data":{"content":[{"type":"text","text":"\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: CLAUDE.md\n\nOld CLAUDE rule.\n\nInstructions from: AGENTS.md\n\nOld AGENTS rule.\n"}],"source":{"kind":"agent-instructions","form":"instructions","baseline":true,"baselineIdentity":"{\"projectRoot\":\"\",\"projectRootMarkers\":[\".git\"],\"maxBytes\":65536,\"maxSourceBytes\":1048576,\"instructionFileCandidates\":[\"CLAUDE.md\",\"AGENTS.md\"],\"localInstructionFileCandidates\":[\"AGENTS.local.md\",\"CLAUDE.local.md\"]}","changes":[{"action":"set","scope":".\u0000CLAUDE.md","path":"CLAUDE.md","digest":"b525eb8a6d3660b732dad4b0aff1b7c63ab32890"},{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"3113bd093ae91976207dcef7390bdc0b2bfcfa10"}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} {"type":"step/end","data":{"turn":1,"step":1}} @@ -14,11 +14,11 @@ {"type":"turn/start","data":{"turn":2}} {"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","data":{"turn":2,"step":1}} -{"type":"system/message","data":{"turn":2,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"{{sessionId}}"}},"sourceEventSeqs":[2],"surfaceOp":{"op":"replace","startSeq":2,"endSeq":2}} +{"type":"system/message","data":{"turn":2,"step":1,"message":{"role":"system","content":[{"type":"text","text":"{{system}}"}],"source":{"kind":"system-prompt"},"id":"{{sessionId}}"}},"sourceEventSeqs":[2],"surfaceOp":{"op":"replace","startSeq":2,"endSeq":2}} {"type":"user/message","data":{"content":[{"type":"text","text":"Acknowledge the current workspace instruction."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} {"type":"user/message","data":{"content":[{"type":"text","text":"\nThis complete workspace instruction baseline replaces all earlier workspace instruction baselines. The following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nCurrent AGENTS rule.\n\n\nInstructions from: CLAUDE.md\n\nCurrent CLAUDE rule.\n\n"}],"source":{"kind":"agent-instructions","form":"instructions","baseline":true,"baselineIdentity":"{\"projectRoot\":\"\",\"projectRootMarkers\":[\".git\"],\"maxBytes\":65536,\"maxSourceBytes\":1048576,\"instructionFileCandidates\":[\"AGENTS.md\",\"CLAUDE.md\"],\"localInstructionFileCandidates\":[\"AGENTS.local.md\",\"CLAUDE.local.md\"]}","changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"7f53d2327837129750aef117f9754a001c46cf68"},{"action":"set","scope":".\u0000CLAUDE.md","path":"CLAUDE.md","digest":"5b1e9e3fd759eee6b43ceff899e47fb10c64701a"}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} -{"type":"user/message","data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} -{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"tools":"{{tools}}"},"reason":"initial"}} +{"type":"user/message","data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"runtime-context","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: workspace-write. Any available operation enforced by the DSH file sandbox may modify files under the session workspace: \"{{cwd}}\". Some platform temporary areas may also be writable."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} +{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"tools":"{{tools}}"},"reason":"initial","startsSeries":true}} {"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} {"type":"session/title","data":{"title":"Remember the workspace instruction.","messageSeqs":[3],"source":{"kind":"fallback"}}} {"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"RESUME_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":0,"index":0,"dt":[],"texts":["RESUME_DONE"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"RESUME_DONE"}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"} diff --git a/apps/cli/tests/profiles/headless/tests/harness.ts b/apps/cli/tests/profiles/headless/tests/harness.ts index 9c17fa27f4..c07b4b73fd 100644 --- a/apps/cli/tests/profiles/headless/tests/harness.ts +++ b/apps/cli/tests/profiles/headless/tests/harness.ts @@ -8,7 +8,7 @@ import * as BashEnvPlugin from '@deepseek-ai/dsh-shell-env' import LocalSubprocessRuntime from '@deepseek-ai/dsh-subprocess-local' import * as ToolBash from '@deepseek-ai/dsh-tool-bash' import * as ToolTodo from '@deepseek-ai/dsh-tool-todo' -import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek' +import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek-api-key' import TokenMeter from '@deepseek-ai/dsh-token-meter' import ToolResultPruner from '@deepseek-ai/dsh-compaction-tool-result-pruner' import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' diff --git a/apps/cli/tests/profiles/headless/tests/ptc.e2e.ts b/apps/cli/tests/profiles/headless/tests/ptc.e2e.ts index 4e0fc43235..ba55c91d16 100644 --- a/apps/cli/tests/profiles/headless/tests/ptc.e2e.ts +++ b/apps/cli/tests/profiles/headless/tests/ptc.e2e.ts @@ -17,7 +17,7 @@ import { LocalBashExecutor } from '@deepseek-ai/dsh-bash-local' import * as BashEnvPlugin from '@deepseek-ai/dsh-shell-env' import LocalSubprocessRuntime from '@deepseek-ai/dsh-subprocess-local' import * as ToolBash from '@deepseek-ai/dsh-tool-bash' -import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek' +import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek-api-key' import NodeRuntime from '@deepseek-ai/dsh-ptc-runtime-node' import Sandbox from '@deepseek-ai/dsh-sandbox-local' import SandboxPolicy from '@deepseek-ai/dsh-sandbox-policy' diff --git a/apps/cli/tests/profiles/sdk/dynamic-tool-cache.e2e.ts b/apps/cli/tests/profiles/sdk/dynamic-tool-cache.e2e.ts new file mode 100644 index 0000000000..e90f5b4b54 --- /dev/null +++ b/apps/cli/tests/profiles/sdk/dynamic-tool-cache.e2e.ts @@ -0,0 +1,121 @@ +/** Real provider cache usage across registry additions through the built SDK profile. */ +import { randomUUID } from 'node:crypto' +import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { fileURLToPath } from 'node:url' +import type { TokenUsage } from '@deepseek-ai/dsh-llm' +import { DeepSeekHarness } from '@deepseek-ai/dsh-sdk-client' +import type { SessionEvent } from '@deepseek-ai/dsh-session' +import { describe, expect, it, onTestFinished } from 'vitest' + +const fixturePath = fileURLToPath(new URL('./fixtures/dynamic-tool-cache.mjs', import.meta.url)) +const dshBin = fileURLToPath(new URL('../../../lib/bin.js', import.meta.url)) +const sampleTool = 'cache_sample' +const sampleLabelGuidance = 'Place each generated sample label on its own line.' +// Provider cache blocks may leave a short uncached suffix of an unchanged request. +const cacheSuffixTokens = 256 + +interface ObservedRequest { + stage: 'initial' | 'added' | 'removed' + turn: number + step: number + body: { + system?: string + messages: { role: string; content: { type: string; text?: string; tool?: { name: string } }[] }[] + tools?: { name: string; defer_loading?: true }[] + } +} + +function usageFor(request: ObservedRequest, events: SessionEvent[]): TokenUsage { + const settled = events.find(event => event.type === 'assistant/message' + && event.data.turn === request.turn && event.data.step === request.step) + if (settled?.type !== 'assistant/message' || settled.data.usage === undefined) { + throw new Error(`Missing provider usage for turn ${request.turn}, step ${request.step}`) + } + return settled.data.usage +} + +function totalInput(usage: TokenUsage): number { + return usage.inputTokens + (usage.cacheReadTokens ?? 0) + (usage.cacheWriteTokens ?? 0) +} + +describe.skipIf(!process.env.DEEPSEEK_API_KEY)('SDK native tool updates with real DeepSeek', () => { + it.each([false, true])('keeps the preceding conversation cached after a tool addition (prompt update: %s)', { retry: 0 }, async (updatePrompt) => { + const root = await mkdtemp(join(tmpdir(), 'dsh-sdk-tool-cache-')) + onTestFinished(async () => { await rm(root, { recursive: true, force: true }) }) + const sampleLabel = `CACHE_SAMPLE_${randomUUID()}` + const evidencePath = join(root, 'requests.jsonl') + const callsPath = join(root, 'calls.txt') + const patch = join(root, 'dynamic-tool-cache.patch.yml') + await writeFile(patch, JSON.stringify([ + { id: 'llm-deepseek', config: { + apiKeyEnv: 'DEEPSEEK_API_KEY', thinking: 'disabled', maxTokens: 1024, + retryPolicy: { maxRetries: 0 }, + models: [{ id: 'deepseek-flash', systemPromptUpdate: 'in-history', toolUpdate: 'addition-only' }], + } }, + { id: 'tools', config: { mode: 'native' } }, + { id: 'session-log-deepseek', disabled: true }, + { id: 'plugin-package-inventory-deepseek', disabled: true }, + { insert: [{ id: 'sdk-dynamic-tool-cache-fixture', name: fixturePath, config: { evidencePath, callsPath, sampleLabel, updatePrompt } }] }, + ])) + const harness = new DeepSeekHarness({ + dshBin, profile: 'sdk', patches: [patch], dshHome: join(root, 'home'), + cwd: root, processCwd: root, provider: 'deepseek-official', model: 'deepseek-flash', + env: { ...process.env, DSH_TELEMETRY_DISABLED: '1', DSH_PERMISSION_MODE: 'danger-full-access' }, + initializeTimeoutMs: 30_000, + }) + onTestFinished(async () => { await harness.close() }) + await harness.start() + const session = harness.session() + const events: SessionEvent[] = [] + const run = async (prompt: string) => { + const result = await session.run(prompt) + events.push(...result.events) + return result.finalResponse + } + await run('Do not call tools. Reply READY.') + // Unique user history makes hits on shared profile instructions insufficient. + const records = Array.from({ length: 96 }, (_, index) => `record-${index}: ${randomUUID()}`).join('\n') + await run(`Keep these reference records. Do not call tools. Reply READY.\n${records}`) + await run('Keep the reference records. Do not call tools. Reply READY.') + expect(await run(`Use cache_tool_control with action add. After it returns, call ${sampleTool} exactly once and report the generated sample label. This is synthetic example data for this run. Call these separately in order.`)).toContain(sampleLabel) + expect(await readFile(callsPath, 'utf8')).toBe('add\nsample\n') + expect(await run('Use cache_tool_control with action remove. After it returns, reply REMOVED and do not call the sample tool.')).toContain('REMOVED') + expect(await readFile(callsPath, 'utf8')).toBe('add\nsample\nremove\n') + + const requests = (await readFile(evidencePath, 'utf8')).trim().split('\n').map(line => JSON.parse(line) as ObservedRequest) + expect(events.filter(event => event.type === 'assistant/attempt')).toHaveLength(0) + expect(requests).toHaveLength(events.filter(event => event.type === 'assistant/message').length) + const [initial, history, warm] = requests + const addedIndex = requests.findIndex(request => request.stage === 'added') + const before = requests[addedIndex - 1] + const added = requests[addedIndex] + const removed = requests.find(request => request.stage === 'removed') + if (!initial || !history || !warm || !before || !added || !removed) throw new Error('Missing cache transition requests') + const historyInput = totalInput(usageFor(history, events)) + const precedingInput = totalInput(usageFor(before, events)) + const cached = usageFor(added, events).cacheReadTokens ?? 0 + process.stdout.write(`SDK tool addition cache: ${JSON.stringify({ updatePrompt, historyInput, precedingInput, cached, deficit: precedingInput - cached, removedCached: usageFor(removed, events).cacheReadTokens })}\n`) + expect(historyInput - totalInput(usageFor(initial, events))).toBeGreaterThan(1024) + expect(usageFor(warm, events).cacheReadTokens ?? 0).toBeGreaterThanOrEqual(historyInput - cacheSuffixTokens) + expect(added.turn).toBe(before.turn) + expect(added.step).toBe(before.step + 1) + expect(before.body.system).toBe(initial.body.system) + expect(added.body.system).toBe(initial.body.system) + expect(added.body.messages.slice(0, before.body.messages.length)).toEqual(before.body.messages) + expect(added.body.messages.some(message => message.role === 'system' + && message.content.some(block => block.type === 'text' && block.text?.includes(sampleLabelGuidance)))).toBe(updatePrompt) + expect(cached, 'the first post-addition request must reuse the preceding conversation input').toBeGreaterThanOrEqual(precedingInput - cacheSuffixTokens) + expect(initial.body.tools?.map(tool => tool.name)).toEqual(['cache_tool_control']) + expect(added.body.tools?.slice(0, initial.body.tools?.length)).toEqual(initial.body.tools) + expect(added.body.tools?.find(tool => tool.name === sampleTool)).toMatchObject({ name: sampleTool, defer_loading: true }) + expect(added.body.messages.flatMap(message => message.content)).toContainEqual({ type: 'tool_addition', tool: { type: 'tool_reference', name: sampleTool } }) + expect(removed.body.tools?.map(tool => tool.name)).toEqual(['cache_tool_control']) + expect(removed.body.messages.flatMap(message => message.content).some(block => block.type === 'tool_addition')).toBe(false) + expect(events.filter(event => event.type === 'developer/message').map(event => event.data.message.content)).toEqual([ + [{ type: 'tool-addition', toolName: sampleTool }], + [{ type: 'tool-removal', toolName: sampleTool }], + ]) + }) +}) diff --git a/apps/cli/tests/profiles/sdk/fixtures/dynamic-tool-cache.mjs b/apps/cli/tests/profiles/sdk/fixtures/dynamic-tool-cache.mjs new file mode 100644 index 0000000000..d01a204673 --- /dev/null +++ b/apps/cli/tests/profiles/sdk/fixtures/dynamic-tool-cache.mjs @@ -0,0 +1,68 @@ +/** SDK fixture for native registry changes and unmodified DeepSeek request observation. */ +import { appendFile } from 'node:fs/promises' +import { defineTool } from '@deepseek-ai/dsh-tools' + +export const name = 'sdk-dynamic-tool-cache-fixture' +export const inject = ['tools', 'systemPrompt', 'deepseekLlmApiExtensions'] + +/** Observe each request and let the model add or remove a scoped tool. */ +export function apply(ctx, config) { + const states = new Map() + ctx.on('session/event', (session, event) => { + const state = states.get(session.id) + if (state !== undefined && event.type === 'step/start') { + state.turn = event.data.turn + state.step = event.data.step + } + }) + ctx.effect(() => ctx.deepseekLlmApiExtensions.register('dynamic_tool_cache_observer', { + async prepare(request) { + if (request.purpose !== undefined) return undefined + const state = states.get(request.sessionId) + if (state === undefined) throw new Error('The SDK request has no observed agent.') + await appendFile(config.evidencePath, `${JSON.stringify({ ...state, body: request.body })}\n`) + return undefined + }, + })) + ctx.on('agent/created', ({ agent }) => { + const scope = agent.ctx + const state = { stage: 'initial', turn: 0, step: 0 } + states.set(agent.id, state) + scope.effect(() => () => { states.delete(agent.id) }) + scope.effect(() => scope.tools.restrict({ allow: [] })) + let guidance = '' + scope.systemPrompt.section({ name: 'sdk:dynamic-tool-guidance', order: 400, text: () => guidance }) + let removeTool + scope.effect(() => scope.tools.register(defineTool({ + name: 'cache_tool_control', + description: 'Add or remove the temporary cache_sample tool. It becomes available on the model step after add returns.', + parameters: { action: { type: 'string', enum: ['add', 'remove'], required: true } }, + output: { schema: { type: 'string' }, render: (_args, value) => [{ type: 'text', text: value }] }, + async execute({ action }) { + if (action === 'add') { + if (removeTool !== undefined) throw new Error('The sample tool is already registered.') + if (config.updatePrompt) guidance = 'Place each generated sample label on its own line.' + removeTool = scope.effect(() => scope.tools.register(defineTool({ + name: 'cache_sample', + description: 'Read a randomly generated sample label created for this example run.', + parameters: {}, + output: { schema: { type: 'string' }, render: (_args, value) => [{ type: 'text', text: value }] }, + async execute() { + await appendFile(config.callsPath, 'sample\n') + return config.sampleLabel + }, + }))) + state.stage = 'added' + await appendFile(config.callsPath, 'add\n') + return 'Tool added. Call cache_sample on the next model step to obtain the generated sample label.' + } + if (removeTool === undefined) throw new Error('The sample tool is not registered.') + await removeTool() + removeTool = undefined + state.stage = 'removed' + await appendFile(config.callsPath, 'remove\n') + return 'Tool removed. The sample tool is unavailable.' + }, + }))) + }) +} diff --git a/apps/cli/tests/profiles/sdk/office-cli.e2e.ts b/apps/cli/tests/profiles/sdk/office-cli.e2e.ts index 359e559241..cc851efd23 100644 --- a/apps/cli/tests/profiles/sdk/office-cli.e2e.ts +++ b/apps/cli/tests/profiles/sdk/office-cli.e2e.ts @@ -108,7 +108,7 @@ it.skipIf(!process.env.DEEPSEEK_API_KEY || process.platform === 'win32')(`agent expect(existsSync(decoyMarker), 'the agent must not invoke system Office when the bundled CLI is supplied').toBe(false) expect(commandText, 'the skill supplies an entry; searching for other Office binaries is unnecessary').not.toMatch(/(?:which|whereis|command -v|find).{0,100}(?:libreoffice|soffice)/iu) const capabilities = JSON.parse(await readFile(join(root, 'capabilities.json'), 'utf8')) as { runtime: { version: string; cliPath: string } } - expect(capabilities.runtime.version).toBe('0.1.0') + expect(capabilities.runtime.version).toBe('0.1.1') expect(capabilities.runtime.cliPath).toMatch(/lib[/\\]cli\.js$/u) const pdf = await readFile(join(root, 'result.pdf')) expect(pdf.subarray(0, 5).toString()).toBe('%PDF-') diff --git a/apps/cli/tests/profiles/web/tests/default-web-process.ts b/apps/cli/tests/profiles/web/tests/default-web-process.ts index 341a97e4c7..537ac77702 100644 --- a/apps/cli/tests/profiles/web/tests/default-web-process.ts +++ b/apps/cli/tests/profiles/web/tests/default-web-process.ts @@ -5,7 +5,7 @@ import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' -import { get } from 'node:http' +import { request as httpRequest } from 'node:http' import type { IncomingHttpHeaders } from 'node:http' import { resolveExampleLaunch } from '@deepseek-ai/dsh-loader-smoke' import ts from 'typescript' @@ -18,6 +18,7 @@ const repoRoot = fileURLToPath(new URL('../../../../../../', import.meta.url)) /** Live process whose IPC observer reports independently collected runtime state. */ interface DefaultWeb { + root: string url: string request: (command: 'roster' | 'mount-experimental' | 'mount-experimental-entry') => Promise } @@ -26,13 +27,19 @@ interface DefaultWeb { * Boot the built Web profile under plain Node and dispose it to quiescence after an assertion callback. * @param test - owning Vitest case, including its timeout, cancellation, and cleanup hooks. * @param inspect - assertions against the running process and its ephemeral loopback URL. + * @param options - additional profile patches and test data prepared before startup. */ -export async function withDefaultWeb(test: TestContext, inspect: (app: DefaultWeb) => Promise): Promise { +export async function withDefaultWeb( + test: TestContext, + inspect: (app: DefaultWeb) => Promise, + options: { patches?: readonly string[]; prepare?: (root: string) => Promise } = {}, +): Promise { const root = await mkdtemp(join(tmpdir(), 'dsh-web-default-isolation-')) let removal: Promise | undefined const removeRoot = (): Promise => removal ??= rm(root, { recursive: true, force: true }) test.onTestFinished(removeRoot) try { + await options.prepare?.(root) await writeFile(join(root, 'package.json'), JSON.stringify({ type: 'module' }) + '\n') for (const relative of ['runtime-roster.ts', 'fixtures/runtime-roster-observer.ts']) { const source = await readFile(new URL(relative, import.meta.url), 'utf8') @@ -53,7 +60,10 @@ export async function withDefaultWeb(test: TestContext, inspect: (app: DefaultWe const launch = resolveExampleLaunch({ srcBin: join(repoRoot, 'apps/cli/src/bin.ts'), mode: 'lib', - configArgs: ['--profile', 'web', '--patch', patch, '--host', '127.0.0.1', '--port', '0', '--no-open'], + configArgs: [ + '--profile', 'web', ...options.patches?.flatMap(path => ['--patch', path]) ?? [], + '--patch', patch, '--host', '127.0.0.1', '--port', '0', '--no-open', + ], env: { NODE_OPTIONS: undefined, NODE_PATH: undefined, @@ -145,7 +155,7 @@ export async function withDefaultWeb(test: TestContext, inspect: (app: DefaultWe return /dsh web: (http:\/\/[^\s]+)/u.exec(stdout)?.[1] }, { timeout: test.task.timeout }).toBeDefined() const url = /dsh web: (http:\/\/[^\s]+)/u.exec(stdout)![1]! - await inspect({ url, request }) + await inspect({ root, url, request }) } finally { const result = await close() test.signal.removeEventListener('abort', abort) @@ -167,13 +177,26 @@ export async function withDefaultWeb(test: TestContext, inspect: (app: DefaultWe * @param headers - optional authentication cookie. * @returns complete response after its stream ends. */ -export function webGet(url: string | URL, signal: AbortSignal, headers: Record = {}): Promise<{ - status: number | undefined - headers: IncomingHttpHeaders - text: string -}> { +export function webGet( + url: string | URL, signal: AbortSignal, headers: Record = {}, +): ReturnType { + return webRequest(url, signal, { method: 'GET', headers }) +} + +/** + * Send one public-protocol request directly to the test-owned loopback process. + * @param url - Exact URL of the owned process. + * @param signal - Owning test cancellation signal. + * @param options - HTTP method, headers, and optional serialized request body. + * @returns Complete response after its stream ends. + */ +export function webRequest( + url: string | URL, + signal: AbortSignal, + options: { method: 'GET' | 'POST'; headers?: Record; body?: string }, +): Promise<{ status: number | undefined; headers: IncomingHttpHeaders; text: string }> { return new Promise((resolve, reject) => { - const request = get(url, { headers, agent: false, signal }, (response) => { + const request = httpRequest(url, { method: options.method, headers: options.headers, agent: false, signal }, (response) => { response.setEncoding('utf8') let text = '' response.on('data', (chunk: string) => { text += chunk }) @@ -181,5 +204,6 @@ export function webGet(url: string | URL, signal: AbortSignal, headers: Record { resolve({ status: response.statusCode, headers: response.headers, text }) }) }) request.once('error', reject) + request.end(options.body) }) } diff --git a/apps/cli/tests/profiles/web/tests/fixtures/schedule.patch.yml b/apps/cli/tests/profiles/web/tests/fixtures/schedule.patch.yml new file mode 100644 index 0000000000..fd53f05e15 --- /dev/null +++ b/apps/cli/tests/profiles/web/tests/fixtures/schedule.patch.yml @@ -0,0 +1,2 @@ +- id: schedule + disabled: false diff --git a/apps/cli/tests/profiles/web/tests/schedule-timing.expected.e2e.ts b/apps/cli/tests/profiles/web/tests/schedule-timing.expected.e2e.ts new file mode 100644 index 0000000000..0cf380636f --- /dev/null +++ b/apps/cli/tests/profiles/web/tests/schedule-timing.expected.e2e.ts @@ -0,0 +1,121 @@ +/** Built CLI, public Remote requests, and persisted task files; seeded receipts are not delivery evidence. */ + +import { randomUUID } from 'node:crypto' +import { mkdir, readFile, writeFile } from 'node:fs/promises' +import { join } from 'node:path' +import { fileURLToPath } from 'node:url' +import type { DailyScheduleRecord, ScheduleCatalogEntry } from '@deepseek-ai/dsh-schedule' +import { expect, it } from 'vitest' +import { withDefaultWeb, webGet, webRequest } from './default-web-process.ts' + +const patches = [fileURLToPath(new URL('./fixtures/schedule.patch.yml', import.meta.url))] + +const id = 'retained-remote-task' as DailyScheduleRecord['id'] +const sessionId = 'unloaded-owner' as ScheduleCatalogEntry['sessionId'] +const record: DailyScheduleRecord = { + id, kind: 'daily', title: 'Retained instruction', prompt: 'Retained instruction\nwith a second line', + time: '09:00:00.125', timeZone: 'Asia/Shanghai', scheduledAt: '2099-01-01T01:00:00.125Z', +} +const lastDelivery = { + scheduledAt: '2026-01-01T01:00:00.125Z', deliveredAt: '2026-01-01T01:00:01.250Z', messageId: 'saved-receipt', +} +const task = { + sessionId, record, status: 'active', lastDelivery, + deliveryHistory: { earlierRecordsUnavailable: false, records: [{ ...lastDelivery, prompt: record.prompt }] }, +} +const taskPath = (root: string) => join(root, 'home', 'storages', 'schedule.json') + +async function seed(root: string, bytes: string): Promise { + await mkdir(join(root, 'home', 'storages'), { recursive: true }) + await writeFile(taskPath(root), bytes) +} + +function encoded(value: unknown): string { + return `${JSON.stringify({ unit: { name: 'schedule', version: 1 }, global: null, tables: { tasks: { [id]: value } } }, null, 2)}\n` +} + +async function connect(url: string, signal: AbortSignal) { + const auth = await webGet(url, signal) + const cookie = auth.headers['set-cookie']?.[0]?.split(';', 1)[0] + if (cookie === undefined) throw new Error('Owned Web process did not issue its authentication cookie') + return async (method: string, args: Record) => { + const rpcId = randomUUID() + const response = await webRequest(new URL(`/api/${method}`, url), signal, { + method: 'POST', headers: { cookie, 'content-type': 'application/json' }, + body: JSON.stringify({ type: 'client-request', rpcId, method, payload: { args } }), + }) + expect(response.status, response.text).toBe(200) + const envelope = JSON.parse(response.text) as { type?: unknown; rpcId?: unknown; result?: unknown } + expect(envelope).toMatchObject({ type: 'server-response', rpcId }) + return envelope.result + } +} + +it('edits a retained task through built Remote bindings and preserves its identity and seeded history after cold startup', async (test) => { + let persisted = encoded(task) + let updated = record + const historyRequest = { request: { sessionId, id, limit: 20 } } + const expectedHistory = { + ok: true, + value: { + id, records: task.deliveryHistory.records, earlierRecordsUnavailable: false, + earlierRecordsPruned: false, retention: { days: 30, records: 200 }, + }, + } + await withDefaultWeb(test, async ({ root, url }) => { + const rpc = await connect(url, test.signal) + expect(await rpc('schedule/catalog', {})).toEqual({ ok: true, value: [{ ...record, sessionId, status: 'active', lastDelivery }] }) + expect(await rpc('schedule/history', historyRequest)).toEqual(expectedHistory) + const target = new Date(Date.now() + 12 * 60 * 60 * 1_000) + target.setUTCMilliseconds(125) + updated = { ...record, time: target.toISOString().slice(11, 23), timeZone: 'UTC', scheduledAt: target.toISOString() } + const change = { kind: 'daily', daily: { time: updated.time, time_zone: 'UTC' } } + expect(await rpc('schedule/update', { request: { sessionId, id, expected: record, change } })) + .toEqual({ ok: true, value: { id, updated: true, record: updated } }) + persisted = await readFile(taskPath(root), 'utf8') + expect(JSON.parse(persisted)).toEqual({ + unit: { name: 'schedule', version: 1 }, + global: null, + tables: { tasks: { [id]: { ...task, record: updated } } }, + }) + expect(await rpc('schedule/history', historyRequest)).toEqual(expectedHistory) + + expect(await rpc('schedule/update', { request: { sessionId, id, expected: record, change } })) + .toEqual({ ok: true, value: { id, updated: false, code: 'schedule_conflict' } }) + expect(await rpc('schedule/update', { request: { sessionId: 'other-owner', id, expected: updated, change } })) + .toEqual({ ok: true, value: { id, updated: false, code: 'schedule_not_found' } }) + expect(await readFile(taskPath(root), 'utf8')).toBe(persisted) + }, { patches, prepare: root => seed(root, persisted) }) + + await withDefaultWeb(test, async ({ root, url }) => { + const rpc = await connect(url, test.signal) + expect(await rpc('schedule/catalog', {})).toEqual({ ok: true, value: [{ ...updated, sessionId, status: 'active', lastDelivery }] }) + expect(await rpc('schedule/history', historyRequest)).toEqual(expectedHistory) + expect(await rpc('schedule/update', { request: { + sessionId, id, expected: updated, change: { kind: 'daily', daily: { time: updated.time, time_zone: 'Etc/UTC' } }, + } })).toEqual({ ok: true, value: { id, updated: false, record: updated } }) + expect(await readFile(taskPath(root), 'utf8')).toBe(persisted) + }, { patches, prepare: root => seed(root, persisted) }) +}) + +it('creates and idempotently adopts the explicit Session id bound to seeded task data without touching its task file', async (test) => { + const persisted = encoded(task) + const expectedList = { ok: true, value: [record] } + const expectedHistory = { + ok: true, + value: { + id, records: task.deliveryHistory.records, earlierRecordsUnavailable: false, + earlierRecordsPruned: false, retention: { days: 30, records: 200 }, + }, + } + await withDefaultWeb(test, async ({ root, url }) => { + const rpc = await connect(url, test.signal) + const create = { request: { sessionId, cwd: root } } + const expectedCreate = { ok: true, value: { sessionId, agentPreset: 'standard' } } + expect(await rpc('session/create', create)).toEqual(expectedCreate) + expect(await rpc('session/create', create)).toEqual(expectedCreate) + expect(await rpc('schedule/list', { request: { sessionId } })).toEqual(expectedList) + expect(await rpc('schedule/history', { request: { sessionId, id, limit: 20 } })).toEqual(expectedHistory) + expect(await readFile(taskPath(root), 'utf8')).toBe(persisted) + }, { patches, prepare: root => seed(root, persisted) }) +}) diff --git a/apps/cli/tests/profiles/web/tests/web-default-isolation.expected.e2e.ts b/apps/cli/tests/profiles/web/tests/web-default-isolation.expected.e2e.ts index ecf19a7253..a9d9821ec4 100644 --- a/apps/cli/tests/profiles/web/tests/web-default-isolation.expected.e2e.ts +++ b/apps/cli/tests/profiles/web/tests/web-default-isolation.expected.e2e.ts @@ -8,7 +8,7 @@ import { withDefaultWeb, webGet } from './default-web-process.ts' const experimentalName = '@deepseek-ai/dsh-experimental-client-ui-agent-team' -it('boots default Web without experimental modules or an active built-in Browser', async (test) => { +it('boots default Web without experimental modules, scheduling, time context, or an active built-in Browser', async (test) => { await withDefaultWeb(test, async ({ url, request }) => { const auth = await webGet(url, test.signal) const cookie = auth.headers['set-cookie']?.[0]?.split(';', 1)[0] @@ -29,11 +29,17 @@ it('boots default Web without experimental modules or an active built-in Browser expect(roster.plugins.length).toBeGreaterThan(roster.entries.length) expect(roster.modules.some(url => modulePackage(url) === '@deepseek-ai/dsh')).toBe(true) expect(roster.client.entries.length).toBeGreaterThan(0) - const browserName = '@deepseek-ai/dsh-client-ui-sidebar-browser' - const browserEntry = roster.entries.find(entry => entry.name === browserName) - expect(browserEntry).toBeDefined() - expect(browserEntry!.state).toBeUndefined() - expect(delivered.entries.some(entry => entry.id === browserName)).toBe(false) + for (const name of [ + '@deepseek-ai/dsh-client-ui-sidebar-browser', + '@deepseek-ai/dsh-time-context', + '@deepseek-ai/dsh-schedule', + '@deepseek-ai/dsh-client-ui-schedule', + ]) { + const entry = roster.entries.find(entry => entry.name === name) + expect(entry, name).toBeDefined() + expect(entry!.state, name).toBeUndefined() + expect(delivered.entries.some(entry => entry.id === name), name).toBe(false) + } expect(experimentalRuntimeReferences(roster)).toEqual([]) const contaminated = await request('mount-experimental') diff --git a/apps/cli/tests/resolved-profile-boot.spec.ts b/apps/cli/tests/resolved-profile-boot.spec.ts index 0df34251c6..6e7bc52060 100644 --- a/apps/cli/tests/resolved-profile-boot.spec.ts +++ b/apps/cli/tests/resolved-profile-boot.spec.ts @@ -60,7 +60,7 @@ describe('runProfile with an application-owned profile', () => { throw failure }) if (stage === 'composition') vi.mocked(createRuntimeResolution).mockRejectedValueOnce(failure) - const profile: Profile = { + const profile: Profile = { skippedBundles: [], name: 'desktop', dir: home, patchPath: join(home, 'cordis.patch.yml'), patches: [], layers: [], } @@ -121,7 +121,7 @@ describe('runProfile with an application-owned profile', () => { writeFileSync(profilePatch, '- id: target\n config: { profile: true, priority: profile }\n') writeFileSync(overlay, '- id: target\n config: { overlay: true, priority: overlay }\n') writeFileSync(join(home, 'cordis.yml'), '- id: stale\n') - const profile: Profile = { + const profile: Profile = { skippedBundles: [], name: 'desktop', dir: home, patchPath: profilePatch, patches: [{ id: 'target', config: { profile: true, priority: 'profile' } }], layers: [{ diff --git a/apps/cli/tests/web-agent-presets.e2e.ts b/apps/cli/tests/web-agent-presets.e2e.ts index d4dc6653f2..758f383a44 100644 --- a/apps/cli/tests/web-agent-presets.e2e.ts +++ b/apps/cli/tests/web-agent-presets.e2e.ts @@ -133,7 +133,7 @@ async function bootWeb( await mkdir(dirname(link), { recursive: true }) await symlink(packageDir, link, 'junction') } - let profile: Profile = { + let profile: Profile = { skippedBundles: [], name: 'spec', dir: profileDir, layers: [], @@ -263,7 +263,8 @@ describe('the shipped Web composition', () => { // depend on ripgrep being present on the machine. expect(toolNames(ctx, handle.agent).filter(name => name !== 'glob' && name !== 'grep')).toEqual([ 'ask_user_question', 'bash', 'create_goal', 'edit', 'exit_plan_mode', - 'get_goal', 'interrupt_agent', 'job_kill', 'job_list', 'job_output', 'list_agents', 'present', 'read', 'read_image', 'send_message', 'skill', + 'get_goal', 'interrupt_agent', 'job_kill', 'job_list', 'job_output', 'list_agents', 'present', 'read', 'read_image', + 'send_message', 'skill', 'subagent', 'subagent_fork', 'todo_write', 'update_goal', 'web_fetch', 'web_search', 'workflow', 'write', ]) @@ -681,10 +682,14 @@ describe('a user preset declared from the shipped cordis rows', () => { agent: copied.agent, }) expect(queried.isError).toBe(false) - const tools = (JSON.parse(resultText(queried)) as { data: { tools: Array<{ name: string }> } }).data.tools - expect(tools.map(tool => tool.name)).toEqual(expect.arrayContaining([ - 'bash', 'cordis_inspect_list', 'cordis_inspect_query', 'plugin_manager', - ])) + // The whole-table answer can pass the inline token budget once the + // preset's tool table grows, and the spill policy then replaces its + // middle with a gap plus a spill footer. What this case proves is the + // provider's answer, so assert the names it must carry. + const queriedText = resultText(queried) + for (const toolName of ['bash', 'cordis_inspect_list', 'cordis_inspect_query', 'plugin_manager']) { + expect(queriedText).toContain(`"name": "${toolName}"`) + } // The `Config` provider reads the booted profile tree: the shipped `tools` row declares a Config, // and the bootstrap include row is a carrier. The name filter keeps each page small. @@ -845,7 +850,6 @@ describe('a delegated child', () => { describe('the default preset as a user setting', () => { it('composes an unnamed session from the stored default, not the composed one', async () => { - expect((await ctx.agentPresets.remoteExportList()).modeSelectionEnabled).toBe(true) expect(ctx.agentPresets.defaultId).toBe('standard') await ctx.settings.update(SETTINGS_NAMESPACE, { selectedDefault: 'minimal' }) @@ -874,6 +878,44 @@ describe('the default preset as a user setting', () => { }) }) +describe('a profile patch stored before Developer tools owned preset selection', () => { + let legacy: Context + let legacyHome: string + beforeAll(async () => { + legacyHome = await mkdtemp(join(tmpdir(), 'dsh-web-presets-legacy-')) + // A stored configuration from before the switch moved to Developer tools: + // it carries the retired key beside the default the user had saved. The + // Loader resolves the declared fields and leaves the extra one alone. + legacy = await bootWeb(legacyHome, [{ + id: SETTINGS_NAMESPACE, + config: { default: 'standard', selectedDefault: 'minimal', modeSelectionEnabled: false }, + }]) + }, 120_000) + afterAll(async () => { + await legacy?.fiber.dispose() + await rm(legacyHome, { recursive: true, force: true }) + }) + + it('starts, keeps the retired key inert and composes new sessions from the saved default', async () => { + expect(legacy.agentPresets.defaultId).toBe('minimal') + expect((await legacy.agentPresets.remoteExportList()).presets.find(row => row.id === 'minimal')?.isDefault).toBe(true) + // Settings projects the declared fields, so the retired key is neither + // shown nor rewritten; the user's saved default is. + expect(legacy.settings.describe().find(row => row.ns === SETTINGS_NAMESPACE)?.value) + .toEqual({ selectedDefault: 'minimal' }) + + const handle = await legacy.agents.create({ + sessionId: SessionId('preset-legacy-patch'), + setup: agentCtx => legacy.agentPresets.mount(agentCtx).then(() => undefined), + }) + try { + expect(toolNames(legacy, handle.agent)).toEqual(['bash']) + } finally { + await handle.dispose() + } + }) +}) + describe('a session keeps the preset it was created with', () => { it('refuses to adopt a live session under a different preset', async () => { const handle = await ctx.agents.create({ diff --git a/apps/desktop-host/package.json b/apps/desktop-host/package.json index eea02dc7ce..a5b679bfff 100644 --- a/apps/desktop-host/package.json +++ b/apps/desktop-host/package.json @@ -1,7 +1,7 @@ { "name": "@deepseek-ai/dsh-desktop-host", "description": "Private Node-mode host process for the Electron desktop application", - "version": "0.1.7-alpha.2", + "version": "0.1.7-rc.2", "private": true, "license": "MIT", "type": "module", @@ -10,7 +10,7 @@ "lib/index.js" ], "dependencies": { - "@deepseek-ai/libreoffice-kit": "^0.1.0", + "@deepseek-ai/libreoffice-kit": "^0.1.1", "@deepseek-ai/cordis": "workspace:~", "@deepseek-ai/dsh": "workspace:*", "@deepseek-ai/dsh-agent": "workspace:*", @@ -19,8 +19,10 @@ "@deepseek-ai/dsh-host-webserver": "workspace:*", "@deepseek-ai/dsh-home-paths": "workspace:*", "@deepseek-ai/dsh-jobs": "workspace:*", + "@deepseek-ai/dsh-schedule": "workspace:*", "@deepseek-ai/dsh-tool-workspace-dependencies": "workspace:*", "@deepseek-ai/dsh-skill-office": "workspace:*", - "@deepseek-ai/dsh-deepseek-account": "workspace:*" + "@deepseek-ai/dsh-deepseek-account": "workspace:*", + "@deepseek-ai/dsh-workspace": "workspace:*" } } diff --git a/apps/desktop-host/src/index.ts b/apps/desktop-host/src/index.ts index ecbff835ce..4a47a92ce8 100644 --- a/apps/desktop-host/src/index.ts +++ b/apps/desktop-host/src/index.ts @@ -2,7 +2,7 @@ import { delimiter, join } from 'node:path' import { inspect } from 'node:util' -import { loadLayeredEnv, loadProfileDirectory } from '@deepseek-ai/dsh-app-boot' +import { loadLayeredEnv, loadProfileDirectory, reportSkippedBundles } from '@deepseek-ai/dsh-app-boot' import { runProfile } from '@deepseek-ai/dsh/profile-boot' import type {} from '@deepseek-ai/dsh-client-connection' import type {} from '@deepseek-ai/dsh-host-webserver' @@ -11,6 +11,7 @@ import { resolveDshHome } from '@deepseek-ai/dsh-home-paths' import * as desktopOffice from './office.ts' import { installDesktopUpdateTaskControl } from './update-tasks.ts' +import { installDesktopQuitInspection } from './quit-inspection.ts' import { installPlatformSessionPublisher } from './platform-session.ts' import { installOfficeEngineResolution } from './office-engine.ts' @@ -20,6 +21,7 @@ async function main(): Promise { installOfficeEngineResolution(runtimeDir) const installAnchor = join(runtimeDir, 'node_modules', '@deepseek-ai', 'dsh', 'package.json') const profile = loadProfileDirectory('dsh', projectDir, installAnchor) + reportSkippedBundles('dsh', profile) const application = runProfile({ environment: loadLayeredEnv('dsh'), profile: 'desktop', @@ -39,7 +41,10 @@ async function main(): Promise { }), }) let stopping: Promise | undefined - const control: { updateTasks?: ReturnType } = {} + const control: { + updateTasks?: ReturnType + quitInspection?: ReturnType + } = {} const send = (message: object): Promise => new Promise((resolve, reject) => { if (!process.connected || process.send === undefined) { resolve(); return } process.send(message, (error) => { if (error === null) resolve(); else reject(error) }) @@ -54,6 +59,22 @@ async function main(): Promise { process.on('message', (message: unknown) => { if (typeof message !== 'object' || message === null || !('type' in message)) return if (message.type === 'shutdown') { void stop(); return } + if (message.type === 'quit-inspection') { + if (!('requestId' in message) || !Number.isSafeInteger(message.requestId)) return + const requestId = message.requestId + void (async () => { + try { + if (stopping !== undefined || control.quitInspection === undefined) throw new Error('desktop quit: Host is unavailable') + const inspection = await control.quitInspection() + await send({ type: 'quit-inspection', requestId, ...inspection }) + } catch (error) { + // The shell treats an unknown state as interruptible work and asks before quitting. + await send({ type: 'quit-inspection', requestId, activeTasks: true, scheduledTasks: false, + error: error instanceof Error ? error.message : String(error) }) + } + })().catch((error: unknown) => { console.error(error) }) + return + } if (message.type !== 'update-tasks' || !('requestId' in message) || !Number.isSafeInteger(message.requestId) || !('action' in message) || !['inspect', 'lock', 'unlock'].includes(String(message.action))) return void (async () => { @@ -70,6 +91,7 @@ async function main(): Promise { process.once('disconnect', () => { void stop() }) const { ctx } = await application control.updateTasks = installDesktopUpdateTaskControl(ctx) + control.quitInspection = installDesktopQuitInspection(ctx) await ctx.plugin(desktopOffice, { runtimeDir, source: process.argv[4] ?? join(runtimeDir, '..', 'runtime', 'primary-runtime'), diff --git a/apps/desktop-host/src/quit-inspection.ts b/apps/desktop-host/src/quit-inspection.ts new file mode 100644 index 0000000000..944bdbaf62 --- /dev/null +++ b/apps/desktop-host/src/quit-inspection.ts @@ -0,0 +1,40 @@ +/** Quit-time inspection of interruptible work and armed scheduled reminders for the Electron shell. */ + +import type { Context } from '@deepseek-ai/cordis' +import type {} from '@deepseek-ai/dsh-workspace' +import type {} from '@deepseek-ai/dsh-schedule' +import { hasDesktopActiveTasks } from './update-tasks.ts' + +/** What quitting the Host now would affect. */ +export interface DesktopQuitInspection { + /** Work the shared update-restart check also counts: running agents, queued messages, live jobs. */ + readonly activeTasks: boolean + /** A loaded session holds a scheduled reminder whose timer is armed in this process. */ + readonly scheduledTasks: boolean +} + +/** + * Register the quit inspector on the owning Host context. + * @param ctx - Booted Desktop profile context; disposal makes the inspector reject. + * @returns Inspector reporting active tasks together with armed reminders of the loaded sessions + * (the `schedule` family of `workspace/session-activity`); reminders in sessions that were never + * loaded during this run cannot fire and are not counted. + */ +export function installDesktopQuitInspection(ctx: Context): () => Promise { + let stopped = false + ctx.effect(() => () => { stopped = true }) + return async () => { + if (stopped) throw new Error('desktop quit: Host is stopping') + const agents = ctx.get('agents') + const jobs = ctx.get('jobs') + if (agents === undefined || jobs === undefined) throw new Error('desktop quit: task services are unavailable') + const liveAgents = agents.list() + const activeTasks = hasDesktopActiveTasks(liveAgents, jobs) + let scheduledTasks = false + for (const agent of liveAgents) { + const activity = await ctx.waterfall('workspace/session-activity', { sessionId: agent.id }, () => Promise.resolve([])) + if (activity.some(entry => entry.kind === 'schedule')) { scheduledTasks = true; break } + } + return { activeTasks, scheduledTasks } + } +} diff --git a/apps/desktop-host/src/update-tasks.ts b/apps/desktop-host/src/update-tasks.ts index 2b2bbf4a33..6e37a8aed8 100644 --- a/apps/desktop-host/src/update-tasks.ts +++ b/apps/desktop-host/src/update-tasks.ts @@ -5,6 +5,21 @@ import type {} from '@deepseek-ai/dsh-agent' import type {} from '@deepseek-ai/dsh-jobs' import type {} from '@deepseek-ai/dsh-client-connection' +/** + * Whether stopping the Host now would interrupt work: a generating or tool-running + * agent (including subagents and turns waiting for approval), queued inbox + * messages, or a running or stopping background job. + * @param liveAgents - Current agent roster. + * @param jobs - Job registry queried for the global roster and each agent's own jobs. + * @returns true when any of those conditions holds. + */ +export function hasDesktopActiveTasks(liveAgents: ReturnType, jobs: Context['jobs']): boolean { + return liveAgents.some(agent => agent.status === 'running' + || agent.inbox.nextTurn.length > 0 || agent.inbox.nextStep.length > 0) + || [undefined, ...liveAgents].some(agent => jobs.list(agent?.id) + .some(job => job.status === 'running' || job.status === 'stopping')) +} + /** * Register update admission on the owning Host context. * @param ctx - Booted Desktop profile context; disposal removes the request listener. @@ -42,10 +57,6 @@ export function installDesktopUpdateTaskControl(ctx: Context): (action: 'inspect if (stopped) throw new Error('desktop update: Host is stopping') if (generation !== lockGeneration) throw new Error('desktop update: admission lock was superseded') } - const liveAgents = agents.list() - return liveAgents.some(agent => agent.status === 'running' - || agent.inbox.nextTurn.length > 0 || agent.inbox.nextStep.length > 0) - || [undefined, ...liveAgents].some(agent => jobs.list(agent?.id) - .some(job => job.status === 'running' || job.status === 'stopping')) + return hasDesktopActiveTasks(agents.list(), jobs) } } diff --git a/apps/desktop-host/tests/platform-session.spec.ts b/apps/desktop-host/tests/platform-session.spec.ts index 3fee3c2d5e..fbc26da6e1 100644 --- a/apps/desktop-host/tests/platform-session.spec.ts +++ b/apps/desktop-host/tests/platform-session.spec.ts @@ -13,13 +13,16 @@ class Account extends DeepSeekAccount { ended = Promise.withResolvers() reading = Promise.withResolvers() finished = Promise.withResolvers() - read: () => Promise = async () => ({ origin: 'https://platform.example', token: 'test' }) + read: () => Promise = async () => ({ origin: 'https://platform.example', userId: null, token: 'test' }) override async getState() { return state } override async getProfile() { return null } override async getBalance() { return null } + override async getUnnotifiedBonuses() { return null } + override async ackBonusNotified() { return false } override async startSignIn() { return state } override async cancelSignIn() { return state } override async signOut() { return state } + override async rejectToken() {} override async resolveToken() { return undefined } override async getPlatformSession() { this.reading.resolve(undefined); return this.read() } override async *watch(signal: AbortSignal) { @@ -50,7 +53,7 @@ it('clears removed credentials and publishes the replacement provider session', delivered = Promise.withResolvers() await ctx.plugin((scope) => { const replacement = new Account(scope) - replacement.read = async () => ({ origin: 'https://platform.example', token: 'replacement' }) + replacement.read = async () => ({ origin: 'https://platform.example', userId: null, token: 'replacement' }) }) await delivered.promise expect(sessions.at(-1)?.token).toBe('replacement') @@ -94,7 +97,7 @@ it('suppresses a credential read that completes during provider disposal', async await account.reading.promise const disposed = provider.dispose() await cleared.promise - pending.resolve({ origin: 'https://platform.example', token: 'stale' }) + pending.resolve({ origin: 'https://platform.example', userId: null, token: 'stale' }) await disposed expect(sessions).toEqual([null]) await account.finished.promise diff --git a/apps/desktop-host/tests/quit-inspection.spec.ts b/apps/desktop-host/tests/quit-inspection.spec.ts new file mode 100644 index 0000000000..6151e56f95 --- /dev/null +++ b/apps/desktop-host/tests/quit-inspection.spec.ts @@ -0,0 +1,103 @@ +import { Context } from '@deepseek-ai/cordis' +import { JobId, JobRegistry } from '@deepseek-ai/dsh-jobs' +import type { JobStatus, JobView } from '@deepseek-ai/dsh-jobs' +import { SessionId } from '@deepseek-ai/dsh-session/types' +import type { SessionActivity } from '@deepseek-ai/dsh-workspace' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { installDesktopQuitInspection } from '../src/quit-inspection.ts' + +type AgentState = { id: SessionId; status: 'idle' | 'running'; inbox: { nextTurn: object[]; nextStep: object[] } } + +let ctx: Context +let inspect: ReturnType +const agents: AgentState[] = [] +const jobs = new Map() +/** Activity each provider family reports per session; the inspector must count only `schedule`. */ +const activity = new Map() + +/** A registry whose only served member is the per-owner roster the inspector reads. */ +class RosterOnlyJobRegistry extends JobRegistry { + readonly events = { subscribe: () => () => {} } + start(): never { throw new Error('unsupported') } + list(caller?: SessionId): JobView[] { + return (jobs.get(caller) ?? []).map((status, index) => ({ + id: JobId(`bash-${index + 1}`), + kind: 'bash', + label: 'sleep 60', + ...caller === undefined ? {} : { owner: caller }, + status, + startedAt: 0, + output: { total: 0, earliest: 0 }, + })) + } + get(): never { throw new Error('unsupported') } + read(): never { throw new Error('unsupported') } + readAt(): never { throw new Error('unsupported') } + kill(): never { throw new Error('unsupported') } + wait(): never { throw new Error('unsupported') } + remove(): never { throw new Error('unsupported') } + attachController(): () => void { return () => {} } +} + +function agent(id: string, status: 'idle' | 'running' = 'idle'): AgentState { + return { id: SessionId(id), status, inbox: { nextTurn: [], nextStep: [] } } +} + +beforeEach(() => { + agents.length = 0 + jobs.clear() + activity.clear() + ctx = new Context() + // Narrow service doubles exercise the inspector against a real Cordis event lifecycle. + ctx.provide('agents', { list: () => agents } as never) + new RosterOnlyJobRegistry(ctx) + ctx.on('workspace/session-activity', async ({ sessionId }, next) => [...activity.get(sessionId) ?? [], ...await next()]) + inspect = installDesktopQuitInspection(ctx) +}) + +afterEach(async () => { await ctx.fiber.dispose() }) + +describe('Desktop Host quit inspection', () => { + it('reports neither active nor scheduled work for idle loaded sessions', async () => { + agents.push(agent('quiet')) + activity.set(SessionId('quiet'), [{ kind: 'turn' }]) + expect(await inspect()).toEqual({ activeTasks: false, scheduledTasks: false }) + }) + + it.each(['running', 'nextTurn', 'nextStep', 'job'] as const)('counts %s work with the same rule as the update restart check', async (kind) => { + const owner = agent('busy') + if (kind === 'running') owner.status = 'running' + else if (kind === 'job') jobs.set(owner.id, ['stopping']) + else owner.inbox[kind].push({ queued: true }) + agents.push(owner) + expect(await inspect()).toEqual({ activeTasks: true, scheduledTasks: false }) + }) + + it('counts an armed schedule family in any loaded session and stops at the first one', async () => { + const asked: SessionId[] = [] + ctx.on('workspace/session-activity', async ({ sessionId }, next) => { asked.push(sessionId); return next() }) + agents.push(agent('first'), agent('second'), agent('third')) + activity.set(SessionId('second'), [{ kind: 'schedule', items: [{ id: 'reminder-1', label: 'stand-up' }] }]) + expect(await inspect()).toEqual({ activeTasks: false, scheduledTasks: true }) + expect(asked).toEqual([SessionId('first'), SessionId('second')]) + }) + + it('reports both when a running session also holds a reminder', async () => { + agents.push(agent('both', 'running')) + activity.set(SessionId('both'), [{ kind: 'job', items: [{ id: 'bash-1' }] }, { kind: 'schedule', items: [{ id: 'reminder-2' }] }]) + expect(await inspect()).toEqual({ activeTasks: true, scheduledTasks: true }) + }) + + it('does not classify unavailable task services as idle', async () => { + const empty = new Context() + try { + await expect(installDesktopQuitInspection(empty)()).rejects.toThrow('task services are unavailable') + } finally { await empty.fiber.dispose() } + }) + + it('refuses inspection after disposal', async () => { + expect(await inspect()).toEqual({ activeTasks: false, scheduledTasks: false }) + await ctx.fiber.dispose() + await expect(inspect()).rejects.toThrow('Host is stopping') + }) +}) diff --git a/apps/desktop-host/tsconfig.json b/apps/desktop-host/tsconfig.json index 865875e338..31c64f179b 100644 --- a/apps/desktop-host/tsconfig.json +++ b/apps/desktop-host/tsconfig.json @@ -11,6 +11,8 @@ { "path": "../../vendor/cordis" }, { "path": "../../packages/core/agent" }, { "path": "../../packages/jobs/jobs" }, + { "path": "../../packages/schedule/schedule" }, + { "path": "../../packages/workspace/workspace" }, { "path": "../../packages/skill/skill-office" }, { "path": "../../packages/util/home-paths" }, { "path": "../../packages/skill/tool-workspace-dependencies" }, diff --git a/apps/desktop/README.i18n.yaml b/apps/desktop/README.i18n.yaml index 7d355c9801..039d4701b1 100644 --- a/apps/desktop/README.i18n.yaml +++ b/apps/desktop/README.i18n.yaml @@ -1,6 +1,70 @@ -# 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: +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write apps/desktop/README.md -README.md: 87b16ac8fd7ec269e8c02a34a32e6593b38aec0a -README.zh.md: 895fdd972148c90bad00916a35b21cebff8842e8 +/deepseek-harness-desktop: + en: 45561fc0dd3a1b20 + zh: f4b03355d4bd0693 +/deepseek-harness-desktop/closing-the-window-and-quitting: + en: fb852f3bd70d8602 + zh: 3d2b0a8d580d7f0a +/deepseek-harness-desktop/key-technical-decisions: + en: 069fdfd72d2ea26a + zh: 76ae549d43c99bb4 +/deepseek-harness-desktop/key-technical-decisions/bundled-workspace-dependencies: + en: 31cbb7452be8e1ad + zh: 502ec556e2ec301e +/deepseek-harness-desktop/installation-ownership: + en: 8307baf6c5b691d0 + zh: 86e46b9552017ff6 +/deepseek-harness-desktop/installation-ownership/runtime-and-plugin-activation: + en: 0d11af8639977a6d + zh: 86b086b12d2210d3 +/deepseek-harness-desktop/develop: + en: 9b9b362a9865e763 + zh: c748901168e2db8c +/deepseek-harness-desktop/develop/startup-onboarding: + en: 5e2d62207a603d81 + zh: 5fb863d4906f4a67 +/deepseek-harness-desktop/develop/welcome-window-appearance: + en: 7220801ccc3b2e6b + zh: 042dc97976aef979 +/deepseek-harness-desktop/package: + en: 4cd8a8da6977928d + zh: 9f624855a2edac37 +/deepseek-harness-desktop/package/release-versions: + en: f461b255133384cc + zh: 2b9db718f22fdd04 +/deepseek-harness-desktop/package/runtime-file-selection: + en: f0e345fd89868803 + zh: fd2c775ad23fa2f0 +/deepseek-harness-desktop/package/upload-updates: + en: c64d7fe2fe2534b7 + zh: 2188e1ae99ab4b33 +/deepseek-harness-desktop/package/unsigned-windows-test-installer: + en: cfd5780dd26a8e46 + zh: f7a16b1ede793b7b +/deepseek-harness-desktop/package/windows-installer-interface: + en: f176a8b1c7de3064 + zh: 6ea2dbe6bb808c34 +/deepseek-harness-desktop/package/windows-ev-signing: + en: 8efe3498dbe8686d + zh: a88c16f20a9430f3 +/deepseek-harness-desktop/updates: + en: d0df867b69cbffa4 + zh: eeb47b79b86fe5ee +/deepseek-harness-desktop/updates/mandatory-update-policy: + en: 2f789a4949fafb12 + zh: d8b28c01cfee11b7 +/deepseek-harness-desktop/updates/local-updater-qualification: + en: bc50fd8a4d96c227 + zh: fb0a6ce80c31cda6 +/deepseek-harness-desktop/low-level-development-overrides: + en: 0b225f914142ef0b + zh: 9ffd07768d37824e +/deepseek-harness-desktop/known-limitations: + en: 5b77213c86bbcfb6 + zh: b34bf21773bb852b +/deepseek-harness-desktop/dev-note: + en: 8e26b460ba31f21b + zh: fbcd0307b3867125 diff --git a/apps/desktop/README.md b/apps/desktop/README.md index 87b16ac8fd..0f579c249b 100644 --- a/apps/desktop/README.md +++ b/apps/desktop/README.md @@ -10,22 +10,42 @@ Desktop’s local native directory flow opens an Electron folder dialog attached Creator and the Web Plugin Manager use Desktop’s bundled pnpm under Electron Node mode without requiring pnpm on PATH. The private Node launcher environment applies only to package operations. -Embedded Platform documents use a dedicated non-persistent WebContentsView session. Host sends account credentials through private Node IPC; account RPC and the Harness renderer receive no token. Before page scripts execute, the Platform preload performs one synchronous IPC to read the prepared main-process credential. It exposes displayMode, synchronous getAuthToken() and getLocale() getters, and onLocaleChange(listener), which returns an unsubscribe function. Both getters read preload memory without further IPC. The bootstrap includes the resolved Desktop language (`zh_CN` or `en_US`); Settings language changes update the preload cache and notify the open Platform document without reloading. Platform applies this language before its first render and does not persist it as a browser preference. The main-process handler performs only sender validation and an in-memory read; it never waits for Host, disk, or network. Trusted-page initialization failures retain embedded mode and make the getter throw, preventing browser-credential fallback. Only the owned Platform main frame on the configured issuer origin can initialize. Sign-out, credential replacement, Host shutdown, and view closure destroy the document. Cross-origin document navigation is blocked. HTTPS links requesting a new window open in the system browser without the embedded session or token; other schemes and URL credentials are rejected. Native views occupy the viewport below the Account feature’s return bar. +Embedded Platform documents use a persistent WebContentsView partition keyed by a hash of the Platform origin and stable account ID. localStorage preferences, including dismissed notices, survive view closure and application restart; different accounts and origins use separate storage. The Host supplies the account ID from its latest successful profile read; while no ID is known, the document opens in a disposable partition that keeps no preference across opens. Opening a persistent partition clears cookies, filesystem, IndexedDB, Cache Storage, the HTTP and shader caches, service workers, and HTTP authentication before the document loads; a disposable partition clears all of its storage. Closing a view destroys the document, removes its request interceptors, and schedules the same cleanup, so authentication left by an unclean exit is cleared before the next document loads. The next open and application shutdown await that cleanup, and an update install waits for it before the installer takes over the exit. A failed cleanup rejects that open and blocks the same account until a later cleanup succeeds; other accounts keep opening. Sign-out destroys the document but retains account-scoped preferences for the next sign-in. A document already open in a disposable partition stays mounted when the account ID arrives for the same credential; the next open uses the account-scoped partition. The [storage decision](../../.agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.md) describes the retention policy. Host sends account credentials through private Node IPC; account RPC and the Harness renderer receive no token. Before page scripts execute, the Platform preload performs one synchronous IPC to read the prepared main-process credential. It exposes displayMode, synchronous getAuthToken() and getLocale() getters, and onLocaleChange(listener), which returns an unsubscribe function. Both getters read preload memory without further IPC. The bootstrap includes the resolved Desktop language (`zh_CN` or `en_US`); Settings language changes update the preload cache and notify the open Platform document without reloading. Platform applies this language before its first render and does not persist it as a browser preference. The main-process handler performs only sender validation and an in-memory read; it never waits for Host, disk, or network. Trusted-page initialization failures retain embedded mode and make the getter throw, preventing browser-credential fallback. Only the owned Platform main frame on the configured issuer origin can initialize. Sign-out, credential replacement, Host shutdown, and view closure destroy the document. Cross-origin document navigation is blocked. HTTPS links requesting a new window open in the system browser without the embedded session or token; other schemes and URL credentials are rejected. Native views occupy the viewport below the Account feature’s return bar. -Desktop Host Platform API requests use the same `x-client-platform` mapping as update-policy requests. The account provider owns [API-only header configuration](../../packages/credentials/deepseek-account-platform/README.md#use-this-package). +Desktop Host Platform API requests and update-policy requests identify the installed client with the same Platform client headers: platform, client version, locale, timezone offset in seconds, and a bundle id that is intentionally empty. Account operations take the calling UI's identity per call; the account provider owns [API-only header configuration](../../packages/credentials/deepseek-account-platform/README.md#use-this-package). Update policy additionally reports architecture, update channel, and bundled runtime version. + +A server-expired account credential returns to Welcome when no official API key is configured; an available API key keeps the workspace open. Explicit sign-out follows the same rule. Both Welcome and the workspace display the localized expiry notice. Desktop microphone access is restricted to audio requests from the primary `dsh-app://app` frame. macOS uses system microphone authorization and a packaged usage description. Press F12 (Fn+F12 on media-key keyboards), Command+Option+I on macOS, or Ctrl+Shift+I on Windows to toggle DevTools for the focused application page, including in packaged builds. These native shortcuts use hidden application-menu items. Update overlays and packaged embedded browser guests disable DevTools. +## Closing the window and quitting + +Closing the main window (macOS close button and ⌘W; Windows ×, Alt+F4, and the taskbar Close window command) hides it; Windows asks for acknowledgement before the first hide. The page and the Host keep running, tasks continue, and the next show presents the same document with its session, drafts, and scroll position; a fullscreen macOS window leaves fullscreen before hiding. The window returns through the Dock icon, a second launch, or `dsh://open` on macOS, and through the tray on Windows. Minimize is unchanged. Closing the welcome window before the workspace opens quits on Windows and, on macOS, keeps the application in the Dock without a window. + +Windows keeps a tray icon for the whole run. Its tooltip is the product name, a single click shows and focuses the window, and the context menu offers Open DeepSeek Harness and Quit DeepSeek Harness in the shell locale. Before the first hide, the shared update-dialog overlay explains that running tasks continue and the window can be reopened from the system tray. Confirm hides the window and writes `background-close-confirmed` under Electron userData; Escape, dismissal, or dialog failure keeps the window visible and does not record acknowledgement. Repeated close requests focus the existing shell dialog. In-place updates retain the marker and uninstall removes it. The old `background-notice-shown` marker does not suppress this confirmation. Closing the window sends no system notification. The tray bitmaps are `resources/tray-windows.ico`, rendered from `resources/icon-windows.svg` at 16, 20, 24, 32, 40, 48, and 64 pixels by `pnpm run render:tray-icon`, and packaged as `resources/tray.ico`. macOS ships no menu bar icon. + +Every ordinary quit entry — ⌘Q, the application menu, the Dock menu, the Windows tray and caption Application menu, and the quits caused by closing the mandatory-update or welcome window — asks the Host what it would interrupt. The Host answers over the private IPC channel with two facts: active tasks under the same rule as the update restart check (running agents including subagents and approval waits, queued messages, running or stopping jobs), and armed scheduled reminders reported by the `schedule` family of `workspace/session-activity` for the sessions loaded during this run. Neither fact, the quit proceeds silently. Otherwise a native message box without an owner window — hidden windows stay hidden — shows **Quit DeepSeek Harness?** with one of three localized explanations: running tasks will be interrupted, scheduled tasks will not run while the application is closed, or both. Quit is the default button and Cancel answers Esc; macOS places Cancel left of Quit, Windows places Quit left of Cancel, and the Windows task dialog shows the application icon and stays light regardless of the application theme. A Host that has not reached ready or has failed cannot run tasks, so the quit proceeds without asking. An inspection failure or a Host that misses the two-second deadline is treated as running tasks. While the box is open, another quit request joins it instead of stacking a second one (macOS also raises it; Electron exposes no handle to the Windows task dialog), the explanation does not change when work starts or ends, Quit stops the application without re-inspecting, and Cancel changes nothing. Cancelling a quit that closing the welcome window started shows the welcome window again. + +The confirmation is skipped when the installer restart already confirmed task interruption, when the fatal-recovery dialog exits or restarts, when the development Restart App and Host command runs, and during operating-system shutdown, restart, or log-off: Windows sets this on the definitive session-end message; macOS sets it on the power-off notification, and because another application can still cancel that shutdown, the next focus or show of the main window clears it. Installer-owned quit cancels any pending ordinary quit decision; late inspection results and dialog answers cannot open another confirmation or repeat cleanup. A user-initiated update download that finishes while the window is hidden defers its Install and Restart confirmation until the window is shown again; the mandatory flow keeps its taskbar and Dock attention. The Windows installer and uninstaller tell a user whose application is still running to quit it from the system tray. Desktop does not enable scheduled tasks by default, so the scheduled-task explanations appear only once that feature is on; reminders fire only in loaded sessions, and unloaded sessions are neither counted nor resumed until they are opened. + +The tray renderer enlarges the whale by 20% around the tile center while preserving the background and aspect ratio; application and installer icons retain their original proportions. + ## Key technical decisions The original artwork lives in `resources/icon.png` and `resources/icon.svg`; platform adaptations retain the whale and gradients in `resources/icon-windows.*` and `resources/icon-macos.*`. Export each platform SVG as a transparent 1024×1024 PNG. Electron-builder generates the multi-size ICO for the Windows application, installer, and uninstaller ([Windows icon requirements](https://learn.microsoft.com/en-us/windows/apps/design/iconography/app-icon-construction)). The installation pages use matching artwork in both themes; the uninstaller's welcome and finish pages share `installer/assets/uninstaller-sidebar.png`, converted to a 164×314 BMP during preparation. +Shortcut overrides are stored in `app.getPath('userData')/keybindings.json`, separately from `DSH_HOME`. The main process validates and serializes changes before publishing accepted bindings. Failed reads retain the last accepted bindings and block edits, including Restore All; unreadable and future-version files remain unchanged. Development can isolate these preferences with `DSH_DESKTOP_USER_DATA_DIR`; the launcher prints its resolved path. See the [shortcut service](../../packages/client/shortcuts/README.md) for format and conflict semantics. + +The macOS File menu displays the accepted single-key binding, including arrow keys, and routes Close Page or Window through the client page owner. On Windows and macOS, all complete accepted bindings are intercepted before main-document, embedded-frame, and browser-guest input, including editing and terminal input. Recording and input-method composition remain protected. Update overlays block product shortcuts and editing-key delivery to the parent window and its browser guests from creation until the last overlay closes. Every overlay opening or closing invalidates pending chord state. The main process shares one overlay owner between update dialogs and shortcut input through explicit creation and input-state capabilities. Two-key chords leave the first key’s initial press available to the page and do not intercept its release; complete chords and their repeats are consumed. The renderer leaves configurable binding dispatch to the native adapter. Chords have no native menu accelerator. Accepted commands are forwarded once through the trusted preload. Linux dispatches main-document shortcuts through the DOM and forwards accepted embedded-frame bindings to the client resolver. Closing the last window preserves macOS application lifetime; Windows exits the desktop instance and stops its tasks. The [close decision](../../.agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.md) records this lifecycle choice. + The macOS PNG uses an inset rounded background for legacy ICNS packaging, with representations up to 1024 pixels. It is a flattened icon, not an Icon Composer document. Apple's [app icon guidance](https://developer.apple.com/design/human-interface-guidelines/app-icons) describes unmasked layers for Icon Composer; those inputs require a separate macOS export and must not reuse the rounded ICNS artwork. Verify Finder and Dock appearance on supported macOS versions before release. ### Bundled workspace dependencies +electron-builder copies only the manifest's `dependencies` into `app.asar/node_modules`, so the Electron main bundle `lib/main.js` inlines its workspace devDependencies and leaves `electron`, Node builtins, and those `dependencies` as its only bare imports; a sandboxed preload may leave only `electron`, `events`, `timers`, and `url`, the modules its `require` polyfill resolves. The main bundle resolves the inlined packages from their `lib/` output, so the root `build:lib:host` bundles `apps/desktop` after the concurrent workspace tsdown pass, and [`desktop-bundle-imports`](scripts/desktop-bundle-imports.mjs) fails any Desktop bundle whose static, dynamic, or `require()` import the packaged application cannot resolve. Without that check an import rolldown could not resolve ships as an external specifier and fails at launch with `ERR_MODULE_NOT_FOUND`. The [bundle-order decision](../../.agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.md) records the alternatives. + Signed Windows packaging scans the primary runtime and application production dependencies for PE content, including files without a conventional extension. The final scan covers the entire unpacked application. Directory links, malformed `MZ` files and non-PE `.exe`, `.dll` or `.pyd` files stop packaging; data files beginning with `MZ` are also rejected unless they contain a valid PE header. It preserves valid vendor signatures and signs unsigned code before sealing runtime hashes or executing smoke checks. Public-key inspection uses batches of 32 files with at most four processes; hardware-token signing remains serial, and each new signature must match the configured certificate and carry a timestamp. Hardware signing and verification failures stop the run; isolated timestamp requests follow the bounded policy below. Electron-builder preserves copied runtime executables only after signature and exact-byte verification. A final PE-signature audit and a fresh-cache ASAR payload and Host smoke must pass before the release completion record is written. Development, preparation-only and unsigned builds do not use the hardware token and can be blocked by Windows code-integrity policy; no build mode disables that policy. Passing smoke checks does not establish compatibility with every enterprise policy. Desktop carries independent Python, Node.js and pnpm distributions. Python includes numpy, pandas, python-docx, python-pptx, openpyxl, Pillow, lxml and XlsxWriter with their complete dependencies. The `load_workspace_dependencies` tool installs this payload offline on first use under `$DSH_HOME/dsh-runtimes/dsh-primary-runtime` (normally `~/.dsh/dsh-runtimes/dsh-primary-runtime`) and returns absolute interpreter, pnpm script and library paths plus `pythonDistributions`, the bundled distribution names and versions. The version report excludes user-installed additions. Office tasks prefer these libraries unless user or workspace instructions select another environment. Execute the pnpm script with the returned Node executable. The returned Node library directory is reserved for bundled libraries, not pnpm's global installation directory. @@ -50,6 +70,8 @@ Node prepares the bundled interpreters and Python libraries without a system Pyt The [thin-wrapper decision](../../.agents/notes/implemented/architecture/2026-09-10-desktop-web-wrapper.md) owns shared Web behavior and Desktop adapters. The [Electron packaging and update decision](../../.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.md) owns release identity, signing, and update qualification. +Welcome loads the shared Toast palette and shadow tokens, with system typography for body-mounted notifications. + ## Installation ownership Electron owns `$DSH_HOME/profiles/desktop`. Its `dependencies` contains packages installed by pnpm; `dsh.profile.bundles` contains the built-in bundles followed by enabled plugins. The signed application supplies dsh, the private Desktop Host, and their production packages from `resources/app.asar/dsh`. Packaged applications select runtime profile resolution without creating package links; development profiles use filesystem links. Both host and plugins execute in the same Electron Node-mode process; Desktop does not enable `--preserve-symlinks`. The CLI cannot boot or mutate this profile. @@ -64,9 +86,9 @@ The product UI retains Web actions, including "Open In..." through the shared au Electron chooses typed English or Chinese shell copy from its application locale and falls back to English. The macOS application bundle declares English and Simplified Chinese in `CFBundleLocalizations`, allowing macOS to match the initial application language to the user’s preferred languages. Saved Client UI language preferences still take precedence for the main interface. On Windows, the main document's language updates desktop menus, recovery and update prompts. The repository Client UI i18n gate checks desktop sources. -Windows uses a 40-DIP caption with native window controls and colors synchronized from the application palette. Localized Application and Edit entries beside the sidebar toggle open native popup menus. They mount only after the application frame publishes its shell overlay seat, and remain absent during startup loading. Application provides Check for Updates and Exit; Edit provides undo, redo, cut, copy, paste, delete, and select all by sending the corresponding keys to the focused editor. Plugin management uses the main application's Plugins page. No separate native menu row appears on Alt. Other platforms retain their native menus. Editable fields retain keyboard commands and a context menu without shortcut labels; Chromium supplies command availability, and selected read-only text offers Copy. +Windows uses a 40-DIP caption with native window controls and colors synchronized from the application palette. Localized Application and Edit entries beside the sidebar toggle open native popup menus. They mount only after the application frame publishes its shell overlay seat, and remain absent during startup loading. Application provides Check for Updates and Exit; Edit provides undo, redo, cut, copy, paste, delete, and select all by sending the corresponding keys to the focused editor, independently of custom shortcut bindings. Plugin management uses the main application's Plugins page. No separate native menu row appears on Alt. Other platforms retain their native menus. Editable fields retain keyboard commands and a context menu without shortcut labels; Chromium supplies command availability, and selected read-only text offers Copy. -On macOS the custom application menu also declares the standard File, Window, and application menus, because replacing Electron's default menu drops Close Window (⌘W), Minimize (⌘M), and Hide (⌘H). Linux keeps the application and Edit menus. +On macOS the custom menu retains Electron's standard Window menu and application hide commands, including Minimize (⌘M) and Hide (⌘H). Linux keeps the application and Edit menus. ### Runtime and plugin activation @@ -88,7 +110,6 @@ Before the first fatal dialog opens, Electron writes a crash report to the platf Recovery waits for Host shutdown before changing plugin activation. The native recovery action calls the shared app-boot recovery function under the profile transaction lock. It disables third-party bundles and renames the profile’s `cordis.patch.yml` to `cordis.patch.yml.bak-` (with an ordinal on collisions) without parsing it; the next startup creates an empty patch. Installed packages and earlier backups remain. The home-level patch is unchanged. The Electron console records the backup path (or its absence) and the unchanged home-level patch. Invalid profile data, rename failures, or write failures are reported as recovery-operation errors; completed changes remain, and Desktop does not restart as though recovery succeeded. Desktop has no profile-reset action or emergency HTML document. - ## Develop The development application menu offers Reload Page (Cmd+R on macOS, Ctrl+R elsewhere) and Restart App and Host. Restart waits for Host shutdown before relaunching Electron and starting a new Host; neither action rebuilds source files. @@ -109,9 +130,12 @@ pnpm run start:desktop The Web counterparts are `pnpm run dev:web` and `pnpm run start:web`, documented in the [development guide](../../docs/development.md). Workspace development runs the current CLI and private Desktop Host packages under Electron RunAsNode. Plugin management and recovery use `$DSH_HOME/profiles/desktop`, separate from the disposable workspace runtime. The Host uses runtime module resolution in both development and packaged builds without creating official-package fallback links; developer-installed packages, including links, retain native priority. Use an unpacked application to exercise Electron RunAsNode, bundled pnpm, bundled dsh resources, plugin installation and repair paths. +The [native/renderer keyboard tests](tests/keyboard.spec.ts) compile in [their own Client test project](../../tsconfig.desktop-keyboard-tests.json), reached by the repository Client typecheck. Its Desktop imports are limited to Cordis-free input, persistence, IPC, browser-guest, and overlay modules. ### Startup onboarding +The API-key input starts empty and uses `autocomplete="new-password"` to ask Chromium not to autofill saved login passwords. + Repeated launches and `dsh://open` keep the workspace hidden until the startup credential check or a welcome action permits entry. Entering from Welcome places keyboard focus on the document without selecting a sidebar control; Tab navigation remains available. Desktop checks configured model API-key references after the Host starts and before opening the workspace. With no configured key, the welcome window offers the [API-key page](https://www.figma.com/design/jRBBK7zBgcszdVWQ0Fh5J8/Harness?node-id=2138-44626). Save and continue writes through the existing credential service using the official DeepSeek provider's configured reference, then opens the workspace. Set up later opens the workspace without saving the draft or a completion setting; the next process launch checks credentials again. Back to sign in returns to the entry and clears the unsaved key and validation message. Buttons keep their labels and block competing actions while saving or opening the workspace. The Desktop preload marker suppresses the Web credential dialog, while retaining the Models settings page and the welcome notice. @@ -195,7 +219,7 @@ Windows release qualification also runs [directory and replacement checks](scrip pwsh -NoProfile -File apps/desktop/scripts/smoke-windows.ps1 -Makensis $Makensis -SevenZip $SevenZip -PluginDir $PluginDir -FrameLibrary apps/desktop/.desktop-build/targets/win-x64/installer-ui/window-frame.dll ``` -The Windows installer extracts the new version beside the installation directory, stops the old application, and replaces directories through same-volume renames. Same-path upgrades preserve the old directory until promotion succeeds; extraction failure leaves it intact, and promotion failure attempts to restore it. The installer removes the old backup before launch. Forced termination or power loss can leave `.new-*` or `.old-*` directories; installation-location and scope migrations retain electron-builder's old-uninstaller flow. +The Windows installer checks for a running application at startup and after destination selection, before extracting the new version beside the installation directory. It checks again before replacing directories through same-volume renames. A running application blocks installation; update launches allow up to ten seconds for it to exit. Same-path upgrades preserve the old directory until promotion succeeds; extraction failure leaves it intact, and promotion failure attempts to restore it. The installer removes the old backup before launch. Forced termination or power loss can leave `.new-*` or `.old-*` directories; installation-location and scope migrations retain electron-builder's old-uninstaller flow. When extraction fails, the installer writes a report with the 7-Zip result and its complete error output to the updater cache directory as `%LOCALAPPDATA%\-updater\installer-logs\extract-failure-.log` (currently `@deepseek-aidsh-desktop-updater`) and shows the first error line with a **Copy error details** button; silent installs write only the report. Unsigned Windows builds (`DSH_DESKTOP_UNSIGNED=1`) name their installer `deepseek-harness--win-x64-unsigned.exe` so they cannot be mistaken for release artifacts. @@ -255,7 +279,7 @@ Mac packaging reads three tuning fields from `.env.macos`: The proxy fields are independent and reject URL credentials, paths, queries and fragments. Empty values preserve inherited networking. An explicit download proxy replaces child-process proxy variables and bypasses local hosts only; it does not change system settings. Windows and standalone `release:pack` retain their existing concurrency defaults. Company proxy addresses belong in the ignored local file; see internal documentation for addresses. -Apple tooling uses the active macOS network service's HTTP/HTTPS proxies. Configured notarization routing checks proxy reachability, saves that service's settings, enables the proxy around both artifact lanes, and restores the saved settings after both lanes settle. An originally disabled proxy with an empty server and port zero is restored by disabling it; the temporary server and port may remain stored but inactive. Directory-only builds apply it to App notarization after the signed directory build. This temporarily affects other applications and requires permission to change system proxies; PAC, auto-discovery, SOCKS and authenticated proxy configurations must be disabled first. Packaging and recovery acquire the same per-user POSIX file lock before reading recovery data or changing proxies; process exit releases ownership, while the lock file remains in place. This prevents overlapping proxy transactions across checkouts; other users and network-setting tools must not change these settings concurrently. SIGINT/SIGTERM wait for active work before restoration. After forced termination or a restoration error, stop any remaining notarization processes and run `pnpm --dir apps/desktop run restore:mac-proxy`; the saved record remains until restoration succeeds. Configuration checks validate URL syntax without changing system settings or contacting the proxy. +Apple tooling uses the active macOS network service's HTTP/HTTPS proxies. Configured notarization routing checks proxy reachability, saves that service's settings, enables the proxy around both artifact lanes, and restores the saved settings after both lanes settle. An originally disabled proxy with an empty server and port zero is restored by disabling it; the temporary server and port may remain stored but inactive. Directory-only builds apply it to App notarization after the signed directory build. This temporarily affects other applications and requires permission to change system proxies; PAC, auto-discovery, SOCKS and authenticated proxy configurations must be disabled first. Packaging and recovery acquire the same per-user POSIX file lock before reading recovery data or changing proxies; process exit releases ownership, while the lock file remains in place. The lock loads `@deepseek-ai/node-addon-system/flock` at first use rather than at script start, so `check:package` and the packaging entry load on a checkout that has not built `native/system`; when the host addon binary or the entry's JavaScript is missing at lock time, the loader runs `pnpm run build:native-system` and `pnpm --dir native/system run build:ts` before locking, so recovery works on such a checkout as well. This prevents overlapping proxy transactions across checkouts; other users and network-setting tools must not change these settings concurrently. SIGINT/SIGTERM wait for active work before restoration. After forced termination or a restoration error, stop any remaining notarization processes and run `pnpm --dir apps/desktop run restore:mac-proxy`; the saved record remains until restoration succeeds. Configuration checks validate URL syntax without changing system settings or contacting the proxy. ### Unsigned Windows test installer @@ -344,11 +368,15 @@ An unpacked artifact contains Electron, the materialized dsh production tree, pn ## Updates -Packaged applications check fixed Nightly asynchronously at startup. Ordinary polling uses a ten-minute base interval with independently sampled ±20% jitter. Each check failure doubles the base delay up to one hour; success resets it. The randomized delay is bounded by that cap and starts after all joined callers settle. Foreground and system-resume checks respect the same monotonic deadline; the localized Check for Updates menu item, including in the Windows caption's Application menu, runs immediately and joins an in-flight check. A newly received mandatory policy also requests an immediate feed check. Automatic checks never open dialogs or download packages. Manual checks display checking, failure, or no-update feedback with the installed version. Ordinary update dialogs fade in and out in place; consecutive prompts replace the card content and reset its scroll position while retaining the backdrop and background blur. +On Windows, the downloaded-update confirmation explains that the application closes during installation, reopens automatically, and should not be launched again while updating. An installer restart carrying `--updated` raises and focuses the main window once when startup opens the workspace directly, without enabling always-on-top. Startup into the welcome page discards that request so a later login keeps its normal activation behavior. Ordinary launches and other platforms do not use this foregrounding step. + +Native update overlays wait for a ready document and a visible parent, and reappear when that parent is shown again. Closing an overlay releases its input interception and parent listeners. The [local window qualification](tests/README.md#verification-overlay) exercises these transitions without starting a workspace. + +Packaged applications check fixed Nightly asynchronously at startup. Ordinary polling uses a ten-minute base interval with independently sampled ±20% jitter. Each check failure doubles the base delay up to one hour; success resets it. The randomized delay is bounded by that cap and starts after all joined callers settle. Foreground and system-resume checks respect the same monotonic deadline; the localized Check for Updates menu item, including in the Windows caption's Application menu, runs immediately and joins an in-flight check. A newly received mandatory policy also requests an immediate feed check. Automatic checks never open dialogs or download packages. Manual checks display checking, failure, or no-update feedback with the installed version. Ordinary update dialogs fade in and out in place; consecutive prompts replace the card content and reset its scroll position while retaining the dark translucent backdrop without blurring the parent page. `DSH_DESKTOP_UPDATE_CHECK_INTERVAL_MS` configures the ordinary base interval, and `DSH_DESKTOP_UPDATE_CHECK_MAX_BACKOFF_MS` configures the cap; both accept integer milliseconds from 1000 through 2147483647, with the cap at least the interval. An omitted cap defaults to the larger of one hour and the interval. `DSH_DESKTOP_UPDATE_CHECK_JITTER` sets the fractional jitter from 0 through 1, defaulting to `0.2`; the final delay is at least one second and never exceeds the cap. These settings do not change mandatory-policy polling or authorize download retries. -The lower-left account row displays localized availability, a spinner with download percentage, verification, readiness, or a persistent red retry action with an accessible tooltip. This Web-embedded copy follows the active in-application language; native dialogs use the Desktop shell locale. The collapsed sidebar shows a dot on its top expand button. Connection status takes priority. Selecting an available release starts downloading immediately. Successful preparation automatically opens a shell-owned restart confirmation; closing it retains readiness without reopening the dialog. Selecting the ready entry opens confirmation again. Running agents, queued input, and running or stopping jobs trigger an interruption warning in that confirmation. API requests alone do not trigger the warning. After approval, the Host locks new requests, drains admitted requests, and rechecks tasks, including work created by an admitted write. A drain that exceeds the control-request deadline refuses installation and unlocks admission. Unknown task status, newly started work without interruption approval, or unsuccessful graceful teardown prevents installation. Ordinary quit hides the product window before stopping the Host, ignores new focus requests during teardown, and never installs an update. The next launch reconciles the version-bound runtime through the existing startup and recovery path. +The lower-left account row displays localized availability, a spinner with download percentage, verification, readiness, or a persistent red retry action with an accessible tooltip. This Web-embedded copy follows the active in-application language; native dialogs use the Desktop shell locale. The collapsed sidebar shows a dot on its top expand button. Connection status takes priority. Selecting an available release starts downloading immediately. Successful preparation automatically opens a shell-owned restart confirmation; closing it retains readiness without reopening the dialog. Selecting the ready entry opens confirmation again. Running agents, queued input, and running or stopping jobs trigger an interruption warning in that confirmation. API requests alone do not trigger the warning. After approval, the Host locks new requests, drains admitted requests, and rechecks tasks, including work created by an admitted write. A drain that exceeds the control-request deadline refuses installation and unlocks admission. Unknown task status, newly started work without interruption approval, or unsuccessful graceful teardown prevents installation. Ordinary quit asks about interruptible work as described under Closing the window and quitting, then hides the product window before stopping the Host, ignores new focus requests during teardown, and never installs an update. The next launch reconciles the version-bound runtime through the existing startup and recovery path. If task teardown fails after confirmed Host exit, installation is refused and the shell restores the current-version Host before allowing another restart confirmation. Installer launch failure after a clean Host stop uses the same recovery. After the replacement Host authenticates, the shell reloads the existing application URL so the Web page obtains its current port, cookie, and boot injections; page-load failure opens native fatal recovery. An unconfirmed process exit never permits a replacement Host. The downloaded target remains available for retry. A known mandatory policy remains blocking throughout recovery; unsuccessful Host restoration opens the native fatal-recovery dialog. @@ -371,7 +399,7 @@ The [mandatory client decision](../../.agents/notes/implemented/feature/2026-09- | `maxBackoffMs` | Maximum failed-request interval including jitter; default `3600000`, at least `intervalMs` | | `jitter` | Random additional interval fraction; default `0.2`, allowed range `0` through `1` | -Durations are integers from 1000 through 2147483647 milliseconds. Startup and scheduled polling are independent of business requests; foreground/resume checks respect the next due time, while manual checks bypass it and join any request in flight. The client sends the installed platform, architecture, exact shell and bundled dsh versions, application ID, locale, and fixed Nightly. It uses no business login credentials or installation ID. +Durations are integers from 1000 through 2147483647 milliseconds. Startup and scheduled polling are independent of business requests; foreground/resume checks respect the next due time, while manual checks bypass it and join any request in flight. The client sends the installed platform, architecture, DSH_CLIENT_VERSION, bundled dsh version, current locale and UTC offset, an empty bundle ID, and fixed Nightly. It uses no business login credentials or installation ID. With `feishu-test`, an HTTP 401 JSON response containing `error.code: "UNAUTHENTICATED"` offers login during user-initiated checks and the packaged application's initial startup check, without waiting for the local backend. A localized explanation identifies the test build, the need for Feishu authentication, and that login neither downloads nor installs updates. Confirmation closes the explanation before opening a sandboxed window at the configured origin’s root, not a response-provided login URL. Concurrent checks reuse the entire confirmation/login operation and focus its existing window. Press F12 in the test login window to open detached DevTools for diagnosis. Cancellation does not trigger repeated prompts from periodic or foreground checks; users can retry manually. @@ -395,11 +423,11 @@ node apps/desktop/node_modules/pnpm/bin/pnpm.mjs --dir apps/desktop run test:upd The command builds the Desktop shell and runs its coordinator with real Electron HTTP requests and `NsisUpdater` against a private loopback server. It checks user-authorized full downloads, SHA-512 rejection, explicit retry, concurrent request coalescing, feed replacement, and installation handoff. It also opens the real mandatory-update renderer with its sandboxed preload and checks button actions, close/Esc prevention, text-only content, a stalled policy request, and policy clearance. Success prints `LOCAL_UPDATER_RESULT` and exits with code zero; functional failure exits nonzero. Each invocation owns a random port and temporary user-data/cache directory, closes the listener, waits for Electron exit, and removes its temporary files. Reports and available screenshots remain in a unique `.desktop-build/qualification/local-updater-*` directory. Screenshot failure is recorded separately, never reported as visual acceptance. No COS or signing credentials are required. -The downloaded bytes are inert, and the installation call is recorded rather than executed. The test substitutes browser opening and clipboard writing to avoid external navigation and clipboard changes. It does not boot the full product workspace, qualify a real installer or restart, verify publisher signatures, or exercise differential updates or macOS. Stalled policy requests, feed requests, and payload transfers exercise real deadlines and recovery. The actual ordinary dialog verifies isolated preload loading, card geometry, background blur, cancellation, task-warning choices, and explicit installation approval; account-row component tests provide separate evidence. The [local qualification decision](../../.agents/notes/implemented/testing/2026-09-10-desktop-local-updater-qualification.md) and [verification record](tests/README.md) preserve these limits; production release requirements remain unchanged. +The downloaded bytes are inert, and the installation call is recorded rather than executed. The test substitutes browser opening and clipboard writing to avoid external navigation and clipboard changes. It does not boot the full product workspace, qualify a real installer or restart, verify publisher signatures, or exercise differential updates or macOS. Stalled policy requests, feed requests, and payload transfers exercise real deadlines and recovery. The actual ordinary dialog verifies isolated preload loading, card geometry, an unfiltered parent page, cancellation, task-warning choices, and explicit installation approval; account-row component tests provide separate evidence. The [local qualification decision](../../.agents/notes/implemented/testing/2026-09-10-desktop-local-updater-qualification.md) and [verification record](tests/README.md) preserve these limits; production release requirements remain unchanged. ## Low-level development overrides -An unpackaged Electron process uses `.desktop-build/development/project` under its application directory as its development project. `DSH_DESKTOP_PNPM_ENTRY` and `DSH_DESKTOP_DSH_DIR` select explicit runtime resources. Packaged applications ignore these variables, resolve signed resources from `process.resourcesPath`, and use the managed Desktop profile. +An unpackaged Electron process uses `.desktop-build/development/project` under its application directory as its development project. `DSH_DESKTOP_PNPM_ENTRY` and `DSH_DESKTOP_DSH_DIR` are optional overrides with application-path defaults. `DSH_DESKTOP_PRIMARY_RUNTIME_DIR` is required for every unpackaged launch: the development launchers (`dev:desktop`, `start:desktop`, and the workspace-update qualification runner) set it to the primary-runtime directory of the target they prepared, and a launch without it fails with the fatal startup dialog. The launcher must set it because the shell cannot derive that directory from `process.arch`: the build target fixes Windows to x64 while the host may be arm64. Packaged applications ignore these variables, resolve signed resources from `process.resourcesPath`, and use the managed Desktop profile. ## Known limitations @@ -408,8 +436,13 @@ An unpackaged Electron process uses `.desktop-build/development/project` under i - Release signing, notarization, update hosting, and previous-version installed-artifact qualification require the production release environment. - Dependency lifecycle scripts follow pnpm’s build permissions; Desktop provides no separate approval dialog. - The desktop shell shares sessions, settings, credentials, workspaces, and storage under `$DSH_HOME` with CLI dsh, while executable packages, plugin activation, and lockfiles remain separate. +- Unpackaged startup on an Electron win32-arm64 host now succeeds, but the payload remains x64: the architecture check in `packages/skill/tool-workspace-dependencies/src/index.ts` compares the recorded payload architecture against the host `process.arch`, so the `load_workspace_dependencies` tool can still reject the primary runtime. -Sign in opens the configured platform page in the system browser. The Host owns PKCE and a temporary loopback callback, saves the credential before entering the workspace, and redirects the browser to the platform completion page. Opened and copied authorization links carry the effective Desktop theme as `theme=light` or `theme=dark`; `system` resolves at the time of the action. Cancel withdraws the local attempt even if the platform page later approves it. Settings offers Account sign-out; without a separate API key, sign-out returns to the welcome window. Packaged applications register dsh://open to show the window without passing credentials. On macOS, the development launcher prepares an ad-hoc-signed `Harness Dev.app` under `.desktop-build/development`, declares `dsh` in its Info.plist, and registers it with Launch Services. It loads the current workspace and records the selected development home, browser-data path, and debug settings for cold starts. Starting this bundle makes it the default `dsh://` handler; starting the packaged application registers the packaged handler again. The generated bundle does not contain account tokens and requires the workspace and prepared runtime to remain available. +The app-only `dshOnboarding.hasApiKey()` preload method returns the welcome backend’s current API-key presence boolean; native login and onboarding share credential discovery, and only the owned application main frame may invoke it. + +Sign in opens the configured platform page in the system browser. The Host owns PKCE and a temporary loopback callback, saves the credential before entering the workspace, and redirects the browser to the platform completion page. Opened and copied authorization links carry the effective Desktop theme as `theme=light` or `theme=dark`; `system` resolves at the time of the action. Cancel withdraws the local attempt even if the platform page later approves it. Settings offers Account sign-out; without a separate API key, sign-out returns to the welcome window. Successful browser sign-in switches Welcome to the workspace without activating the application; the completion page’s dsh://open link brings it to the foreground. Packaged applications register dsh://open to show the window without passing credentials. On macOS, the development launcher prepares an ad-hoc-signed `Harness Dev.app` under `.desktop-build/development`, declares `dsh` in its Info.plist, and registers it with Launch Services. It loads the current workspace and records the selected development home, browser-data path, and debug settings for cold starts. Starting this bundle makes it the default `dsh://` handler; starting the packaged application registers the packaged handler again. The generated bundle does not contain account tokens and requires the workspace and prepared runtime to remain available. + +When an expired account returns to Welcome, the main process retains a one-time notification until the renderer requests it over window-owned IPC. Reloading Welcome does not repeat the notice; manual sign-out and cold startup do not create it. An expired login displays a timeout heading with explicit Sign in again and Add API Key actions. Opening the API-key form dismisses the authorization view; late account-state notifications do not replace an in-progress key entry. diff --git a/apps/desktop/README.zh.md b/apps/desktop/README.zh.md index 895fdd9721..62e34fad48 100644 --- a/apps/desktop/README.zh.md +++ b/apps/desktop/README.zh.md @@ -10,22 +10,44 @@ Desktop 的本地原生目录流程打开绑定应用窗口的 Electron 文件 Creator 和 Web Plugin Manager 在 Electron Node 模式下使用 Desktop 内置 pnpm,无需 PATH 中存在 pnpm。私有 Node 启动器环境仅应用于包操作。 -内嵌 Platform 文档使用独立且不持久化的 WebContentsView 会话。Host 通过私有 Node IPC 发送账号凭证;账号 RPC 和 Harness 渲染进程不接收 token。Platform preload 在页面脚本执行前通过一次同步 IPC 读取主进程中已准备的凭证。它暴露 displayMode、同步的 getAuthToken() 和 getLocale() getter,以及返回取消订阅函数的 onLocaleChange(listener)。两个 getter 都只读取 preload 内存,不再调用 IPC。bootstrap 包含 Desktop 已解析的语言(`zh_CN` 或 `en_US`);Settings 语言变更会更新 preload 缓存并通知已打开的 Platform 文档,无需重载。Platform 在首屏渲染前应用该语言,且不将其持久化为浏览器偏好。主进程处理器仅校验调用来源并读取内存,不等待 Host、磁盘或网络。可信页面初始化失败时保留内嵌模式,由 getter 抛错,避免回退到浏览器凭证。只有受控 Platform 页面中、位于所配置签发来源的主 frame 能完成初始化。退登、凭证替换、Host 关闭及视图关闭都会销毁文档。跨来源文档导航被阻止。请求新窗口的 HTTPS 链接在系统浏览器中打开,不携带内嵌会话或 token;其他协议及带 URL 凭证的链接被拒绝。原生视图占据 Account 功能返回栏下方的视口。 +Platform 内嵌文档使用持久化 WebContentsView 分区,分区名由 Platform 来源和稳定账号 ID 的哈希决定。localStorage 中的页面偏好(包括已关闭的通知)在关闭视图和重启应用后保留;不同账号和来源使用独立存储。账号 ID 来自 Host 最近一次成功的资料读取;尚无该 ID 时,文档在一次性分区中打开,该分区不跨次保留偏好。打开持久分区会先清理 Cookie、文件系统、IndexedDB、Cache Storage、HTTP 与着色器缓存、Service Worker 及 HTTP 认证状态;一次性分区则清理其全部存储。关闭视图会销毁文档、移除请求拦截器并安排相同的清理,因此异常退出遗留的认证会在下一个文档加载前被清除。下次打开和应用退出都会等待该清理完成,更新安装也会在安装器接管退出前等待。清理失败会使该次打开失败,并在后续清理成功前阻止同一账号打开;其他账号不受影响。退出登录会销毁文档,但保留账号偏好供下次登录使用。同一凭证下账号 ID 迟到时,已以一次性分区打开的文档保持挂载;下次打开使用账号分区。[存储决策](../../.agents/notes/implemented/architecture/2026-09-22-platform-browser-storage.zh.md)说明保留策略。Host 通过私有 Node IPC 发送账号凭证;账号 RPC 和 Harness 渲染进程不接收 token。Platform preload 在页面脚本执行前通过一次同步 IPC 读取主进程中已准备的凭证。它暴露 displayMode、同步的 getAuthToken() 和 getLocale() getter,以及返回取消订阅函数的 onLocaleChange(listener)。两个 getter 都只读取 preload 内存,不再调用 IPC。bootstrap 包含 Desktop 已解析的语言(`zh_CN` 或 `en_US`);Settings 语言变更会更新 preload 缓存并通知已打开的 Platform 文档,无需重载。Platform 在首屏渲染前应用该语言,且不将其持久化为浏览器偏好。主进程处理器仅校验调用来源并读取内存,不等待 Host、磁盘或网络。可信页面初始化失败时保留内嵌模式,由 getter 抛错,避免回退到浏览器凭证。只有受控 Platform 页面中、位于所配置签发来源的主 frame 能完成初始化。退登、凭证替换、Host 关闭及视图关闭都会销毁文档。跨来源文档导航被阻止。请求新窗口的 HTTPS 链接在系统浏览器中打开,不携带内嵌会话或 token;其他协议及带 URL 凭证的链接被拒绝。原生视图占据 Account 功能返回栏下方的视口。 -Desktop Host 的 Platform API 请求与更新策略请求使用相同的 `x-client-platform` 映射。账号 provider 管理[仅 API 使用的请求头配置](../../packages/credentials/deepseek-account-platform/README.zh.md#use-this-package)。 +Desktop Host 的 Platform API 请求与更新策略请求用相同的 Platform 客户端请求头标识已安装客户端:平台、客户端版本、语言、以秒为单位的时区偏移,以及有意保持为空的 bundle id。账号操作按调用逐次传入调用界面的身份;账号 provider 管理[仅 API 使用的请求头配置](../../packages/credentials/deepseek-account-platform/README.zh.md#use-this-package)。更新策略额外上报架构、更新通道和内置运行时版本。 + +账号凭据被服务端判定失效后,未配置官方 API key 时返回 Welcome;有可用 API key 时保持工作区打开。主动退出登录遵循相同规则。Welcome 和工作区均显示本地化的登录失效提示。 桌面麦克风访问仅允许主 `dsh-app://app` 页面发起的音频请求。macOS 使用系统麦克风授权与随包用途说明。 按 F12(多媒体功能键键盘上为 Fn+F12)、macOS 的 Command+Option+I 或 Windows 的 Ctrl+Shift+I,可切换当前获得焦点的应用页面的 DevTools,打包版本同样支持。这些原生快捷键通过隐藏的应用菜单项注册。更新遮罩和打包版本的内嵌浏览器禁用 DevTools。 +## 关闭窗口与退出 + +关闭主窗口(macOS 的关闭按钮和 ⌘W;Windows 的 ×、Alt+F4 和任务栏"关闭窗口")会隐藏窗口;Windows 首次隐藏前需要确认。页面和 Host 继续运行,任务不受影响,下次显示时仍是原来的文档,会话、草稿和滚动位置都保留;macOS 全屏窗口先退出全屏再隐藏。macOS 通过 Dock 图标、再次启动或 `dsh://open` 找回窗口,Windows 通过托盘找回。最小化行为不变。进入工作区前关闭欢迎窗口,Windows 上走退出流程,macOS 上应用留在 Dock 中且没有窗口。 + +Windows 在整个运行期间常驻托盘图标。悬停提示为产品名,单击显示并聚焦窗口,右键菜单提供壳语言下的"打开 DeepSeek Harness"和"退出 DeepSeek Harness"。首次隐藏前复用更新弹窗,显示“正在运行的任务不会中断,可在系统托盘中重新打开窗口”和“确认”按钮。确认后隐藏窗口,并在 Electron userData 下写入 `background-close-confirmed`;Esc、关闭弹窗或加载失败均保持主窗口可见,不记录确认。重复关闭请求会聚焦已有壳弹窗。覆盖更新保留标记,卸载删除标记。旧的 `background-notice-shown` 标记不会跳过此确认。关闭窗口不发送系统通知。托盘位图是 `resources/tray-windows.ico`,由 `pnpm run render:tray-icon` 从 `resources/icon-windows.svg` 按 16、20、24、32、40、48、64 像素分别渲染,打包为 `resources/tray.ico`。macOS 不提供菜单栏图标。 + +所有普通退出入口——⌘Q、应用菜单、Dock 菜单、Windows 托盘和标题栏"应用程序"菜单,以及关闭强制更新窗口或欢迎窗口引起的退出——都先向 Host 查询退出会中断什么。Host 通过私有 IPC 通道回答两项事实:与更新重启检查同一口径的运行中任务(运行中的 agent,包括子代理和等待审批的回合、排队消息、运行中或停止中的后台任务),以及本次运行中已加载会话里由 `workspace/session-activity` 的 `schedule` family 报告的已挂定时器的提醒。两项都没有时直接退出,不弹框。否则弹出一个没有父窗口的原生消息框——隐藏的窗口保持隐藏——标题为**退出 DeepSeek Harness?**,正文为三种本地化说明之一:正在运行的任务将会中断、应用关闭期间定时任务不会运行,或两者兼有。"退出"是默认按钮,Esc 等同"取消";macOS 上"取消"在"退出"左侧,Windows 上"退出"在"取消"左侧,Windows 任务对话框显示应用图标且不跟随应用主题、始终为浅色。Host 尚未就绪或已失败时不可能有任务在跑,直接退出。查询失败或 Host 超过两秒截止时间未答复,按运行中任务处理。弹框打开期间,再次请求退出只会并入同一弹框而不叠加新弹框(macOS 上还会把它提到前面;Electron 不暴露 Windows 任务对话框的句柄);任务开始或结束不会改变文案;点"退出"不再重新查询即停止应用;点"取消"不发生任何变化。取消由关闭欢迎窗口引起的退出时,欢迎窗口会重新显示。 + +以下情况跳过确认:安装更新的重启已确认过任务中断、致命错误恢复对话框中的退出或重启、开发版"重启应用与 Host"命令,以及操作系统关机、重启或注销:Windows 在确定性的会话结束消息上设置该状态;macOS 在关机通知上设置,而其他应用仍可能取消这次关机,因此主窗口下一次获得焦点或显示时会清除它。安装器接管退出时会取消尚未结束的普通退出决策;晚到的查询结果和弹框答复不会再次打开确认框或重复清理。窗口隐藏期间完成的用户主动发起的更新下载,把"安装并重启"确认推迟到窗口再次显示时;强制更新流程沿用其任务栏和 Dock 提醒。Windows 安装程序和卸载程序在应用仍在运行时提示用户先在系统托盘中退出。Desktop 默认未开启定时任务,定时任务的说明只在该功能开启后出现;提醒只在已加载的会话中触发,未加载的会话既不计入,也要等到打开后才会继续。 + +托盘渲染器以底板中心为基准将鲸鱼放大 20%,保留背景和宽高比;应用和安装器图标保持原有比例。 + ## 关键技术决策 设计师原稿位于 `resources/icon.png` 和 `resources/icon.svg`;平台适配保留鲸鱼与渐变,分别位于 `resources/icon-windows.*` 和 `resources/icon-macos.*`。将各平台 SVG 导出为透明的 1024×1024 PNG。electron-builder 为 Windows 应用、安装程序和卸载程序生成多尺寸 ICO([Windows 图标要求](https://learn.microsoft.com/en-us/windows/apps/design/iconography/app-icon-construction))。安装页面在两种主题下使用匹配的图案;卸载程序的欢迎和完成页共用 `installer/assets/uninstaller-sidebar.png`,准备阶段将其转换为 164×314 BMP。 +快捷键覆盖保存在 `app.getPath('userData')/keybindings.json`,与 `DSH_HOME` 分离。主进程校验并串行保存修改后才发布已接受键位。读取失败保留上次接受的键位并阻止编辑,包括全部恢复;不可读和未来版本的文件保持不变。开发时可通过 `DSH_DESKTOP_USER_DATA_DIR` 隔离这些偏好,启动器会输出解析后的路径。格式和冲突语义见[快捷键服务](../../packages/client/shortcuts/README.zh.md)。 + +macOS“文件”菜单显示已接受的单键绑定(包括方向键),并通过 Client 页面 owner 路由“关闭页面或窗口”。Windows 和 macOS 在主文档、内嵌 frame 和浏览器 guest 输入之前拦截所有已接受的完整绑定,包括编辑和终端输入。录制和输入法组合状态仍受保护。更新蒙层从创建到最后一个蒙层关闭期间阻挡父窗口及其浏览器 guest 的产品快捷键和编辑按键递送。每次打开或关闭蒙层都会作废待完成的组合键状态。主进程通过显式的创建能力和输入状态读取能力,让更新对话框与快捷键输入共享同一个蒙层管理实例。双键组合会将首键的初次按下事件交给页面,且不拦截其松开事件;完整组合及其重复事件会被消费。渲染进程将可配置绑定的分发交给原生适配器。双键组合不注册原生菜单快捷键。已接受的命令通过可信 preload 转发一次。Linux 通过 DOM 分发主文档快捷键,并将已接受的内嵌 frame 绑定转发给 Client 解析器。关闭最后一个窗口后 macOS 保留应用生命周期;Windows 退出桌面实例并停止其任务。[关窗决策](../../.agents/notes/implemented/architecture/2026-09-21-desktop-page-close-shortcuts.zh.md)记录了这一生命周期选择。 + macOS PNG 使用带留白的圆角底板,供传统 ICNS 打包使用,包含最高 1024 像素的表示。它是扁平图标,并非 Icon Composer 文档。Apple 的[应用图标指南](https://developer.apple.com/design/human-interface-guidelines/app-icons)要求向 Icon Composer 提供未遮罩的图层;这些输入需要在 macOS 上单独导出,不能复用已做圆角的 ICNS 图案。发布前须在支持的 macOS 版本中验收 Finder 和 Dock 的显示效果。 + + ### 内置工作区依赖 +electron-builder 只把清单中的 `dependencies` 复制进 `app.asar/node_modules`,因此 Electron 主进程 bundle `lib/main.js` 内联其工作区 devDependencies,裸导入只剩 `electron`、Node 内置模块与这些 `dependencies`;沙箱 preload 只能留下 `electron`、`events`、`timers` 与 `url`,即其 `require` polyfill 能解析的模块。主进程 bundle 从被内联包的 `lib/` 产物解析它们,所以根 `build:lib:host` 在并发的工作区 tsdown 阶段之后才为 `apps/desktop` 打 bundle,并由 [`desktop-bundle-imports`](scripts/desktop-bundle-imports.mjs) 让任何静态、动态或 `require()` 导入无法在打包应用内解析的 Desktop bundle 直接失败。没有这项检查时,rolldown 无法解析的导入会作为外部说明符进入产物,并在启动时以 `ERR_MODULE_NOT_FOUND` 失败。[bundle 顺序决策](../../.agents/notes/implemented/process/2026-09-22-desktop-main-bundle-after-workspace-tsdown.zh.md)记录了备选方案。 + Windows 签名打包按 PE 文件内容扫描第一方运行时和应用生产依赖,包括没有常规扩展名的文件。最终扫描覆盖整个解包应用。目录链接、格式错误的 `MZ` 文件以及非 PE 的 `.exe`、`.dll` 或 `.pyd` 文件会使打包停止;以 `MZ` 开头的数据文件也会被拒绝,除非包含有效 PE 头。它保留有效的上游签名,并在记录运行时哈希或执行冒烟检查前为未签名代码补签。公钥验签每个进程处理最多 32 个文件,同时最多运行四个进程;硬件令牌签名仍串行执行,每个新签名必须匹配配置的证书且带时间戳。硬件签名或验签失败会停止本轮执行;独立的时间戳请求遵循下文的有界重试规则。electron-builder 只有在验签和逐字节比对通过后,才保留复制后运行时可执行文件的签名。写入发布完成记录前,必须通过最终 PE 签名检查,以及使用全新缓存的 ASAR 载荷和 Host 冒烟检查。开发、仅准备和未签名构建不使用硬件令牌,可能被 Windows 代码完整性策略阻止;任何构建模式都不会关闭该策略。冒烟检查通过不代表兼容所有企业策略。 Desktop 携带独立的 Python、Node.js 和 pnpm 分发包。Python 包含 numpy、pandas、python-docx、python-pptx、openpyxl、Pillow、lxml、XlsxWriter 及其完整依赖。`load_workspace_dependencies` 工具首次使用时,将该产物离线安装到 `$DSH_HOME/dsh-runtimes/dsh-primary-runtime`(通常为 `~/.dsh/dsh-runtimes/dsh-primary-runtime`),并返回解释器、pnpm 脚本和库目录的绝对路径,以及记录内置分发包名称与版本的 `pythonDistributions`。版本报告不包含用户自行安装的包。Office 任务默认使用这些库,用户或工作区指令指定其他环境时遵循其要求。pnpm 脚本通过返回的 Node 可执行文件运行。返回的 Node 库目录为随包交付的库预留,不是 pnpm 的全局安装目录。 @@ -50,11 +72,13 @@ Node 准备内置解释器和 Python 库,无需系统 Python 或 pip。[下载 [薄壳决策](../../.agents/notes/implemented/architecture/2026-09-10-desktop-web-wrapper.zh.md)负责共享 Web 行为与 Desktop 适配。[Electron 打包与更新决策](../../.agents/notes/implemented/architecture/2026-08-25-electron-desktop-packaging-and-updates.zh.md)负责发布身份、签名及更新验收。 +Welcome 加载共享 Toast 的配色和阴影变量,挂载在 body 下的通知使用系统字体。 + ## 安装归属 Electron 拥有 `$DSH_HOME/profiles/desktop`。其 `dependencies` 包含 pnpm 安装的包;`dsh.profile.bundles` 包含内置 bundle,后接已启用插件。签名应用从 `resources/app.asar/dsh` 提供 dsh、私有 Desktop Host 及其生产依赖。打包应用选择 runtime profile 解析,不创建包链接;开发 profile 使用文件系统链接。宿主与插件在同一个 Electron Node 模式进程中执行;Desktop 不启用 `--preserve-symlinks`。CLI 不能启动或修改此 profile。 -应用 preload 只向 `dsh-app://app` 文档暴露启动就绪、致命启动失败上报、原生目录选择、用于 composer 路径引用的 `__DSH_HOST_PATHS__` 桥接和租约范围内的 Browser 桥接。产品页面还获得 Desktop 标记、更新展示数据和打开原生确认的操作,不能选择安装产物或授权安装。插件管理使用 Web 应用经过认证的 HTTP API;Electron 在 `dsh-app://shell/` 本地提供更新弹窗文档和资源,不依赖 Host 就绪。Electron 不提供插件管理 IPC 或独立管理页面。 +应用 preload 只向 `dsh-app://app` 文档暴露启动就绪、致命启动失败上报、原生目录选择、用于 composer 路径引用的 `__DSH_HOST_PATHS__` 桥接和租约范围内的 Browser 桥接。产品页面还获得 Desktop 标记、更新展示数据和打开原生确认的操作,不能选择安装产物或授权安装。插件管理使用 Web 应用经过认证的 HTTP API;Electron 在 `dsh-app://shell/` 本地提供更新弹窗文档和资源,不依赖 Host 就绪。Electron 不提供插件管理 IPC 或独立管理页面。任何渲染进程都不会获得文件系统访问、原始 Electron IPC、shell 或任意 pnpm 参数。 只有主应用窗口启用 ``。guest 挂载必须匹配主进程签发的租约和分区;guest 保持 sandbox、context isolation 和 Web security,不启用 Node integration 或 guest preload。Browser IPC 监听只为应用文档创建。[Sidebar Browser](../../packages/client/ui-sidebar-browser/README.zh.md) 说明存储分组和 guest 限制;Host 鉴权仍独立于 URL 过滤而必需。 @@ -64,9 +88,9 @@ Electron 拥有 `$DSH_HOME/profiles/desktop`。其 `dependencies` 包含 pnpm Electron 根据应用语言选择类型化的英文或中文 shell 文案,并回退到英文。macOS 应用包通过 `CFBundleLocalizations` 声明支持英语和简体中文,让 macOS 根据用户的首选语言匹配初始应用语言。主界面仍优先使用已保存的 Client UI 语言偏好。在 Windows 上,主文档的语言会更新桌面菜单、恢复与更新提示。仓库 Client UI i18n 检查覆盖桌面端源码。 -Windows 使用 40 DIP 顶栏,保留原生窗口按钮,颜色随应用调色板同步。侧栏开关旁的本地化“应用”和“编辑”入口打开原生弹出菜单。仅当应用框架发布 shell overlay 席位后才挂载菜单,启动加载期间不显示。“应用”提供检查更新和退出;“编辑”向当前编辑器发送对应按键,提供撤销、重做、剪切、复制、粘贴、删除和全选。插件管理使用主应用的“插件”页面。按 Alt 不会出现额外的原生菜单行。其他平台保留原生菜单。可编辑区域保留快捷键和不带快捷键标注的右键菜单;命令可用状态由 Chromium 提供,选中的只读文本提供“复制”命令。 顶栏菜单保留鼠标和键盘操作,顶栏中的 Web 控件仍可触达。共享 DOM 只约束展示,不构成安全边界:产品脚本可以隐藏蒙层,但不能借此清除主进程策略或授权安装。更新操作与状态通过隔离预加载和壳 frame 之间的私有 MessageChannel 传递。 +Windows 使用 40 DIP 顶栏,保留原生窗口按钮,颜色随应用调色板同步。侧栏开关旁的本地化“应用”和“编辑”入口打开原生弹出菜单。仅当应用框架发布 shell overlay 席位后才挂载菜单,启动加载期间不显示。“应用”提供检查更新和退出;“编辑”向当前编辑器发送对应按键,提供撤销、重做、剪切、复制、粘贴、删除和全选,不受自定义快捷键绑定影响。插件管理使用主应用的“插件”页面。按 Alt 不会出现额外的原生菜单行。其他平台保留原生菜单。可编辑区域保留快捷键和不带快捷键标注的右键菜单;命令可用状态由 Chromium 提供,选中的只读文本提供“复制”命令。 -macOS 上自定义应用菜单还会声明标准的 File、Window 和应用菜单,因为替换 Electron 的默认菜单会丢掉 Close Window(⌘W)、Minimize(⌘M)和 Hide(⌘H)。Linux 保留应用菜单和 Edit 菜单。 +macOS 上自定义菜单保留 Electron 的标准 Window 菜单及应用隐藏命令,包括 Minimize(⌘M)和 Hide(⌘H)。Linux 保留应用菜单和 Edit 菜单。 ### 运行时与插件激活 @@ -88,7 +112,6 @@ macOS 上自定义应用菜单还会声明标准的 File、Window 和应用菜 恢复操作等待 Host 关闭后才修改插件启用状态。原生恢复操作在 profile 事务锁内调用共享 app-boot 恢复函数。它禁用第三方 bundle,并将 profile 的 `cordis.patch.yml` 重命名为 `cordis.patch.yml.bak-`(重名时追加序号),无需解析;下次启动创建空 patch。已安装包和已有备份保留。home 级 patch 不变。Electron 控制台记录备份路径(或原文件不存在)以及 home 级 patch 未修改。profile 数据无效、重命名失败或写入失败会作为恢复操作错误报告;已完成的修改保留,Desktop 不会假装恢复成功后重启。Desktop 不提供 profile 重置操作或应急 HTML 文档。 - ## 开发 开发环境应用菜单提供“刷新页面”(macOS 为 Cmd+R,其他平台为 Ctrl+R)和“重启应用与 Host”。重启会等待 Host 关闭,再重新启动 Electron 和新的 Host;这两项操作都不会重新构建源码。 @@ -109,9 +132,12 @@ pnpm run start:desktop Web 侧的对应命令是 `pnpm run dev:web` 与 `pnpm run start:web`,见[开发指南](../../docs/development.zh.md)。Workspace 开发使用 Electron RunAsNode 运行当前 CLI 与私有 Desktop Host 包,插件管理和恢复使用 `$DSH_HOME/profiles/desktop`,与一次性工作区运行时分离。Host 在开发与打包构建中都使用 runtime 模块解析,不创建官方包的 fallback 链接;开发者安装的包(包括链接)保留原生优先级。需要验证 Electron RunAsNode、内置 pnpm、内置 dsh 资源、插件安装和修复时,应运行未封装安装器的应用目录。 +[原生输入与渲染进程键盘测试](tests/keyboard.spec.ts)在[独立的 Client 测试项目](../../tsconfig.desktop-keyboard-tests.json)中编译,由仓库 Client 类型检查纳入。它只导入不依赖 Cordis 的 Desktop 输入、持久化、IPC、浏览器 guest 和蒙层模块。 ### 启动引导 +API Key 输入框初始为空,并通过 `autocomplete="new-password"` 请求 Chromium 不要自动填入已保存的登录密码。 + 重复启动和 `dsh://open` 会保持工作区隐藏,直到启动凭据检查或欢迎页操作允许进入。从 Welcome 进入时,键盘焦点落在文档上,不选中侧边栏控件;Tab 导航仍可使用。 Desktop 在 Host 启动后、打开工作区前检查模型 API Key 引用是否已配置。没有已配置的密钥时,欢迎窗口提供 [API Key 页面](https://www.figma.com/design/jRBBK7zBgcszdVWQ0Fh5J8/Harness?node-id=2138-44626)。“保存并继续”通过现有凭证服务写入 DeepSeek 官方提供方配置的引用,然后打开工作区。“稍后配置”打开工作区,但不保存草稿或完成标记;下次进程启动时会重新检查凭证。“返回登录”回到入口并清空未保存的密钥和校验提示。保存或打开工作区期间,按钮保持原文案并禁用竞争操作。Desktop preload 标记使 Web 凭证弹窗不再显示,同时保留模型设置页和欢迎须知。 @@ -195,7 +221,7 @@ Windows 发布验收还需在 Desktop 构建后手动运行[目录和替换检 pwsh -NoProfile -File apps/desktop/scripts/smoke-windows.ps1 -Makensis $Makensis -SevenZip $SevenZip -PluginDir $PluginDir -FrameLibrary apps/desktop/.desktop-build/targets/win-x64/installer-ui/window-frame.dll ``` -Windows 安装器先将新版本解压到安装目录旁边,再退出旧应用并通过同卷目录改名完成替换。同路径升级在替换成功前保留旧目录;解压失败时旧版不变,替换失败时尝试恢复旧目录。安装器在启动前清理旧版备份。强制结束安装器或断电可能留下 `.new-*` 或 `.old-*` 目录;不同安装位置或安装范围迁移仍使用 electron-builder 的旧卸载器流程。 +Windows 安装器在启动时和选定目标目录后检查应用是否正在运行,通过检查后才将新版本解压到安装目录旁边。通过同卷目录改名替换前,安装器会再次检查。运行中的应用会阻止安装;更新启动允许等待应用退出,最长十秒。同路径升级在替换成功前保留旧目录;解压失败时旧版不变,替换失败时尝试恢复旧目录。安装器在启动前清理旧版备份。强制结束安装器或断电可能留下 `.new-*` 或 `.old-*` 目录;不同安装位置或安装范围迁移仍使用 electron-builder 的旧卸载器流程。 解压失败时,安装器会把 7-Zip 的结果和完整错误输出写入更新缓存目录 `%LOCALAPPDATA%\<按包名派生>-updater\installer-logs\extract-failure-<时间戳>.log`(当前为 `@deepseek-aidsh-desktop-updater`),并在弹窗中显示首条错误行和 **复制错误信息** 按钮;静默安装只写入报告。未签名的 Windows 构建(`DSH_DESKTOP_UNSIGNED=1`)会将安装包命名为 `deepseek-harness-<版本>-win-x64-unsigned.exe`,以免被误当作发布产物。 @@ -255,7 +281,7 @@ Mac 打包从 `.env.macos` 读取三个调优字段: 两个代理字段互相独立,拒绝 URL 中的凭证、路径、查询参数和片段。空值沿用继承的网络设置。显式下载代理会替换子进程的代理变量,仅绕过本地主机;它不修改系统设置。Windows 与独立 `release:pack` 保持现有并发默认值。公司代理地址仅写入 Git 忽略的本地文件;具体地址参见内部文档。 -Apple 工具使用 macOS 当前活动网络服务的 HTTP/HTTPS 代理。配置公证代理后,打包会检查代理可达性、保存该服务的设置,在两条产物任务期间启用代理,并在两条任务均结束后恢复原设置。对于原本关闭、服务器为空且端口为零的代理,恢复时仅关闭代理;临时服务器和端口可能保留,但不生效。仅生成目录的打包会在签名目录构建完成后的 App 公证期间启用代理。这会临时影响其他应用,并要求修改系统代理的权限;必须先禁用 PAC、自动发现、SOCKS 及需要认证的代理配置。打包和恢复在读取恢复记录或修改代理前获取同一个用户级 POSIX 文件锁;进程退出会释放锁的持有权,锁文件保留。这会阻止不同 checkout 的代理事务重叠;其他用户及网络设置工具不得同时修改这些设置。SIGINT/SIGTERM 会等待活动任务结束后恢复。强制终止或恢复失败后,先停止残留公证进程,再运行 `pnpm --dir apps/desktop run restore:mac-proxy`;保存的记录会保留到恢复成功。配置检查仅验证 URL 语法,不修改系统设置或连接代理。 +Apple 工具使用 macOS 当前活动网络服务的 HTTP/HTTPS 代理。配置公证代理后,打包会检查代理可达性、保存该服务的设置,在两条产物任务期间启用代理,并在两条任务均结束后恢复原设置。对于原本关闭、服务器为空且端口为零的代理,恢复时仅关闭代理;临时服务器和端口可能保留,但不生效。仅生成目录的打包会在签名目录构建完成后的 App 公证期间启用代理。这会临时影响其他应用,并要求修改系统代理的权限;必须先禁用 PAC、自动发现、SOCKS 及需要认证的代理配置。打包和恢复在读取恢复记录或修改代理前获取同一个用户级 POSIX 文件锁;进程退出会释放锁的持有权,锁文件保留。该锁在首次使用时才加载 `@deepseek-ai/node-addon-system/flock`,而不是在脚本启动时加载,因此 `check:package` 和打包入口在未构建 `native/system` 的 checkout 上也能加载;加锁时若宿主 addon 二进制或入口的 JavaScript 缺失,加载器会先运行 `pnpm run build:native-system` 和 `pnpm --dir native/system run build:ts` 再加锁,因此恢复命令在这样的 checkout 上同样可用。这会阻止不同 checkout 的代理事务重叠;其他用户及网络设置工具不得同时修改这些设置。SIGINT/SIGTERM 会等待活动任务结束后恢复。强制终止或恢复失败后,先停止残留公证进程,再运行 `pnpm --dir apps/desktop run restore:mac-proxy`;保存的记录会保留到恢复成功。配置检查仅验证 URL 语法,不修改系统设置或连接代理。 ### 未签名 Windows 测试安装包 @@ -344,11 +370,15 @@ macOS 打包在组装 App 时、代码签名前写入 `Contents/Resources/app-up ## 更新 -打包应用在启动后异步检查固定 Nightly。常规轮询以十分钟为基础间隔,每次独立采样 ±20% 的随机抖动。每次检查失败将基础延迟翻倍,上限为一小时;成功后重置。随机延迟不超过该上限,并从全部复用调用结算后开始计时。本地化的“检查更新…”菜单项(Windows 可从顶栏的“应用”菜单进入)立即执行,并复用正在进行的检查。回到前台和系统恢复时遵守相同的单调时钟截止时间。新收到的强更策略也会立即请求检查更新清单。自动检查从不弹窗或下载安装包。手动检查显示正在检查、失败或包含已安装版本号的无更新反馈。常规更新弹窗原位渐入渐出;连续弹窗替换卡片内容并重置其滚动位置,保留蒙层与背景模糊。 +Windows 下载完成后的更新确认说明应用会在安装期间关闭、完成后自动打开,并提示期间不要重复启动。安装器携带 `--updated` 重启应用并直接打开工作区时,壳会将主窗口前置并聚焦一次,不启用永久置顶。启动进入欢迎页时会清除此请求,使后续登录保留正常的激活行为。普通启动和其他平台不执行此前置步骤。 + +原生更新浮层在文档就绪且父窗口可见时显示,并在父窗口再次显示时恢复。关闭浮层会释放输入拦截和父窗口监听。[本地窗口验证](tests/README.zh.md#verification-overlay)无需启动工作区即可检查这些切换。 + +打包应用在启动后异步检查固定 Nightly。常规轮询以十分钟为基础间隔,每次独立采样 ±20% 的随机抖动。每次检查失败将基础延迟翻倍,上限为一小时;成功后重置。随机延迟不超过该上限,并从全部复用调用结算后开始计时。本地化的“检查更新…”菜单项(Windows 可从顶栏的“应用”菜单进入)立即执行,并复用正在进行的检查。回到前台和系统恢复时遵守相同的单调时钟截止时间。新收到的强更策略也会立即请求检查更新清单。自动检查从不弹窗或下载安装包。手动检查显示正在检查、失败或包含已安装版本号的无更新反馈。常规更新弹窗原位渐入渐出;连续弹窗替换卡片内容并重置其滚动位置,保留黑色半透明蒙层,不模糊父页面。 `DSH_DESKTOP_UPDATE_CHECK_INTERVAL_MS` 配置常规基础间隔,`DSH_DESKTOP_UPDATE_CHECK_MAX_BACKOFF_MS` 配置上限;两者均接受 1000 至 2147483647 的整数毫秒数,且上限不能小于间隔。省略上限时取一小时与间隔中的较大值。`DSH_DESKTOP_UPDATE_CHECK_JITTER` 配置 0 至 1 的抖动比例,默认 `0.2`;最终延迟至少一秒,且不超过上限。这些配置不改变强更策略轮询,也不授权下载重试。 -左下角账户行显示本地化的更新可用状态、加载图标与下载百分比、验证、就绪状态,或带可访问提示的持久红色重试操作。嵌入 Web 界面的文案跟随应用内当前语言;原生弹窗使用 Desktop 壳语言。侧栏收起时,顶部展开按钮显示圆点。连接状态优先展示。选择可用版本即开始下载。准备成功后自动打开壳拥有的重启确认;关闭后保留就绪状态,不重复弹窗。选择就绪入口可再次打开确认。运行中的 agent、排队输入,以及运行中或停止中的后台任务都会在该确认中触发中断警告。仅有 API 请求不会触发警告。用户批准后,Host 锁定新请求,等待已接收的请求结束,再检查任务,包括已接收写操作创建的工作。等待超过控制请求截止时间时,拒绝安装并解除准入锁。任务状态未知、未获中断授权的新任务,或未成功完成正常收尾,都会阻止安装。常规退出会在停止 Host 前隐藏产品窗口,在收尾期间忽略新的聚焦请求,且从不安装更新。下次启动通过已有的启动与恢复流程校准版本绑定的运行时。 +左下角账户行显示本地化的更新可用状态、加载图标与下载百分比、验证、就绪状态,或带可访问提示的持久红色重试操作。嵌入 Web 界面的文案跟随应用内当前语言;原生弹窗使用 Desktop 壳语言。侧栏收起时,顶部展开按钮显示圆点。连接状态优先展示。选择可用版本即开始下载。准备成功后自动打开壳拥有的重启确认;关闭后保留就绪状态,不重复弹窗。选择就绪入口可再次打开确认。运行中的 agent、排队输入,以及运行中或停止中的后台任务都会在该确认中触发中断警告。仅有 API 请求不会触发警告。用户批准后,Host 锁定新请求,等待已接收的请求结束,再检查任务,包括已接收写操作创建的工作。等待超过控制请求截止时间时,拒绝安装并解除准入锁。任务状态未知、未获中断授权的新任务,或未成功完成正常收尾,都会阻止安装。常规退出先按"关闭窗口与退出"一节所述询问可中断的工作,再在停止 Host 前隐藏产品窗口,在收尾期间忽略新的聚焦请求,且从不安装更新。下次启动通过已有的启动与恢复流程校准版本绑定的运行时。 若任务收尾失败但已确认 Host 退出,安装会被拒绝,壳会在允许再次确认重启前恢复当前版本的 Host。Host 正常停止后的安装器启动失败使用同一恢复路径。替代 Host 启动并完成认证后,壳重新加载原有应用地址,让 Web 页面获取当前端口、Cookie 和启动注入数据;页面加载失败时打开原生致命故障恢复弹窗。未确认进程退出时,绝不允许启动替代 Host。已下载目标保留以供重试。已知强更策略在恢复过程中继续阻塞;Host 恢复失败打开原生致命故障恢复弹窗。 @@ -371,13 +401,13 @@ macOS 打包在组装 App 时、代码签名前写入 `Contents/Resources/app-up | `maxBackoffMs` | 含抖动的失败请求最大间隔;默认 `3600000`,不小于 `intervalMs` | | `jitter` | 随机增加的间隔比例;默认 `0.2`,范围为 `0` 至 `1` | -时长必须是 1000 至 2147483647 毫秒的整数。启动与定时轮询独立于业务请求;前台/恢复检查遵守下次到期时间,手动检查绕过该时间并复用在途请求。客户端发送已安装平台、架构、完整壳与内置 dsh 版本、应用 ID、语言和固定 Nightly。不使用业务登录凭据或安装 ID。 +时长必须是 1000 至 2147483647 毫秒的整数。启动与定时轮询独立于业务请求;前台/恢复检查遵守下次到期时间,手动检查绕过该时间并复用在途请求。客户端发送已安装平台、架构、DSH_CLIENT_VERSION、内置 dsh 版本、当前语言与 UTC 偏移、空 bundle ID 和固定 Nightly。不使用业务登录凭据或安装 ID。 启用 `feishu-test` 时,包含 `error.code: "UNAUTHENTICATED"` 的 HTTP 401 JSON 响应会在用户主动检查和打包应用首次启动检查时提供登录入口,不等待本地后端就绪。本地化说明指出这是测试版、需要飞书鉴权,且登录不会下载或安装更新。确认后先关闭说明,再打开配置源站根路径的沙箱窗口,不使用响应中的登录 URL。并发检查复用整个确认/登录流程,并聚焦已有窗口。在测试环境登录窗口按 F12 可打开独立的 DevTools 进行排查。取消后,定时或前台检查不会反复弹窗;用户可手动重试。 登录和策略请求共用内存 Session,与产品窗口及 updater 隔离;应用重启后需要重新登录。关闭窗口取消登录,导航失败提供本地化重试提示。返回服务后重新查询策略;重定向、Cookie 或 HTTP 422 都不是有效策略决定。取消、登录过期及无效响应均保留已知强更阻塞。固定登录结果写入进程诊断及可选更新日志;登录控制器不记录 Cookie、OAuth 参数或远程错误原文。真实 Harness 网关/API 联调及 macOS 登录验收仍未完成。 -扁平化的 `40005` 打开壳拥有的模态窗口,并拒绝后续插件修改,不停止现有 Host 任务。服务端标题与详情是可选纯文本,缺失时使用客户端兜底文案;缺少下载地址或地址未获批准时隐藏外部页面操作,不解除阻塞。macOS 强更蒙层原位渐入渐出,在更新状态切换时保留蒙层,并将父窗口焦点和键盘输入重定向到蒙层。Windows 由隔离的应用 preload 在主窗口内挂载 shell 来源的 frame,以蒙层和弹窗覆盖 40 DIP 顶栏下方的内容区域。它阻止背景页面输入,不创建额外的原生窗口;移动和最大化只作用于主窗口。父窗口保持启用,原生移动、缩放、最小化、最大化和关闭控件仍可操作。退出应用会完成清理,不会解除更新要求;Esc 不会关闭覆盖层。批准安装后,安装器接管的退出流程会在 Electron 关闭窗口前释放模态窗口。下载、含准备步骤的文件校验、任务检查和安装确认共用同一弹窗。只有第二次用户批准才允许任务收尾和安装;稍后更新保留阻塞与安装包。仅存在受影响任务时,重启文案才提示正在停止任务。策略不跨应用重启持久化,策略响应也不作废或替换 updater 产物。 +扁平化的 `40005` 打开壳拥有的模态窗口,并拒绝后续插件修改,不停止现有 Host 任务。服务端标题与详情是可选纯文本,缺失时使用客户端兜底文案;缺少下载地址或地址未获批准时隐藏外部页面操作,不解除阻塞。macOS 强更蒙层原位渐入渐出,在更新状态切换时保留蒙层,并将父窗口焦点和键盘输入重定向到蒙层。Windows 由隔离的应用 preload 在主窗口内挂载 shell 来源的 frame,以蒙层和弹窗覆盖 40 DIP 顶栏下方的内容区域。它阻止背景页面输入,不创建额外的原生窗口;移动和最大化只作用于主窗口。顶栏菜单保留鼠标和键盘操作,顶栏中的 Web 控件仍可触达。共享 DOM 只约束展示,不构成安全边界:产品脚本可以隐藏蒙层,但不能借此清除主进程策略或授权安装。更新操作与状态通过隔离 preload 和壳 frame 之间的私有 MessageChannel 传递。父窗口保持启用,原生移动、缩放、最小化、最大化和关闭控件仍可操作。退出应用会完成清理,不会解除更新要求;Esc 不会关闭覆盖层。批准安装后,安装器接管的退出流程会在 Electron 关闭窗口前释放模态窗口。下载、含准备步骤的文件校验、任务检查和安装确认共用同一弹窗。只有第二次用户批准才允许任务收尾和安装;稍后更新保留阻塞与安装包。仅存在受影响任务时,重启文案才提示正在停止任务。策略不跨应用重启持久化,策略响应也不作废或替换 updater 产物。 失败时在同一弹窗内保留阻塞、本地化重试提示和折叠诊断。白名单下载页面操作只在恢复状态出现,不与正常下载或安装并列。请求打开浏览器后立即提供复制替代入口,即使系统请求尚未返回;请求成功不证明网页已打开。复制失败时展示完整、只读的地址供手动复制。浏览器与剪贴板结果不覆盖 updater 错误。只有新的有效无需强更响应才解除阻塞;阻塞期间仍可使用顶部菜单检查。 @@ -395,11 +425,11 @@ node apps/desktop/node_modules/pnpm/bin/pnpm.mjs --dir apps/desktop run test:upd 此命令构建 Desktop 壳,让其协调器通过真实 Electron HTTP 请求和 `NsisUpdater` 访问私有回环服务器。它验证用户授权的完整下载、SHA-512 拒绝、显式重试、并发请求合并、清单替换和安装交接。它还打开使用沙箱预加载的真实强更页面,检查按钮操作、关闭/Esc 拦截、纯文本内容、策略请求停滞和策略解除。成功时打印 `LOCAL_UPDATER_RESULT` 并以零退出码结束;功能失败时返回非零退出码。每次调用独占随机端口和临时用户数据/缓存目录,关闭监听器、等待 Electron 退出,并移除临时文件。报告和可用截图保存在唯一的 `.desktop-build/qualification/local-updater-*` 目录中。截图失败单独记录,绝不当作视觉验收通过。不需要 COS 或签名凭据。 -下载内容是不可执行的测试字节,安装调用仅记录而不执行。测试替换浏览器打开与剪贴板写入,避免外部导航和剪贴板修改。它不启动完整产品工作区,不验证真实安装器或重启,不验证发布者签名,也不覆盖差分更新或 macOS。停滞的策略请求、清单请求和负载传输会执行真实截止时间及恢复。真实常规弹窗验证隔离预加载、卡片尺寸、背景模糊、取消、任务警告选项与显式安装批准;账户行组件测试另行提供证据。[本地验证决策](../../.agents/notes/implemented/testing/2026-09-10-desktop-local-updater-qualification.zh.md)和[验证记录](tests/README.zh.md)保留这些限制;生产发布要求保持不变。 +下载内容是不可执行的测试字节,安装调用仅记录而不执行。测试替换浏览器打开与剪贴板写入,避免外部导航和剪贴板修改。它不启动完整产品工作区,不验证真实安装器或重启,不验证发布者签名,也不覆盖差分更新或 macOS。停滞的策略请求、清单请求和负载传输会执行真实截止时间及恢复。真实常规弹窗验证隔离预加载、卡片尺寸、未施加模糊的父页面、取消、任务警告选项与显式安装批准;账户行组件测试另行提供证据。[本地验证决策](../../.agents/notes/implemented/testing/2026-09-10-desktop-local-updater-qualification.zh.md)和[验证记录](tests/README.zh.md)保留这些限制;生产发布要求保持不变。 ## 底层开发覆盖项 -未打包的 Electron 进程使用应用目录下的 `.desktop-build/development/project` 作为开发项目。`DSH_DESKTOP_PNPM_ENTRY` 和 `DSH_DESKTOP_DSH_DIR` 用于选择明确的运行时资源。打包应用会忽略这些变量,从 `process.resourcesPath` 解析签名资源,并使用受管 Desktop profile。 +未打包的 Electron 进程使用应用目录下的 `.desktop-build/development/project` 作为开发项目。`DSH_DESKTOP_PNPM_ENTRY` 和 `DSH_DESKTOP_DSH_DIR` 是带应用路径默认值的可选覆盖项。每次未打包启动都必须设置 `DSH_DESKTOP_PRIMARY_RUNTIME_DIR`:开发启动器(`dev:desktop`、`start:desktop` 及工作区更新验证运行器)会把它设置为自己已准备目标的 primary-runtime 目录;缺少该变量的启动会以致命启动对话框失败。启动器必须设置它,因为壳无法从 `process.arch` 推导该目录:构建目标将 Windows 固定为 x64,而宿主可能是 arm64。打包应用会忽略这些变量,从 `process.resourcesPath` 解析签名资源,并使用受管 Desktop profile。 ## 已知限制 @@ -408,8 +438,13 @@ node apps/desktop/node_modules/pnpm/bin/pnpm.mjs --dir apps/desktop run test:upd - 发布签名、公证、更新托管和跨上一版本的已安装产物验证需要生产发布环境。 - 依赖的生命周期脚本遵循 pnpm 的构建权限;Desktop 不提供单独的审批对话框。 - 桌面壳与 CLI dsh 共享 `$DSH_HOME` 下的会话、设置、凭据、工作区和存储,但可执行包、插件激活和锁文件彼此隔离。 +- 在 Electron win32-arm64 宿主上,未打包启动现在可以成功,但载荷仍为 x64:`packages/skill/tool-workspace-dependencies/src/index.ts` 的架构校验会把载荷记录的架构与宿主 `process.arch` 比较,因此 `load_workspace_dependencies` 工具仍可能拒绝 primary runtime。 -登录会在系统浏览器中打开配置的平台页面。Host 负责 PKCE 和临时本机回调,在进入工作区前保存凭证,再将浏览器跳转到平台完成页。打开和复制的授权链接通过 `theme=light` 或 `theme=dark` 携带当前生效的 Desktop 主题;`system` 在执行操作时解析。即使平台页面随后批准,取消仍会撤销本地尝试。设置中的账号页面提供退出;没有独立 API Key 时,退出后返回欢迎窗。打包应用注册 dsh://open,只显示窗口而不传递凭证。macOS 开发启动器在 `.desktop-build/development` 下准备经临时签名的 `Harness Dev.app`,在 Info.plist 中声明 `dsh` 并注册到 Launch Services。它加载当前工作区,并记录选定的开发 home、浏览器数据路径和调试设置,以供冷启动使用。启动此应用会将其设为 `dsh://` 默认处理程序;启动打包应用会重新注册打包版处理程序。生成的应用包不包含账号 token,依赖工作区和已准备的运行环境继续存在。 +仅向应用提供的 `dshOnboarding.hasApiKey()` preload 方法返回欢迎后端当前的 API Key 存在状态布尔值;原生登录与引导共用凭证发现逻辑,且只有受管理的应用主 frame 可以调用。 + +登录会在系统浏览器中打开配置的平台页面。Host 负责 PKCE 和临时本机回调,在进入工作区前保存凭证,再将浏览器跳转到平台完成页。打开和复制的授权链接通过 `theme=light` 或 `theme=dark` 携带当前生效的 Desktop 主题;`system` 在执行操作时解析。即使平台页面随后批准,取消仍会撤销本地尝试。设置中的账号页面提供退出;没有独立 API Key 时,退出后返回欢迎窗。浏览器登录成功后,Welcome 切换到工作区但不激活应用;完成页的 dsh://open 链接负责将客户端置前。打包应用注册 dsh://open,只显示窗口而不传递凭证。macOS 开发启动器在 `.desktop-build/development` 下准备经临时签名的 `Harness Dev.app`,在 Info.plist 中声明 `dsh` 并注册到 Launch Services。它加载当前工作区,并记录选定的开发 home、浏览器数据路径和调试设置,以供冷启动使用。启动此应用会将其设为 `dsh://` 默认处理程序;启动打包应用会重新注册打包版处理程序。生成的应用包不包含账号 token,依赖工作区和已准备的运行环境继续存在。 + +账号失效并返回 Welcome 时,主进程保留一次性通知,直到渲染器通过所属窗口的 IPC 领取。重新加载 Welcome 不会重复提示;主动退登和冷启动不会生成该通知。 登录超时后显示超时标题,并提供重新登录和添加 API Key 按钮。打开 API Key 表单会关闭授权视图;后续账号状态通知不会覆盖正在填写的密钥。 diff --git a/apps/desktop/electron-builder.config.d.mts b/apps/desktop/electron-builder.config.d.mts index d1cae61b6a..3ccec5b190 100644 --- a/apps/desktop/electron-builder.config.d.mts +++ b/apps/desktop/electron-builder.config.d.mts @@ -21,6 +21,7 @@ export interface DesktopElectronBuilderConfig { readonly extraResources: readonly [ { readonly from: string, readonly to: 'runtime' }, { readonly from: string, readonly to: 'icon.png' }, + ...{ readonly from: string, readonly to: 'tray.ico' }[], ] readonly mac: { readonly extendInfo: { readonly NSMicrophoneUsageDescription: string } diff --git a/apps/desktop/installer/lifecycle.nsh b/apps/desktop/installer/lifecycle.nsh index 452c4d2662..525fde4080 100644 --- a/apps/desktop/installer/lifecycle.nsh +++ b/apps/desktop/installer/lifecycle.nsh @@ -50,6 +50,7 @@ Function InstallerBeforeInstall SetErrorLevel 2 Quit ${EndIf} + Call InstallerCheckAppRunning FunctionEnd Function InstallerProgressShow diff --git a/apps/desktop/installer/strings.nsh b/apps/desktop/installer/strings.nsh index f2f2b08191..174ebfa28b 100644 --- a/apps/desktop/installer/strings.nsh +++ b/apps/desktop/installer/strings.nsh @@ -27,8 +27,8 @@ LangString INSTALLER_THEME_ERROR ${LANG_ENGLISH} "Use /THEME=auto, /THEME=light LangString INSTALLER_THEME_ERROR ${LANG_SIMPCHINESE} "主题参数须为 /THEME=auto、/THEME=light 或 /THEME=dark。" LangString INSTALLER_FAILED ${LANG_ENGLISH} "Installation did not finish. Close this installer and retry. If the problem persists, download the installer again." LangString INSTALLER_FAILED ${LANG_SIMPCHINESE} "安装未完成,请关闭安装程序后重试。如仍然失败,请重新下载安装包。" -LangString INSTALLER_RUNNING ${LANG_ENGLISH} "DeepSeek Harness is running. Close the application, then run this installer again." -LangString INSTALLER_RUNNING ${LANG_SIMPCHINESE} "DeepSeek Harness 正在运行。请先关闭应用,再重新运行安装程序。" +LangString INSTALLER_RUNNING ${LANG_ENGLISH} "DeepSeek Harness is running. Quit it from the system tray and try again." +LangString INSTALLER_RUNNING ${LANG_SIMPCHINESE} "DeepSeek Harness 正在运行,请先在系统托盘中退出应用后重试。" LangString INSTALLER_PATH_INVALID ${LANG_ENGLISH} "Choose a full local folder path. Drive roots, system folders, links and special characters are not supported." LangString INSTALLER_PATH_INVALID ${LANG_SIMPCHINESE} "请选择本地磁盘上的完整文件夹路径,不能使用磁盘根目录、系统目录、链接目录或包含特殊字符的路径。" LangString INSTALLER_PATH_OWNERSHIP ${LANG_ENGLISH} "Choose an empty folder or the registered DeepSeek Harness installation folder." diff --git a/apps/desktop/package.json b/apps/desktop/package.json index db69834af2..cc0ce4f064 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,18 +1,20 @@ { "name": "@deepseek-ai/dsh-desktop", "description": "Electron desktop shell for a bundled dsh runtime and external plugins", - "version": "0.1.7-alpha.2", + "version": "0.1.7-rc.2", "private": true, "license": "MIT", "type": "module", "main": "lib/main.js", "scripts": { "test:installer": "node scripts/test-windows-installer.mjs", - "build": "tsc -b && tsdown", + "build": "tsc -b && pnpm run bundle", + "bundle": "tsdown", "dev": "tsx scripts/dev.ts", "start": "tsx scripts/dev.ts --skip-build", "test:updates:local": "pnpm run build && node scripts/test-local-updater.mjs", "prepare:runtime": "tsx scripts/prepare-runtime.ts", + "render:tray-icon": "tsx scripts/render-tray-icon.ts", "prepare:primary-runtime": "tsx scripts/prepare-primary-runtime.ts", "sign:primary-runtime": "tsx scripts/sign-primary-runtime.ts", "cache:windows-signatures": "node scripts/manage-windows-signature-cache.mjs", @@ -61,6 +63,7 @@ "js-yaml": "^4.2.0", "koffi": "^3.1.0", "pnpm": "11.7.0", + "sharp": "^0.35.3", "typescript": "^6.0.3", "@deepseek-ai/dsh-deepseek-account": "workspace:*", "@types/ws": "^8.18.1", @@ -70,6 +73,8 @@ "@types/react": "~18.3.1", "@types/react-dom": "~18.3.0", "vite": "^6.0.0", - "@deepseek-ai/dsh-client-ui-theme": "workspace:*" + "@deepseek-ai/dsh-client-ui-theme": "workspace:*", + "@deepseek-ai/dsh-client-shortcuts": "workspace:*", + "@deepseek-ai/dsh-atomic-write": "workspace:*" } } diff --git a/apps/desktop/renderer/welcome.css b/apps/desktop/renderer/welcome.css index 3d5fc88460..3b4da2defb 100644 --- a/apps/desktop/renderer/welcome.css +++ b/apps/desktop/renderer/welcome.css @@ -1,7 +1,7 @@ @import url('./assets/window-material.css'); /* Figma 2121:39336 / 2138:44626, Platform modes. Native material supplies the blur. */ -:root { +body { color-scheme: light dark; --dsw-alias-label-primary: #0f1115; --dsw-alias-label-secondary: #61666b; @@ -23,7 +23,7 @@ } @media (prefers-color-scheme: dark) { - :root { + body { --dsw-alias-label-primary: #f9fafb; --dsw-alias-label-secondary: #cfd3d6; --dsw-alias-label-tertiary: #adb2b8; @@ -52,6 +52,8 @@ body { margin: 0; overflow: hidden; background: transparent; + font-family: var(--dsw-font-family); + font-weight: 400; } #root { @@ -192,6 +194,7 @@ body { top: calc(100% + 16px); left: 50%; transform: translateX(-50%); + white-space: nowrap; min-width: 58px; height: 28px; padding: 4px 10px; @@ -245,7 +248,7 @@ body { .key-heading h1 { margin: 0; font-size: 20px; - font-weight: 300; + font-weight: 400; line-height: 32px; letter-spacing: 0.01em; } diff --git a/apps/desktop/renderer/welcome.html b/apps/desktop/renderer/welcome.html index 0731e3be96..f8cbeb8e15 100644 --- a/apps/desktop/renderer/welcome.html +++ b/apps/desktop/renderer/welcome.html @@ -6,8 +6,8 @@ - + diff --git a/apps/desktop/resources/icon-windows.svg b/apps/desktop/resources/icon-windows.svg index eb07a50158..212560ed20 100644 --- a/apps/desktop/resources/icon-windows.svg +++ b/apps/desktop/resources/icon-windows.svg @@ -3,7 +3,7 @@ - + diff --git a/apps/desktop/resources/tray-windows.ico b/apps/desktop/resources/tray-windows.ico new file mode 100644 index 0000000000..e60f1cb885 Binary files /dev/null and b/apps/desktop/resources/tray-windows.ico differ diff --git a/apps/desktop/scripts/desktop-build-paths.d.mts b/apps/desktop/scripts/desktop-build-paths.d.mts index b26c633d9c..9a8e408ed1 100644 --- a/apps/desktop/scripts/desktop-build-paths.d.mts +++ b/apps/desktop/scripts/desktop-build-paths.d.mts @@ -36,6 +36,17 @@ export function resolveDesktopBuildTarget( */ export function desktopTargetBuildPaths(target: DesktopAutoUpdateTarget): DesktopTargetBuildPaths +/** + * Return the platform and architecture of the payload one release target prepares. + * Windows is prepared as x64 only, so this differs from the build host on an arm64 Windows machine. + * @param target - Supported Desktop target name. + * @returns Platform and architecture of the prepared payload. + */ +export function desktopTargetPlatform(target: DesktopAutoUpdateTarget): { + readonly platform: 'darwin' | 'win32' + readonly arch: 'arm64' | 'x64' +} + /** * Resolve the paths owned by the target selected in a packaging environment. * @param env - Packaging environment. @@ -48,3 +59,16 @@ export function resolveDesktopTargetBuildPaths( hostPlatform?: NodeJS.Platform, hostArch?: string, ): DesktopTargetBuildPaths + +/** + * Resolve the primary-runtime directory an unpackaged development launch uses. + * @param env - Packaging environment. + * @param hostPlatform - Build-host platform used when no target override exists. + * @param hostArch - Build-host architecture used when no target override exists. + * @returns Primary-runtime directory prepared for the selected target. + */ +export function developmentRuntimeDirectory( + env?: NodeJS.ProcessEnv, + hostPlatform?: NodeJS.Platform, + hostArch?: string, +): string diff --git a/apps/desktop/scripts/desktop-build-paths.mjs b/apps/desktop/scripts/desktop-build-paths.mjs index 841da2c4ba..4f33e804c3 100644 --- a/apps/desktop/scripts/desktop-build-paths.mjs +++ b/apps/desktop/scripts/desktop-build-paths.mjs @@ -29,15 +29,19 @@ export function resolveDesktopBuildTarget( return /** @type {'mac-arm64' | 'mac-x64' | 'win-x64'} */ (target) } +function assertSupportedTarget(target) { + if (!SUPPORTED_TARGETS.has(target)) { + throw new Error(`desktop build paths: unsupported target ${String(target)}`) + } +} + /** * Return the mutable preparation and artifact directories owned by one release target. * @param {'mac-arm64' | 'mac-x64' | 'win-x64'} target - Supported Desktop target name. * @returns {{ root: string, artifacts: string, unsignedArtifacts: string, runtime: string, packageSet: string, dsh: string, dshPnpm: string, electron: string, packedDsh: string, packedVendor: string, packedLandlock: string, downloads: string }} Target paths plus the shared immutable download cache. */ export function desktopTargetBuildPaths(target) { - if (!SUPPORTED_TARGETS.has(target)) { - throw new Error(`desktop build paths: unsupported target ${String(target)}`) - } + assertSupportedTarget(target) const root = join(BUILD_ROOT, 'targets', target) const packed = join(root, 'packed') return { @@ -56,6 +60,20 @@ export function desktopTargetBuildPaths(target) { } } +/** + * Return the platform and architecture of the payload one release target prepares. + * Windows is prepared as x64 only, so this differs from the build host on an arm64 Windows machine. + * @param {'mac-arm64' | 'mac-x64' | 'win-x64'} target - Supported Desktop target name. + * @returns {{ platform: 'darwin' | 'win32', arch: 'arm64' | 'x64' }} Platform and architecture of the prepared payload. + */ +export function desktopTargetPlatform(target) { + assertSupportedTarget(target) + return { + platform: /** @type {'darwin' | 'win32'} */ (target === 'win-x64' ? 'win32' : 'darwin'), + arch: /** @type {'arm64' | 'x64'} */ (target === 'mac-arm64' ? 'arm64' : 'x64'), + } +} + /** * Resolve the paths owned by the target selected in a packaging environment. * @param {NodeJS.ProcessEnv} env - Packaging environment. @@ -70,3 +88,20 @@ export function resolveDesktopTargetBuildPaths( ) { return desktopTargetBuildPaths(resolveDesktopBuildTarget(env, hostPlatform, hostArch)) } + +/** + * Resolve the primary-runtime directory an unpackaged development launch uses. + * The build target fixes Windows to x64, so the shell cannot derive this directory from + * the architecture of the process that launched it. + * @param {NodeJS.ProcessEnv} env - Packaging environment. + * @param {NodeJS.Platform} hostPlatform - Build-host platform used when no target override exists. + * @param {string} hostArch - Build-host architecture used when no target override exists. + * @returns {string} Primary-runtime directory prepared for the selected target. + */ +export function developmentRuntimeDirectory( + env = process.env, + hostPlatform = process.platform, + hostArch = process.arch, +) { + return join(resolveDesktopTargetBuildPaths(env, hostPlatform, hostArch).runtime, 'primary-runtime') +} diff --git a/apps/desktop/scripts/desktop-bundle-imports.d.mts b/apps/desktop/scripts/desktop-bundle-imports.d.mts new file mode 100644 index 0000000000..3743e8ea39 --- /dev/null +++ b/apps/desktop/scripts/desktop-bundle-imports.d.mts @@ -0,0 +1,46 @@ +import type { Rolldown } from 'tsdown' + +/** Bare specifiers one Desktop bundle may leave for the runtime to resolve. */ +export interface BundleImportPolicy { + /** Package names present at runtime, matched by package name so subpaths pass. */ + readonly packages: ReadonlySet + /** + * Whether Node builtins resolve at runtime: true for the Electron main + * process; false for sandboxed preloads, whose `require` polyfill offers only + * the modules listed in `packages`. + */ + readonly nodeBuiltins: boolean +} + +/** + * Package name of a bare import specifier. + * @param specifier - Bare specifier as rolldown reports it, such as `@scope/name/subpath`. + * @returns The package name without its subpath. + */ +export function importPackageName(specifier: string): string + +/** + * Whether a module id rolldown reports is a bare specifier, i.e. an import the + * bundle leaves external. Bundled modules carry absolute ids; virtual modules + * start with `\0`. + * @param id - Module id from `importedIds` or `dynamicallyImportedIds`. + * @returns True for a bare specifier. + */ +export function isBareSpecifier(id: string): boolean + +/** + * Bare imports the packaged application cannot resolve. + * @param imports - External specifiers a module imports statically, dynamically, or through `require()`. + * @param policy - What this bundle may leave external. + * @returns Offending specifiers in import order, each once. + */ +export function unpackagedImports(imports: readonly string[], policy: BundleImportPolicy): string[] + +/** + * Rolldown plugin that fails a bundle whose external imports the packaged + * application cannot resolve. The failure names the importing module and every + * offending specifier, and no output is written. + * @param policy - What this bundle may leave external. + * @returns The plugin. + */ +export function packagedImportsPlugin(policy: BundleImportPolicy): Rolldown.Plugin diff --git a/apps/desktop/scripts/desktop-bundle-imports.mjs b/apps/desktop/scripts/desktop-bundle-imports.mjs new file mode 100644 index 0000000000..d1aa8f5b9d --- /dev/null +++ b/apps/desktop/scripts/desktop-bundle-imports.mjs @@ -0,0 +1,90 @@ +/** + * Keep every bare import a Desktop bundle leaves to the runtime resolvable + * inside the packaged application. + * + * electron-builder copies only the manifest's `dependencies` into + * `app.asar/node_modules`, so a bare import of anything else bundles without + * complaint and fails at launch with `ERR_MODULE_NOT_FOUND`. The main-process + * bundle inlines its workspace devDependencies; when one of their `lib/` + * outputs is missing at bundle time, rolldown reports `UNRESOLVED_IMPORT` as a + * warning and keeps the specifier as an external import, which is exactly the + * broken artifact. This check fails the bundle instead of the installed + * application. + * + * The check runs in `moduleParsed`, where rolldown reports every import record + * of a module: static imports, dynamic `import()`, and `require()` calls. A + * bundled import resolves to an absolute module id; an external one keeps its + * bare specifier. Chunk metadata (`imports`/`dynamicImports`) omits external + * `import()` and `require()` targets, so it cannot serve this check. + */ + +import { isBuiltin } from 'node:module' +import { isAbsolute, relative } from 'node:path' + +/** + * Bare specifiers one Desktop bundle may leave for the runtime to resolve. + * @typedef {object} BundleImportPolicy + * @property {ReadonlySet} packages - Package names present at runtime, matched by package name so subpaths pass. + * @property {boolean} nodeBuiltins - Whether Node builtins resolve at runtime (true for the Electron main process; false for sandboxed preloads, whose `require` polyfill offers only the modules listed in `packages`). + */ + +/** + * Package name of a bare import specifier. + * @param {string} specifier - Bare specifier as rolldown reports it, such as `@scope/name/subpath`. + * @returns {string} The package name without its subpath. + */ +export function importPackageName(specifier) { + const segments = specifier.split('/') + return specifier.startsWith('@') ? segments.slice(0, 2).join('/') : segments[0] +} + +/** + * Whether a module id rolldown reports is a bare specifier, i.e. an import the + * bundle leaves external. Bundled modules carry absolute ids; virtual modules + * start with `\0`. + * @param {string} id - Module id from `importedIds` or `dynamicallyImportedIds`. + * @returns {boolean} True for a bare specifier. + */ +export function isBareSpecifier(id) { + return !id.startsWith('.') && !id.startsWith('\0') && !isAbsolute(id) +} + +/** + * Bare imports the packaged application cannot resolve. + * @param {readonly string[]} imports - External specifiers a module imports statically, dynamically, or through `require()`. + * @param {BundleImportPolicy} policy - What this bundle may leave external. + * @returns {string[]} Offending specifiers in import order, each once. + */ +export function unpackagedImports(imports, policy) { + const offending = new Set() + for (const specifier of imports) { + if (policy.nodeBuiltins && isBuiltin(specifier)) continue + if (policy.packages.has(importPackageName(specifier))) continue + offending.add(specifier) + } + return [...offending] +} + +/** + * Rolldown plugin that fails a bundle whose external imports the packaged + * application cannot resolve. The failure names the importing module and every + * offending specifier, and no output is written. + * @param {BundleImportPolicy} policy - What this bundle may leave external. + * @returns {import('tsdown').Rolldown.Plugin} The plugin. + */ +export function packagedImportsPlugin(policy) { + const allowed = [...policy.packages].join(', ') + (policy.nodeBuiltins ? ', and Node builtins' : '') + return { + name: 'desktop-packaged-imports', + moduleParsed(info) { + const external = [...info.importedIds, ...info.dynamicallyImportedIds].filter(isBareSpecifier) + const offending = unpackagedImports(external, policy) + if (offending.length === 0) return + this.error( + `desktop bundle: ${relative(process.cwd(), info.id)} imports ${offending.join(', ')}, which the packaged application does not ship. ` + + `This bundle may leave only ${allowed} as bare imports; anything else must be bundled, ` + + 'which requires its lib/ output to exist before this bundle runs (pnpm run build:lib:host).', + ) + }, + } +} diff --git a/apps/desktop/scripts/dev.ts b/apps/desktop/scripts/dev.ts index 74840eae03..1ae2f3e952 100644 --- a/apps/desktop/scripts/dev.ts +++ b/apps/desktop/scripts/dev.ts @@ -7,6 +7,7 @@ import { join, resolve } from 'node:path' import { parseArgs } from 'node:util' import { DESKTOP_HOST_PROTOCOL_VERSION } from '../src/host-protocol.ts' import type { DesktopRelease } from '../src/release.ts' +import { developmentRuntimeDirectory, resolveDesktopBuildTarget } from './desktop-build-paths.mjs' import { prepareDevelopmentProject } from './development-project.ts' import { prepareDevelopmentApp } from './development-app.ts' import { preparePrimaryRuntime } from './prepare-primary-runtime.ts' @@ -63,15 +64,17 @@ async function launchElectron(): Promise { const rendererPort = debugPort('DSH_DESKTOP_RENDERER_DEBUG_PORT', 9222) const hostPort = debugPort('DSH_DESKTOP_HOST_INSPECT_PORT', 9230) const home = resolve(process.env.DSH_HOME ?? join(DEVELOPMENT_ROOT, 'home')) - const userData = join(DEVELOPMENT_ROOT, 'electron-user-data') + const userData = resolve(process.env.DSH_DESKTOP_USER_DATA_DIR ?? join(DEVELOPMENT_ROOT, 'electron-user-data')) const environment: NodeJS.ProcessEnv = { ...process.env, DSH_HOME: home, + DSH_DESKTOP_PRIMARY_RUNTIME_DIR: process.env.DSH_DESKTOP_PRIMARY_RUNTIME_DIR ?? developmentRuntimeDirectory(), DSH_DESKTOP_HOST_INSPECT_PORT: String(hostPort), DSH_DESKTOP_OPEN_DEVTOOLS: process.env.DSH_DESKTOP_OPEN_DEVTOOLS ?? '1', ELECTRON_ENABLE_LOGGING: process.env.ELECTRON_ENABLE_LOGGING ?? '1', } console.log(`desktop development: DSH_HOME=${home}`) + console.log(`desktop development: userData=${userData}`) console.log(`desktop development: inspectors main=${String(mainPort)}, renderer=${String(rendererPort)}, host=${String(hostPort)}`) if (process.platform === 'darwin') { const executable = prepareDevelopmentApp({ electron, appRoot: APP_ROOT, directory: DEVELOPMENT_ROOT, home, userData, @@ -115,6 +118,7 @@ async function main(): Promise { hostDir: join(REPOSITORY_ROOT, 'apps', 'desktop-host'), dependencyDir: join(REPOSITORY_ROOT, 'node_modules', '.pnpm', 'node_modules'), release, + target: resolveDesktopBuildTarget(), }) await preparePrimaryRuntime() await launchElectron() diff --git a/apps/desktop/scripts/development-project.ts b/apps/desktop/scripts/development-project.ts index 36c70baff0..d544ce6d36 100644 --- a/apps/desktop/scripts/development-project.ts +++ b/apps/desktop/scripts/development-project.ts @@ -16,6 +16,8 @@ import { dirname, join } from 'node:path' import { createDevelopmentProjectMetadata } from '../src/project-manager.ts' import type { DesktopRelease } from '../src/release.ts' import { DESKTOP_RUNTIME_FILE, type DesktopRuntimeDescriptor } from '../src/runtime-tree.ts' +import type { DesktopAutoUpdateTarget } from './desktop-auto-update-environment.mjs' +import { desktopTargetPlatform } from './desktop-build-paths.mjs' interface PackageManifest { readonly name?: string @@ -35,6 +37,8 @@ export interface DevelopmentProjectOptions { readonly dependencyDir: string /** Release identity written into the disposable project metadata. */ readonly release: DesktopRelease + /** Build target whose prepared payload the disposable project runs against. */ + readonly target: DesktopAutoUpdateTarget } function readManifest(path: string): PackageManifest { @@ -115,7 +119,7 @@ function mirrorWorkspaceDependencies(roots: readonly string[], destinationRoot: /** * Replace one disposable project with links to the current built workspace. - * @param options - Project destination, CLI package, and release identity. + * @param options - Project destination, CLI package, release identity, and build target. * @returns the absolute project directory supplied by the caller. */ export function prepareDevelopmentProject(options: DevelopmentProjectOptions): string { @@ -159,7 +163,7 @@ export function prepareDevelopmentProject(options: DevelopmentProjectOptions): s return typeof manifest.version === 'string' ? [{ name, version: manifest.version, path: `node_modules/${name}` }] : [] }) const runtime: DesktopRuntimeDescriptor = { schemaVersion: 1, release: options.release, - platform: process.platform, arch: process.arch, sharedPackages, files: [] } + ...desktopTargetPlatform(options.target), sharedPackages, files: [] } writeFileSync(join(options.projectDir, DESKTOP_RUNTIME_FILE), `${JSON.stringify(runtime, undefined, 2)}\n`) return options.projectDir } diff --git a/apps/desktop/scripts/electron-builder-config.mjs b/apps/desktop/scripts/electron-builder-config.mjs index e0a707dc32..bab440ea61 100644 --- a/apps/desktop/scripts/electron-builder-config.mjs +++ b/apps/desktop/scripts/electron-builder-config.mjs @@ -144,6 +144,8 @@ export function createElectronBuilderConfig( extraResources: [ { from: buildPaths.runtime, to: 'runtime' }, { from: fileURLToPath(new URL('../resources/icon-windows.png', import.meta.url)), to: 'icon.png' }, + // Windows tray bitmaps; macOS keeps the Dock and ships no menu bar icon. + ...(packagesWindows ? [{ from: fileURLToPath(new URL('../resources/tray-windows.ico', import.meta.url)), to: 'tray.ico' }] : []), ], mac: { icon: fileURLToPath(new URL('../resources/icon-macos.png', import.meta.url)), diff --git a/apps/desktop/scripts/flock-entry.ts b/apps/desktop/scripts/flock-entry.ts new file mode 100644 index 0000000000..7c2f3e75da --- /dev/null +++ b/apps/desktop/scripts/flock-entry.ts @@ -0,0 +1,94 @@ +/** Load the POSIX flock entry on first use so packaging entry scripts start on a checkout that has not built `native/system`. */ + +import { spawn } from 'node:child_process' +import { once } from 'node:events' +import { existsSync, readFileSync } from 'node:fs' +import { createRequire } from 'node:module' +import { dirname, join, resolve } from 'node:path' + +type FlockEntry = typeof import('@deepseek-ai/node-addon-system/flock') + +const REPOSITORY_ROOT = resolve(import.meta.dirname, '..', '..', '..') +/** Root package script that compiles the host addon, then the `native/system` script that emits the entry's JavaScript. */ +const BUILD_COMMANDS: readonly (readonly string[])[] = [ + ['run', 'build:native-system'], + ['--dir', 'native/system', 'run', 'build:ts'], +] +const BUILD_COMMAND_TEXT = BUILD_COMMANDS.map(args => `pnpm ${args.join(' ')}`).join(' && ') + +/** Loader steps; tests replace the module import, the addon probe, and the build. */ +export interface FlockEntryLoaderSteps { + /** Import `@deepseek-ai/node-addon-system/flock`; rejects with `ERR_MODULE_NOT_FOUND` while its `lib/` is unbuilt. */ + readonly importEntry: () => Promise + /** Whether every binary the host platform package declares in `prebuilds.json` exists. */ + readonly hostAddonBuilt: () => boolean + /** Compile the host addon and emit the entry's JavaScript; rejects when a build fails. */ + readonly build: () => Promise +} + +function isModuleNotFound(error: unknown): boolean { + return (error as NodeJS.ErrnoException | undefined)?.code === 'ERR_MODULE_NOT_FOUND' +} + +/** + * Create a memoized loader that imports the flock entry, building `native/system` once when its entry or host addon is missing. + * @param steps - Module import, addon probe, and build used by the loader. + * @returns Loader that resolves the same entry on every call; a failed load is retried by the next call. + */ +export function createFlockEntryLoader(steps: FlockEntryLoaderSteps): () => Promise { + let loading: Promise | undefined + const load = async (): Promise => { + let entry: FlockEntry | undefined + try { + entry = await steps.importEntry() + } catch (error) { + if (!isModuleNotFound(error)) throw error + } + if (entry !== undefined && steps.hostAddonBuilt()) return entry + process.stderr.write(`desktop package: flock addon is not built; running ${BUILD_COMMAND_TEXT}\n`) + await steps.build() + return steps.importEntry() + } + return () => { + loading ??= load().catch((error: unknown) => { loading = undefined; throw error }) + return loading + } +} + +function hostAddonBuilt(): boolean { + const { platform, arch } = process + // flock itself rejects other platforms; the probe only reports missing builds for supported ones. + if (platform !== 'darwin' && platform !== 'linux') return true + const entryManifest = createRequire(import.meta.url).resolve('@deepseek-ai/node-addon-system/package.json') + let prebuilds: string + try { + prebuilds = createRequire(entryManifest).resolve(`@deepseek-ai/node-addon-system-${platform}-${arch}/prebuilds.json`) + } catch (error) { + if ((error as NodeJS.ErrnoException).code !== 'MODULE_NOT_FOUND') throw error + return false + } + const manifest = JSON.parse(readFileSync(prebuilds, 'utf8')) as { readonly binaries: readonly { readonly path: string }[] } + return manifest.binaries.every(binary => existsSync(join(dirname(prebuilds), binary.path))) +} + +async function buildNativeSystem(): Promise { + const pnpmEntry = process.env.npm_execpath + if (pnpmEntry === undefined || pnpmEntry === '') { + throw new Error(`desktop package: flock addon is not built; run ${BUILD_COMMAND_TEXT} or invoke this script through a pnpm package command`) + } + for (const args of BUILD_COMMANDS) { + const child = spawn(process.execPath, [pnpmEntry, ...args], { cwd: REPOSITORY_ROOT, stdio: 'inherit' }) + const [code, signal] = await once(child, 'close') as [number | null, NodeJS.Signals | null] + if (code !== 0) throw new Error(`desktop package: pnpm ${args.join(' ')} exited with ${String(code ?? signal)}`) + } +} + +/** + * Load `@deepseek-ai/node-addon-system/flock`, building the host addon and the entry's JavaScript through pnpm when either is missing. + * @returns The flock entry; rejects when a build fails or the script did not run under pnpm. + */ +export const loadFlockEntry = createFlockEntryLoader({ + importEntry: () => import('@deepseek-ai/node-addon-system/flock'), + hostAddonBuilt, + build: buildNativeSystem, +}) diff --git a/apps/desktop/scripts/installer.nsh b/apps/desktop/scripts/installer.nsh index 5980287859..0f4d859e78 100644 --- a/apps/desktop/scripts/installer.nsh +++ b/apps/desktop/scripts/installer.nsh @@ -23,6 +23,9 @@ ManifestDPIAware true !include "${INSTALLER_SOURCE_DIR}\theme.nsh" !include "${INSTALLER_SOURCE_DIR}\pages.nsh" !include "${INSTALLER_SOURCE_DIR}\lifecycle.nsh" + Function InstallerCheckAppRunning + !insertmacro customCheckAppRunning + FunctionEnd !endif !macroend @@ -63,6 +66,7 @@ ManifestDPIAware true File "/oname=$PLUGINSDIR\brand-dark.bmp" "${INSTALLER_BUILD_DIR}\brand-dark.bmp" File "/oname=$PLUGINSDIR\brand-dark-2x.bmp" "${INSTALLER_BUILD_DIR}\brand-dark-2x.bmp" File "/oname=$PLUGINSDIR\window-frame.dll" "${INSTALLER_BUILD_DIR}\window-frame.dll" + Call InstallerCheckAppRunning ${If} ${Silent} Call InstallerPreflight ${If} $InstallerError != "" diff --git a/apps/desktop/scripts/macos-notarization-proxy.ts b/apps/desktop/scripts/macos-notarization-proxy.ts index 11f19b4022..bd5900a758 100644 --- a/apps/desktop/scripts/macos-notarization-proxy.ts +++ b/apps/desktop/scripts/macos-notarization-proxy.ts @@ -5,7 +5,7 @@ import { closeSync, mkdirSync, openSync, readFileSync, rmSync, writeFileSync } f import { connect } from 'node:net' import { homedir } from 'node:os' import { dirname, join, resolve } from 'node:path' -import { tryLockExclusive } from '@deepseek-ai/node-addon-system/flock' +import { loadFlockEntry } from './flock-entry.ts' interface ProxyState { readonly enabled: boolean @@ -50,6 +50,7 @@ const operations: ProxyOperations = { } async function withProxyLock(lock: string, action: () => Promise): Promise { + const { tryLockExclusive } = await loadFlockEntry() mkdirSync(dirname(lock), { recursive: true, mode: 0o700 }) // Keep this inode across transactions: unlinking it would allow two independent locks. const fd = openSync(`${lock}.flock`, 'a', 0o600) diff --git a/apps/desktop/scripts/render-tray-icon.ts b/apps/desktop/scripts/render-tray-icon.ts new file mode 100644 index 0000000000..01bacdea5e --- /dev/null +++ b/apps/desktop/scripts/render-tray-icon.ts @@ -0,0 +1,123 @@ +/** + * Render the Windows tray icon with an enlarged whale from `resources/icon-windows.svg`. + * + * The tray shows the icon at 16 logical pixels, so Windows picks one of the + * bundled bitmaps by display scale. Each size is rasterized from the vector + * source separately instead of downscaling one large bitmap, which keeps edges + * crisp at every scale. The committed `resources/tray-windows.ico` is the output; + * rerun `pnpm run render:tray-icon` in `apps/desktop` after changing the vector source. + */ + +import { readFile, writeFile } from 'node:fs/promises' +import { resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import sharp from 'sharp' + +/** Bitmap edge lengths bundled in the tray icon: 16 px at 100 % through 400 % display scale. */ +export const TRAY_ICON_SIZES = [16, 20, 24, 32, 40, 48, 64] as const + +/** Vector source and committed output of the tray icon. */ +export const TRAY_ICON_PATHS = { + source: fileURLToPath(new URL('../resources/icon-windows.svg', import.meta.url)), + output: fileURLToPath(new URL('../resources/tray-windows.ico', import.meta.url)), +} as const + +/** Coordinate space of the vector source; sharp's SVG density is scaled against it. */ +const SOURCE_EDGE = 1024 +const SOURCE_DENSITY = 72 +const PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]) +const ICON_DIRECTORY_BYTES = 6 +const ICON_ENTRY_BYTES = 16 + +/** One bitmap of an icon file. */ +export interface IcoEntry { + readonly size: number + /** Complete PNG stream; Windows Vista and later read PNG-compressed entries directly. */ + readonly png: Buffer +} + +/** + * Pack PNG bitmaps into one ICO file. + * @param entries - Bitmaps in ascending size; each PNG must be square with the declared edge. + * @returns the ICO bytes. + */ +export function packIco(entries: readonly IcoEntry[]): Buffer { + const header = Buffer.alloc(ICON_DIRECTORY_BYTES + ICON_ENTRY_BYTES * entries.length) + header.writeUInt16LE(0, 0) + header.writeUInt16LE(1, 2) + header.writeUInt16LE(entries.length, 4) + let offset = header.length + entries.forEach((entry, index) => { + if (entry.size < 1 || entry.size > 256) throw new Error(`tray icon: unsupported bitmap edge ${String(entry.size)}`) + const { width, height } = pngDimensions(entry.png) + if (width !== entry.size || height !== entry.size) { + throw new Error(`tray icon: bitmap ${String(index)} is ${String(width)}x${String(height)}, expected ${String(entry.size)}`) + } + const at = ICON_DIRECTORY_BYTES + ICON_ENTRY_BYTES * index + // 256 px is encoded as 0 in the one-byte edge fields. + header.writeUInt8(entry.size % 256, at) + header.writeUInt8(entry.size % 256, at + 1) + header.writeUInt8(0, at + 2) + header.writeUInt8(0, at + 3) + header.writeUInt16LE(1, at + 4) + header.writeUInt16LE(32, at + 6) + header.writeUInt32LE(entry.png.length, at + 8) + header.writeUInt32LE(offset, at + 12) + offset += entry.png.length + }) + return Buffer.concat([header, ...entries.map(entry => entry.png)]) +} + +/** + * Read the bitmaps back out of one ICO file. + * @param ico - Bytes written by {@link packIco} or another PNG-entry ICO producer. + * @returns entries in directory order, each PNG checked against its declared edge. + */ +export function unpackIco(ico: Buffer): IcoEntry[] { + if (ico.length < ICON_DIRECTORY_BYTES || ico.readUInt16LE(0) !== 0 || ico.readUInt16LE(2) !== 1) { + throw new Error('tray icon: not an ICO file') + } + const count = ico.readUInt16LE(4) + return Array.from({ length: count }, (_, index) => { + const at = ICON_DIRECTORY_BYTES + ICON_ENTRY_BYTES * index + const declared = ico.readUInt8(at) + const size = declared === 0 ? 256 : declared + const length = ico.readUInt32LE(at + 8) + const offset = ico.readUInt32LE(at + 12) + const png = ico.subarray(offset, offset + length) + const { width, height } = pngDimensions(png) + if (width !== size || height !== size) throw new Error(`tray icon: entry ${String(index)} declares ${String(size)} but holds ${String(width)}x${String(height)}`) + return { size, png } + }) +} + +/** + * Rasterize the vector source at each tray size. + * @param svg - SVG document with a 1024-unit square viewBox and a `tray-glyph` group. + * @param sizes - Bitmap edges to render. + * @returns PNG entries in the given order. + */ +export async function renderTrayIconEntries(svg: Buffer, sizes: readonly number[] = TRAY_ICON_SIZES): Promise { + const source = svg.toString('utf8') + const glyph = ' ({ + size, + png: await sharp(tray, { density: SOURCE_DENSITY * size / SOURCE_EDGE }).resize(size, size).png().toBuffer(), + }))) +} + +function pngDimensions(png: Buffer): { width: number; height: number } { + if (png.length < 24 || !png.subarray(0, PNG_SIGNATURE.length).equals(PNG_SIGNATURE)) throw new Error('tray icon: bitmap is not a PNG stream') + return { width: png.readUInt32BE(16), height: png.readUInt32BE(20) } +} + +async function main(): Promise { + const entries = await renderTrayIconEntries(await readFile(TRAY_ICON_PATHS.source)) + await writeFile(TRAY_ICON_PATHS.output, packIco(entries)) + console.info(`tray icon: wrote ${TRAY_ICON_PATHS.output} with ${entries.map(entry => String(entry.size)).join(', ')} px bitmaps`) +} + +if (process.argv[1] !== undefined && import.meta.filename === resolve(process.argv[1])) await main() diff --git a/apps/desktop/scripts/test-workspace-updates.ts b/apps/desktop/scripts/test-workspace-updates.ts index 669d572b9d..41f40caa09 100644 --- a/apps/desktop/scripts/test-workspace-updates.ts +++ b/apps/desktop/scripts/test-workspace-updates.ts @@ -8,6 +8,7 @@ import { fileURLToPath } from 'node:url' import { createDevelopmentProjectMetadata, createPluginProfile } from '../src/project-manager.ts' import { removeOwnedDirectory } from '../src/owned-directory.ts' import { DESKTOP_HOST_PROTOCOL_VERSION } from '../src/host-protocol.ts' +import { desktopTargetPlatform, developmentRuntimeDirectory, resolveDesktopBuildTarget } from './desktop-build-paths.mjs' const repo = resolve(import.meta.dirname, '../../..') const interactive = process.argv.includes('--interactive') @@ -27,10 +28,11 @@ try { nodeVersion: execFileSync(electron, ['-p', 'process.versions.node'], { encoding: 'utf8', env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' }, windowsHide: true }).trim(), pnpmVersion: pnpm.version, hostProtocolVersion: DESKTOP_HOST_PROTOCOL_VERSION } + const target = resolveDesktopBuildTarget() createDevelopmentProjectMetadata(project, release) createPluginProfile(profile) await writeFile(join(project, 'desktop-runtime.json'), JSON.stringify({ - schemaVersion: 1, release, platform: process.platform, arch: process.arch, files: [], + schemaVersion: 1, release, ...desktopTargetPlatform(target), files: [], sharedPackages: ['@deepseek-ai/dsh', '@deepseek-ai/dsh-desktop-host'] .map(name => ({ name, version: manifest.version, path: `node_modules/${name}` })), })) @@ -43,7 +45,6 @@ try { for (const owner of [application, project]) { await symlink(join(repo, 'node_modules/.pnpm/node_modules'), join(owner, 'node_modules'), process.platform === 'win32' ? 'junction' : 'dir') } - const target = `${process.platform === 'darwin' ? 'mac' : 'win'}-${process.arch}` const targetRoot = join(application, '.desktop-build/targets', target) await mkdir(targetRoot, { recursive: true }) await symlink(join(repo, 'apps/desktop/.desktop-build/targets', target, 'runtime'), join(targetRoot, 'runtime'), @@ -61,7 +62,7 @@ try { ...(interactive ? ['--interactive'] : [])], { cwd: root, env: { ...environment, DSH_HOME: join(root, 'home'), USERPROFILE: root, HOME: root, TEMP: root, TMP: root, TMPDIR: root, DSH_WORKSPACE_UPDATE_ROOT: root, DSH_WORKSPACE_UPDATE_TOKEN: randomUUID(), - DSH_DESKTOP_OPEN_DEVTOOLS: '0' }, + DSH_DESKTOP_PRIMARY_RUNTIME_DIR: developmentRuntimeDirectory(), DSH_DESKTOP_OPEN_DEVTOOLS: '0' }, // Hiding the GUI process suppresses its first window and can suspend renderer frame callbacks. stdio: 'inherit', windowsHide: false, }) diff --git a/apps/desktop/src/account-backend.ts b/apps/desktop/src/account-backend.ts index 0db791f631..889b4371bc 100644 --- a/apps/desktop/src/account-backend.ts +++ b/apps/desktop/src/account-backend.ts @@ -2,7 +2,7 @@ import { randomUUID } from 'node:crypto' import WebSocket from 'ws' import { parseRemoteStreamServerMessage, REMOTE_STREAM_MUX_PATH } from '@deepseek-ai/dsh-api-gateway/stream-protocol' -import type { AccountView, SignInAttemptId } from '@deepseek-ai/dsh-deepseek-account/types' +import type { AccountClientMetadata, AccountView, SignInAttemptId } from '@deepseek-ai/dsh-deepseek-account/types' /** Authenticated unary caller shared with native onboarding. */ export type AccountInvoke = (request: { namespace: string; method: string; args: Record }) => Promise @@ -57,14 +57,19 @@ function validateBrowserDestination(value: string): void { export interface DesktopAccountBackend { /** @returns current account snapshot. */ state(): Promise - /** @param locale - active desktop UI language. @returns new or already-running login attempt. */ - start(locale: string): Promise + /** @param client - this window's identity and current language. @returns new or already-running login attempt. */ + start(client: AccountClientMetadata): Promise /** @param id - attempt to cancel. @returns cancellation or completed commit state. */ cancel(id: SignInAttemptId): Promise - /** @returns state after local sign-out. */ - signOut(): Promise - /** @param listener - state recipient. @param failed - stream failure recipient. @returns stream disposer. */ - watch(listener: (state: AccountView) => void, failed: () => void): () => void + /** @param client - this window's identity. @returns state after local sign-out. */ + signOut(client: AccountClientMetadata): Promise + /** + * @param listener - state recipient. + * @param failed - stream failure recipient. + * @param expired - live credential-expiry recipient. + * @returns stream disposer. + */ + watch(listener: (state: AccountView) => void, failed: () => void, expired: () => void): () => void } /** @@ -78,24 +83,30 @@ export function desktopAccountBackend(origin: string, invoke: AccountInvoke, coo const call = async (method: string, args: Record = {}): Promise => accountView(await invoke({ namespace: 'account', method, args })) return { - state: () => call('getState'), start: locale => call('startSignIn', { locale, callbackOrigin: new URL(origin).origin, loginSource: 'desktop' }), - cancel: attemptId => call('cancelSignIn', { attemptId }), signOut: () => call('signOut'), - watch(listener, failed) { + state: () => call('getState'), + start: client => call('startSignIn', { client, callbackOrigin: new URL(origin).origin, loginSource: 'desktop' }), + cancel: attemptId => call('cancelSignIn', { attemptId }), signOut: client => call('signOut', { client }), + watch(listener, failed, expired) { let closed = false let socket: WebSocket | undefined let retry: ReturnType | undefined const connect = (): void => { const streamId = randomUUID() + const expiryStreamId = randomUUID() void cookies().then((cookie) => { if (closed) return const url = new URL(REMOTE_STREAM_MUX_PATH, origin) url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:' socket = new WebSocket(url, { headers: { cookie, origin }, maxPayload: 65_536 }) - socket.on('open', () => socket?.send(JSON.stringify({ type: 'open', streamId, endpoint: 'account/watch', payload: { args: {} } }))) + socket.on('open', () => { + socket?.send(JSON.stringify({ type: 'open', streamId: expiryStreamId, endpoint: 'account/watchExpiry', payload: { args: {} } })) + socket?.send(JSON.stringify({ type: 'open', streamId, endpoint: 'account/watch', payload: { args: {} } })) + }) socket.on('message', (data) => { try { const bytes = Array.isArray(data) ? Buffer.concat(data) : Buffer.isBuffer(data) ? data : Buffer.from(data) const frame = parseRemoteStreamServerMessage(bytes.toString('utf8')) + if (frame.streamId === expiryStreamId && frame.type === 'item' && frame.value === 'session-expired') { expired(); return } if (frame.streamId !== streamId) throw new Error('desktop account: unexpected stream') if (frame.type === 'item') listener(accountView(frame.value)) else socket?.close() diff --git a/apps/desktop/src/background-notice.ts b/apps/desktop/src/background-notice.ts new file mode 100644 index 0000000000..c2a0007d2e --- /dev/null +++ b/apps/desktop/src/background-notice.ts @@ -0,0 +1,56 @@ +/** One-time Windows confirmation before hiding the application in the tray. */ + +import { existsSync, mkdirSync, writeFileSync } from 'node:fs' +import { dirname } from 'node:path' +import type { MessageBoxOptions, MessageBoxReturnValue } from 'electron' +import type { DesktopLocale } from './locale.ts' + +/** Persistent acknowledgement and the shared shell dialog. */ +export interface DesktopBackgroundNoticeOptions { + /** Acknowledgement under Electron userData; updates retain it and uninstall removes it. */ + readonly markerPath: string + readonly locale: () => DesktopLocale + readonly show: (options: MessageBoxOptions) => Promise + readonly focus: () => void +} + +/** Only an explicit acknowledgement permits the first hide; cancelled prompts remain eligible. */ +export class DesktopBackgroundNotice { + private acknowledged = false + private pending = false + private disposed = false + + /** @param options - Marker path, localized copy, and shell dialog actions. */ + constructor(private readonly options: DesktopBackgroundNoticeOptions) {} + + /** + * Request a window hide, prompting until acknowledged and coalescing repeated requests. + * @param hide - Hide the still-owned window after acknowledgement, or immediately when already recorded. + */ + close(hide: () => void): void { + if (this.disposed) return + if (this.pending) { this.options.focus(); return } + if (this.acknowledged || existsSync(this.options.markerPath)) { hide(); return } + this.pending = true + void this.confirm(hide) + } + + /** Ignore late dialog responses after application shutdown begins. */ + dispose(): void { this.disposed = true } + + private async confirm(hide: () => void): Promise { + try { + const { messages } = this.options.locale() + const result = await this.options.show({ type: 'info', title: messages.aboutProduct, + message: messages.backgroundNoticeBody, buttons: [messages.backgroundNoticeConfirm], defaultId: 0, cancelId: -1 }) + if (this.disposed || result.response !== 0) return + this.acknowledged = true + try { + mkdirSync(dirname(this.options.markerPath), { recursive: true }) + writeFileSync(this.options.markerPath, '') + } catch (error) { console.warn('desktop tray: could not record background confirmation', error) } + hide() + } catch (error) { console.warn('desktop tray: background confirmation unavailable', error) } + finally { this.pending = false } + } +} diff --git a/apps/desktop/src/browser-guests.ts b/apps/desktop/src/browser-guests.ts index 027b7cee5b..c3f0b10eea 100644 --- a/apps/desktop/src/browser-guests.ts +++ b/apps/desktop/src/browser-guests.ts @@ -9,6 +9,7 @@ interface GuestLease { readonly partition: string attached: boolean guest?: WebContents + releaseInput?: () => void } /** Owns workspace storage partitions independently from individual tab guests. */ @@ -51,6 +52,7 @@ export class DesktopBrowserGuests { const lease = this.leases.get(key) if (lease === undefined) return if (lease.owner !== owner) throw new Error('desktop browser: guest belongs to another window') + lease.releaseInput?.() this.leases.delete(key) const guest = lease.guest if (guest !== undefined && !guest.isDestroyed()) { @@ -63,8 +65,9 @@ export class DesktopBrowserGuests { /** * Install attachment checks before the application document can create a webview. * @param window - primary application window. + * @param attachInput - attaches native input after guest ownership is verified and returns its disposer. */ - bind(window: BrowserWindow): void { + bind(window: BrowserWindow, attachInput: (guest: WebContents, name: DesktopBrowserLeaseId) => () => void): void { const owner = window.webContents owner.on('will-attach-webview', (event, preferences, params) => { const id = typeof params.src === 'string' && params.src.startsWith('about:blank#') @@ -102,7 +105,8 @@ export class DesktopBrowserGuests { } lease.guest = guest attachedLease = id - guest.once('destroyed', () => { this.leases.delete(id) }) + lease.releaseInput = attachInput(guest, id) + guest.once('destroyed', () => { lease.releaseInput?.(); this.leases.delete(id) }) }) guest.setWindowOpenHandler(({ url, postBody }) => { const lease = attachedLease === undefined ? undefined : this.leases.get(attachedLease) diff --git a/apps/desktop/src/client-metadata.ts b/apps/desktop/src/client-metadata.ts new file mode 100644 index 0000000000..0191bea92d --- /dev/null +++ b/apps/desktop/src/client-metadata.ts @@ -0,0 +1,29 @@ +/** Desktop client identity for one Platform account call. */ +import type { AccountClientMetadata } from '@deepseek-ai/dsh-deepseek-account/types' + +/** + * Read the client build version inlined by the Desktop build. + * @returns the version embedded in this application build. + * @throws Error when the build carries no client version, instead of reporting a guessed one. + */ +export function desktopClientVersion(): string { + const version = process.env.DSH_CLIENT_VERSION + if (version === undefined || version === '') { + throw new Error('desktop account: this application build carries no DSH_CLIENT_VERSION') + } + return version +} + +/** + * Sample the Desktop client identity for one Platform request. + * @param locale - current resolved Desktop language. + * @returns this call's build version, the raw active language, and the UTC offset in whole seconds east. + */ +export function desktopClientMetadata(locale: string): AccountClientMetadata { + return { + version: desktopClientVersion(), + locale, + // Date.getTimezoneOffset reports minutes west of UTC; Platform wants seconds east. + timezoneOffsetSeconds: -new Date().getTimezoneOffset() * 60, + } +} diff --git a/apps/desktop/src/client/WelcomePage.tsx b/apps/desktop/src/client/WelcomePage.tsx index 179bc4ef09..8fcde7768a 100644 --- a/apps/desktop/src/client/WelcomePage.tsx +++ b/apps/desktop/src/client/WelcomePage.tsx @@ -1,6 +1,7 @@ /** Desktop welcome presentation; account and credential operations stay in the preload. */ import { useEffect, useRef, useState } from 'react' import type { FormEvent } from 'react' +import { Toast } from '@deepseek-ai/dsh-client-ui-primitives/src/Toast.tsx' import { StateDot } from '@deepseek-ai/dsh-client-ui-primitives/src/StateDot.tsx' import type { AccountView } from '@deepseek-ai/dsh-deepseek-account/types' import type { WelcomeApi } from '../welcome-api.ts' @@ -9,11 +10,13 @@ type Page = 'entry' | 'key' | 'account' /** * Render the standalone welcome flow using shell-owned operations and localized copy. + * Clearing the account attempt returns the sign-in status page to the initial choices. * @param props.api - isolated preload API; no account credentials reach the renderer. * @returns welcome pages with fixed bottom actions. */ export function Welcome({ api }: { api: WelcomeApi }) { const { messages: m } = api + const [expiryNotice, setExpiryNotice] = useState(false) const [page, setPage] = useState('entry') const pageRef = useRef('entry') const [attempt, setAttempt] = useState(null) @@ -42,15 +45,24 @@ export function Welcome({ api }: { api: WelcomeApi }) { setAttempt(state.attempt) setStarting(false) setCopyFeedback({ status: 'idle' }) - navigate(state.attempt?.phase === 'cancelled' ? 'entry' : 'account') + navigate(state.attempt === null || state.attempt.phase === 'cancelled' ? 'entry' : 'account') } useEffect(() => { mounted.current = true document.documentElement.lang = api.id document.title = m.welcomeTitle + const takeNotice = (): void => { + void api.takeNotice().then((notice) => { + if (mounted.current && notice === 'session-expired') setExpiryNotice(true) + }).catch((_closedChannel: unknown) => { + // A closed Welcome IPC channel must not interrupt the sign-in page. + }) + } + takeNotice() const stop = api.onAccountState((state) => { revision.current++ + takeNotice() showAccount(state) }) return () => { mounted.current = false; stop() } @@ -156,6 +168,7 @@ export function Welcome({ api }: { api: WelcomeApi }) { const heading = page === 'entry' ? 'welcome-heading' : page === 'key' ? 'key-title' : 'auth-status' return <> + {expiryNotice && { setExpiryNotice(false) }} />}