Compare commits

...
Author SHA1 Message Date
Yichen Jiang fb2c4b9e69 Merge pull request #3978 from deepseek-harness/worktree/release-dsh-0.1.5-rc.2
release(dsh): 0.1.5-rc.2
2026-09-10 21:50:19 +08:00
Yichen Jiang a305303422 release(dsh): 0.1.5-rc.2 2026-09-10 21:38:20 +08:00
Yichen Jiang 2107e4697e Merge pull request #3973 from deepseek-harness/worktree/release-0.1.5-backport-feedback-deliverables
feat(web): backport feedback and file refinements to 0.1.5
2026-09-10 21:09:45 +08:00
yixiangihsiangandLegGasai 060323d8e2 feat(web): backport feedback and file refinements to 0.1.5
Backport the selected changes from PR #3928 and PR #3902 onto dsh-v0.1.5-rc.1, retaining baseline session recordings and excluding newer master commits.

Refs #3927
Refs #3903

Co-authored-by: LegGasai <[email protected]>
2026-09-10 20:51:46 +08:00
imccyu 183f08e9c6 Merge pull request #3912 from deepseek-harness/worktree/release/dsh-0.1.5-rc.1
release: [email protected]
2026-09-10 09:36:48 +08:00
imccyu 1ef9c1fa9a release(dsh): 0.1.5-rc.1 2026-09-10 09:13:14 +08:00
imccyu ecc6f11cf1 Merge pull request #3824 from deepseek-harness/worktree/deepseek-flash-catalog
feat(llm): add V41 Flash alongside V4 models
2026-09-10 09:13:00 +08:00
Yichen Jiang 0729dbec66 feat(llm): restore V4 Flash Vision Exp catalog entry 2026-09-10 03:39:57 +08:00
Yichen Jiang 441385fe38 feat(llm): retain V4 models alongside V41 Flash 2026-09-10 03:39:57 +08:00
Yichen Jiang c98fe6ecdd test(web): pin the recorded model before scenario overlays 2026-09-10 03:39:57 +08:00
Yichen Jiang 719331ecb7 test: keep webhook smoke on the shipped model route 2026-09-10 03:39:56 +08:00
Yichen Jiang 61c5954372 test: pin model routes in webhook and Cordis fixtures 2026-09-10 03:39:56 +08:00
Yichen Jiang bc5fd3b8dc feat(llm): default Chat Completions to DeepSeek V41 Flash 2026-09-10 03:39:56 +08:00
imccyu 4cbaeb8d69 Merge pull request #3909 from deepseek-harness/fix/sidebar-preview-layout-polish
fix(client): refine sidebar previews, guide, and stats
2026-09-10 03:38:01 +08:00
imccyu 3435dbd690 fix(web): address sidebar and stats review feedback 2026-09-10 03:20:55 +08:00
imccyu 57da0906f3 Merge remote-tracking branch 'refs/remotes/origin/pr-3910' into fix/sidebar-preview-layout-polish 2026-09-10 02:04:17 +08:00
imccyu ded26f225d chore(client): refresh slot catalog 2026-09-10 01:57:14 +08:00
imccyu 19b3c4c34b fix(client): keep preview scrollports current 2026-09-10 01:51:21 +08:00
Yif 53d5c9386e fix(sidebar): pin the guide hero to the pure-gray ramp
The label-dimmed alias rides the bluish neutral ramp, whose cast shows
at the 56px compass; the hero now takes neutral-200 (light) and
neutral-700 (dark) from the pure-gray static ramp.
2026-09-10 01:32:45 +08:00
Yif 1c044f5140 feat(sidebar): refine guide start page and quiet stat pill noise
The guide tab gains a compass hero, per-entry descriptions (shown while
at most four entries are listed), and a quieter cube placeholder for
entries that registered no glyph; the files entry registers its
description and folder glyph. Bundled stat fixes: the session usage
dialog drops the zero cache-write row, and the turn-time pill renders as
plain text when its dialog would only repeat the pill's own duration.
2026-09-10 01:23:24 +08:00
imccyu 284ab15519 fix(client): refine sidebar document previews 2026-09-10 01:04:55 +08:00
imccyu b2e3b2a012 Merge pull request #3893 from deepseek-harness/worktree/release/dsh-0.1.5-alpha.2
release: [email protected]
2026-09-09 22:13:03 +08:00
imccyu dd393c1820 release(dsh): 0.1.5-alpha.2 2026-09-09 22:02:09 +08:00
Tianyi Cui 7588e1ea11 Merge pull request #3901 from deepseek-harness/revert-3710-feat/mermaid-preview
Revert "feat(web): preview Mermaid, Graphviz, SVG, and HTML code fences"
2026-09-09 22:01:43 +08:00
Tianyi Cui 58956c1a8a Revert "feat(web): preview Mermaid, Graphviz, SVG, and HTML code fences" 2026-09-09 22:01:10 +08:00
Yudong Han 83253e0d16 Merge pull request #3710 from deepseek-harness/feat/mermaid-preview
feat(web): preview Mermaid, Graphviz, SVG, and HTML code fences
2026-09-09 20:24:43 +08:00
imccyu 9d83e3e534 Merge pull request #3890 from deepseek-harness/feat/sidebar-image-preview
feat(sidebar): preview image files
2026-09-09 20:17:43 +08:00
imccyu 8870a13aa9 feat(sidebar): preview image files 2026-09-09 20:01:24 +08:00
Tianyi Cui f05e0fb6b9 Merge pull request #3878 from deepseek-harness/fix/ci-cancel-superseded
fix(ci): cancel superseded PR and master validation
2026-09-09 20:00:13 +08:00
Yudong 7aa73877e6 Merge origin/master into feat/mermaid-preview 2026-09-09 19:53:42 +08:00
Yudong 516bfd5f30 test(web): cover preview import recovery and color schemes 2026-09-09 19:49:56 +08:00
imccyu 16953f2b8e Merge pull request #3884 from deepseek-harness/feat/public-experimental-agent-team
release: publish experimental Agent Teams packages
2026-09-09 19:21:51 +08:00
imccyu fbfc8123e3 Merge pull request #3871 from deepseek-harness/worktree-fixworkerflock
fix(webworker): restore session and workspace writes
2026-09-09 19:21:07 +08:00
imccyu 63187de80f release: publish experimental Agent Teams packages 2026-09-09 18:54:14 +08:00
imccyu 9b308c9568 Merge pull request #3819 from deepseek-harness/feat/artifact-file-actions
feat(web): unify file icons, delivery actions, and sidebar interactions
2026-09-09 18:51:34 +08:00
Ruilin Geng 2b521b31f1 Merge pull request #3846 from deepseek-harness/fix/mcp-pagination-cycles
fix(mcp): reject repeated tool discovery cursors
2026-09-09 18:46:44 +08:00
creatixchu 0b3248e67d test(web): stabilize delivered-file snapshots across CI hosts 2026-09-09 18:21:45 +08:00
imccyu d7ecdcf02c fix(lint): parenthesize file handle callback 2026-09-09 18:21:17 +08:00
imccyu 60a3d0fbc2 fix(webworker): support file handle chmod 2026-09-09 18:21:17 +08:00
imccyu 950474605f docs(webworker): record file handle compatibility 2026-09-09 18:21:16 +08:00
imccyu a7bd71e024 fix(webworker): preserve bigint file handle identity 2026-09-09 18:21:16 +08:00
imccyu 0a9c774617 docs(webworker): document bigint handle identity 2026-09-09 18:21:16 +08:00
Tianyi Cui 3c4c6c3d7b fix(ci): cancel superseded PR and master validation 2026-09-09 18:20:01 +08:00
gengruilin 556857bcd2 Merge origin/master into fix/mcp-pagination-cycles 2026-09-09 18:15:36 +08:00
creatixchu b53fed39d7 Merge remote-tracking branch 'origin/master' into worktree/pr-3819-release-sync 2026-09-09 18:07:26 +08:00
creatixchu b9587ada12 fix(web): open delivered files using the viewed session scope 2026-09-09 18:07:16 +08:00
Tianyi Cui 8803287f71 Merge pull request #3853 from deepseek-harness/fix/3835-tool-guidance-restrictions
fix: respect scoped tools in filesystem and web guidance
2026-09-09 18:04:11 +08:00
yudshj 4e0a405a9b fix(web): size diagram previews to image content 2026-09-09 18:01:36 +08:00
creatixchu 2ab73152ae Merge remote-tracking branch 'origin/master' into worktree/pr-3819-release-sync 2026-09-09 18:01:07 +08:00
creatixchu 7f69a3ec37 fix(web): complete shared file icon consumers and browser checks 2026-09-09 18:01:04 +08:00
creatixchu 43bf1d3f93 Merge remote-tracking branch 'origin/master' into worktree/pr-3819-release-sync 2026-09-09 17:56:14 +08:00
creatixchu 454caf0280 fix(web): reject empty sidebar splits and clarify page targeting 2026-09-09 17:56:11 +08:00
imccyu bd60582403 Merge pull request #3859 from deepseek-harness/worktree-sidebarsubagent
fix(workspace-files): support subagent session roots
2026-09-09 17:55:17 +08:00
creatixchu 9961eedec8 fix(web): preserve office file icons and lazy sidebar replay 2026-09-09 17:48:47 +08:00
Tianyi Cui cd95dda1bd Merge pull request #3866 from deepseek-harness/docs/session-format-authority
docs(session): centralize format status and timeless guidance
2026-09-09 17:46:17 +08:00
HYD@OVERTON 9e050260e4 feat(web): adapt diagram previews to application theme 2026-09-09 17:39:04 +08:00
yudshj fb84576ea7 refactor(web): unify markdown preview components and notes 2026-09-09 17:39:04 +08:00
yudshj a8f9d81f3a feat(client): preview Graphviz, SVG, and HTML Markdown fences 2026-09-09 17:39:04 +08:00
fz 4fabbd39c5 test(web): scope Mermaid snapshots to diagram content 2026-09-09 17:39:04 +08:00
fz 0bfd594875 refactor(ui): use tagged Mermaid preview results 2026-09-09 17:39:04 +08:00
fz 220103670a fix(ui): retain Mermaid previews and support hybrid touch controls 2026-09-09 17:39:04 +08:00
fz fc0c885287 style(ui): simplify Mermaid preview controls 2026-09-09 17:39:04 +08:00
fz ee35e40bc8 feat(ui): preview Mermaid diagrams in Chat code blocks 2026-09-09 17:39:04 +08:00
creatixchu 7c9b29563d Merge branch 'worktree/pr-3872-release-sync' into worktree/pr-3819-release-sync 2026-09-09 17:34:20 +08:00
creatixchu c6b3900d2a Merge remote-tracking branch 'origin/master' into worktree/pr-3872-release-sync 2026-09-09 17:33:47 +08:00
imccyu d7dcc5f5af test(web): update sidebar preview expectations 2026-09-09 17:29:38 +08:00
imccyu 177eacbe8b docs(workspace-files): clarify session scope behavior 2026-09-09 17:29:38 +08:00
imccyu c5432b94f9 chore: satisfy workspace files CI gates 2026-09-09 17:29:38 +08:00
imccyu 7214a97723 fix(workspace-files): resolve subagent session roots 2026-09-09 17:29:38 +08:00
Yif 3b4122ac16 feat(client): polish sidebar and file preview interactions
Seed sidebar default pages lazily on expansion, scope page-tab dedupe
to the target pane, let a sole tab split its own pane with a factory
backfill, close menus when focus enters a sandboxed iframe, and pin the
code preview copy banner while unifying its background with the pane.
2026-09-09 17:27:37 +08:00
creatixchu 1d55cab9e6 fix(web): use shared file type icons in delivery cards 2026-09-09 17:23:07 +08:00
creatixchu 644f6abd7c Merge branch 'worktree/pr-3858-release-sync' into worktree/pr-3819-release-sync
# Conflicts:
#	packages/client/ui-primitives/README.i18n.yaml
#	packages/client/ui-primitives/README.md
#	packages/client/ui-primitives/README.zh.md
2026-09-09 17:20:37 +08:00
creatixchu a7b5c8a043 Merge remote-tracking branch 'origin/master' into worktree/pr-3858-release-sync 2026-09-09 17:20:01 +08:00
creatixchu f5804826a8 Merge remote-tracking branch 'origin/master' into codex/pr-3819 2026-09-09 17:13:08 +08:00
Tianyi Cui 8a41f7a8e1 docs(session): clarify release authority review findings 2026-09-09 17:12:06 +08:00
Tianyi Cui 56c4c3e47c docs(session): centralize format status and timeless guidance 2026-09-09 17:06:03 +08:00
Tianyi Cui bafe887d6d Merge pull request #3851 from deepseek-harness/docs/released-v3-wording
docs(session): correct released V3 compatibility guidance
2026-09-09 17:05:14 +08:00
creatixchu dfda1d6aaf fix(web): ship protocol runtime dependency for delivered file actions 2026-09-09 17:02:24 +08:00
gengruilin 86c61e24e9 Merge origin/master into fix/mcp-pagination-cycles 2026-09-09 16:57:25 +08:00
creatixchu 99bffa7f9a fix(web): update delivery card snapshot and remove unused button segments 2026-09-09 16:52:04 +08:00
creatixchu b443c4d246 fix(present): resolve file services in live agent scope and refresh snapshots 2026-09-09 16:48:39 +08:00
creatixchu 7e4d9edc13 Merge remote-tracking branch 'origin/master' into codex/pr-3819 2026-09-09 16:45:05 +08:00
creatixchu 00bfdfbce6 fix(present): follow session filesystem access for deliverables 2026-09-09 16:44:51 +08:00
yixiangihsiang 1eee75b424 fix(client): satisfy icon validation gates 2026-09-09 16:41:15 +08:00
yixiangihsiang 4ee9e055d5 feat(client): add shared file type icons 2026-09-09 16:41:15 +08:00
Turtle 6d99a8a53a Merge pull request #3794 from deepseek-harness/turtle/issue-3761-plugin-instance-label
fix(web): distinguish same-package plugin instances
2026-09-09 16:29:54 +08:00
Tianyi Cui a5fc275a56 docs(session): address scoped review clarifications 2026-09-09 16:26:49 +08:00
Turtle d6a699be19 Merge pull request #3845 from deepseek-harness/turtle/keep-blocked-approval-pending
Keep blocked weighted approvals pending
2026-09-09 16:20:11 +08:00
creatixchu 74bf7aaa2f fix(web): preserve artifact actions across reconnects and keyboard use 2026-09-09 16:18:24 +08:00
fz aed212657a docs: clarify scoped guidance and file observation policy 2026-09-09 16:13:09 +08:00
Turtle e9f1725b11 docs: record pending weighted approval blockers 2026-09-09 15:58:21 +08:00
turtle1999 0d44848ba6 Rename weighted approval publisher job 2026-09-09 15:58:21 +08:00
turtle1999 8eede0f60d Keep blocked approvals pending 2026-09-09 15:58:21 +08:00
yx.zhang 057b4879cf feat(web): align presented file cards with design 2026-09-09 15:53:44 +08:00
fz 4029451fa7 test: refresh guidance for the fetch-only composition 2026-09-09 15:50:06 +08:00
fz 9d6c964985 fix: respect scoped tools in filesystem and web guidance 2026-09-09 15:45:54 +08:00
Turtle 2e2489b888 fix(web): trim composition marker from plugin subtitles 2026-09-09 15:41:02 +08:00
Tianyi Cui 7b6b8a2baa docs(session): correct released V3 compatibility guidance 2026-09-09 15:32:55 +08:00
Turtle 2b631c0646 test(web): update plugin settings golden order 2026-09-09 15:27:18 +08:00
yudshj c83f02ad81 fix(web): defer desktop metadata until delivery cards appear 2026-09-09 15:26:34 +08:00
yudshj 5b671d7df3 fix(web): show artifact paths relative to the workspace 2026-09-09 15:26:34 +08:00
yudshj b27d861741 docs: refresh native file action catalog references 2026-09-09 15:26:34 +08:00
yudshj 4158a96e14 feat(web): add native file actions to artifact cards 2026-09-09 15:26:28 +08:00
imccyu da042b78ff Merge pull request #3765 from deepseek-harness/worktree/issue-3515-feedback-dialog
反馈弹窗:点踩与 /feedback 共用一个带分类的弹窗,提交后出 toast
2026-09-09 15:24:24 +08:00
Turtle 1349af8e97 fix(web): give plugin identities a full row 2026-09-09 14:57:45 +08:00
creatixchu 0b5fca5c68 Merge remote-tracking branch 'origin/master' into worktree/issue-3515-feedback-dialog
# Conflicts:
#	apps/web/tests/message-feedback-layout.e2e.ts
2026-09-09 14:56:31 +08:00
Yudong Han ba5ce5700c Merge pull request #3832 from deepseek-harness/fix/file-delivery-present
fix(deliverables): distinguish file changes and require explicit delivery
2026-09-09 14:53:17 +08:00
gengruilin 96ac11885e Merge origin/master into fix/mcp-pagination-cycles 2026-09-09 14:40:06 +08:00
Turtle f42fddad34 Merge pull request #3840 from deepseek-harness/turtle/remove-weighted-approval-cyborg-text
Remove cyborg wording from weighted approval
2026-09-09 14:35:50 +08:00
Tianyi Cui 456162410b Merge pull request #3780 from deepseek-harness/fix/master-ci-3661
test(ci): 固定异步完成观察并收紧导入豁免
2026-09-09 14:35:17 +08:00
CreatixChu 4f0adbc99a Merge pull request #3839 from deepseek-harness/fix/3838-composer-placeholder
fix(web): 输入空白字符后隐藏 Composer 占位提示
2026-09-09 14:34:43 +08:00
Huanqi Cao cc5a7697e7 Merge pull request #3698 from deepseek-harness/feat/picker-alt-foreground
fix(picker): foreground-activate the Windows native folder dialog via a synthesized Alt press
2026-09-09 14:28:23 +08:00
turtle1999 1eaba2809b Remove cyborg wording from weighted approval 2026-09-09 14:28:10 +08:00
creatixchu 6c4a2fb294 Merge remote-tracking branch 'origin/master' into worktree/issue-3515-feedback-dialog
# Conflicts:
#	packages/client/ui-model-selection/tests/browser-plugin.client.spec.ts
2026-09-09 14:27:15 +08:00
creatixchu 224f75dc63 test(web): strengthen composer placeholder regression evidence 2026-09-09 14:15:25 +08:00
yx.zhang 30ea609363 Merge remote-tracking branch 'origin/pr-3765-head' into pr-3765 2026-09-09 14:06:27 +08:00
creatixchu a6ee97ebe1 Merge remote-tracking branch 'origin/master' into fix/3838-composer-placeholder 2026-09-09 14:04:23 +08:00
creatixchu 0f1164cdee fix(web): hide composer placeholder for whitespace drafts 2026-09-09 13:56:54 +08:00
yx.zhang 4b3cfcfaf3 style(feedback): refine feedback dialog disclosure and layout 2026-09-09 13:56:53 +08:00
Turtle cad50c2504 Merge pull request #3792 from deepseek-harness/turtle/issue-3762-provider-base-url-validation
fix(web): validate custom provider base URLs
2026-09-09 13:54:48 +08:00
yudshj 9708c4bb42 test(web): scope SVG delivery snapshot to the chat transcript 2026-09-09 13:41:56 +08:00
yudshj 152e0f42ca fix(web): await settled browser state and shorten file-change label 2026-09-09 13:41:56 +08:00
yudshj 7a0afea27f fix(deliverables): distinguish file changes and require explicit delivery 2026-09-09 13:41:56 +08:00
Turtle fac33d7ba7 Merge pull request #3791 from deepseek-harness/turtle/issue-3760-zh-display-model-copy
fix(web): localize Chinese display and model copy
2026-09-09 13:36:09 +08:00
gengruilin 8053f3d450 Merge origin/master into fix/mcp-pagination-cycles 2026-09-09 13:19:42 +08:00
Tianyi Cui 6bc836c0c0 docs(ci): distinguish fixture controls from completion policy 2026-09-09 13:18:09 +08:00
Tianyi Cui 1b56cf6013 test(ci): retain useful regression controls after master rebase 2026-09-09 13:18:09 +08:00
Tianyi Cui da1df501b8 test(runtime): isolate busy-meter decisions from worker startup 2026-09-09 13:18:09 +08:00
Tianyi Cui 43d00069a9 test(web): await restoration before workspace actions 2026-09-09 13:18:09 +08:00
Tianyi Cui bc55f10a46 test(web): wait for admitted queue before steering shortcut 2026-09-09 13:18:09 +08:00
Tianyi Cui d85bdd80c1 test(ci): observe command readiness and transport settlement 2026-09-09 13:18:08 +08:00
Tianyi Cui c93bfee16e test(web): drain retained request handlers before teardown 2026-09-09 13:18:08 +08:00
Tianyi Cui e7feedab5e test(web): await durable UI and responsive layout publication 2026-09-09 13:18:08 +08:00
Tianyi Cui d38391d629 test(web): release timed-out barriers and await frame animations 2026-09-09 13:18:08 +08:00
Tianyi Cui 94a2b0a248 test(ci): await details transitions and report benchmark runtime 2026-09-09 13:18:08 +08:00
Tianyi Cui 5b0d65fd72 test(ci): observe asynchronous completion and settled layout 2026-09-09 13:18:08 +08:00
Huanqi Cao 2059bdf78e Merge remote-tracking branch 'origin/master' into feat/picker-alt-foreground 2026-09-09 13:17:20 +08:00
Turtle ebd7e82075 Merge pull request #3834 from deepseek-harness/turtle/remove-automatic-review-requests
ci: remove automatic review requests
2026-09-09 13:13:25 +08:00
Turtle 939222a4ad fix(web): normalize custom provider base URLs 2026-09-09 13:12:43 +08:00
Turtle d6ed693f23 ci: remove automatic review requests 2026-09-09 12:56:06 +08:00
imccyu 88dfd72537 Merge pull request #3807 from deepseek-harness/sidebar-ui-polish-main
feat(web): right sidebar UI polish
2026-09-09 12:49:57 +08:00
creatixchu 0199633269 Merge remote-tracking branch 'origin/master' into worktree/issue-3515-feedback-dialog 2026-09-09 12:45:32 +08:00
creatixchu 700e8df91a test(feedback): cover the seed-failure and unmount paths of the Dislike control 2026-09-09 12:45:31 +08:00
imccyu 2f2831f033 test(web): align sidebar interaction expectations 2026-09-09 12:15:00 +08:00
imccyu ff3ccb4d7c test(web): use supported sidebar visibility assertion 2026-09-09 12:15:00 +08:00
imccyu 3481d4043e fix(client): align sidebar checks after rebase 2026-09-09 12:15:00 +08:00
Yif d0a1ab8723 chore(client): regenerate slot catalog after master merge 2026-09-09 12:15:00 +08:00
Yif c73dcecb96 fix(textpreview): say a stat-and-read failure once
A file whose stat and first page both fail — outside the workspace, gone —
showed the same line twice: the metadata bar above an identical centred body
failure. The bar now stands only over pages already loaded, and the centred
retry runs the full reload so one press clears both halves.
2026-09-09 12:15:00 +08:00
Yif 284758cbc3 test(web): refresh goldens for the sidebar aria renames
The expand/collapse and wrap toggles' accessible names diverged from their
tooltips, and the replay harness now normalizes clientTimeZone in recorded
sessions; every golden holding the old names or the literal zone refreshes.
2026-09-09 12:15:00 +08:00
Yif c76e371874 fix(sidebar): address review feedback on aria names, touch hits, and fullscreen close
- Split toggle aria-labels from their tooltips: the sidebar expand/collapse
  buttons announce "Open/Collapse right sidebar" so the two sidebars stay
  distinguishable, and the wrap toggle keeps an invariant "Line wrap" name
  beside aria-pressed while the tooltip keeps the action wording.
- A hidden tab close also takes no pointer events, so a touch press on the
  chip's trailing edge activates the tab instead of closing it; e2e closes
  hover the chip first, the way a reader would.
- Closing the last docked tab in fullscreen hands the mode back to push, so
  the next expand does not give the whole window to the start page.
- The drop scrim mixes from bg-base, not bg-layer-2, which dark mode binds
  to a lighter bluish step than the column beneath it.
- Document the menuitem probe in TabMenuExtras and the strip fade's known
  gap; match the open-in-app split-button comment to the 28px control row.
2026-09-09 12:14:59 +08:00
Yif 814f447b8f fix(dockkit): move ui-primitives to devDependencies and hoist zone glyph paths past the i18n gate 2026-09-09 12:14:59 +08:00
Yif 5e44fc79d3 test(web): refresh header and file-preview goldens for renamed controls 2026-09-09 12:14:59 +08:00
Yif 7a032b6366 test(web): disambiguate the left sidebar toggle from the right expand control 2026-09-09 12:14:58 +08:00
Yif 237618ca33 test(dockkit): cover the bottom drop-zone glyph 2026-09-09 12:14:58 +08:00
Yif e94241f601 feat(web): move the session-log control into the header more-actions menu 2026-09-09 12:14:58 +08:00
Yif 5ee343f735 feat(sidebar): live tab titles with file-type icons and disambiguated paths 2026-09-09 12:14:58 +08:00
Yif f4c1e31ba8 feat(sidebar): last-tab close rules and collapsed expand button
The lone guide tab withholds its close and menu, any other lone tab closes
together with the column, and the expand button renders only while collapsed
so the corner seat costs the header nothing.
2026-09-09 12:14:58 +08:00
Yif 838dbbe0d0 feat(dockkit): refine strip and chip presentation, close policy, and room reading
Chip capsules with scroll fades and live titles, drop-zone hint cards, the
canCloseTab control policy with the quiet lone chip and self-dismissing empty
menu, and a room reading that stays independent of hidden split controls.
2026-09-09 12:14:58 +08:00
Yif 69a13cef6d feat(primitives): add file-type icon set and shared link icon 2026-09-09 12:14:57 +08:00
Turtle bc4fde06ac fix(web): validate custom provider base URLs 2026-09-09 12:04:40 +08:00
gengruilin 189ca97ec9 Merge origin/master into fix/mcp-pagination-cycles 2026-09-09 12:04:24 +08:00
Tianyi Cui 08f646da36 Merge pull request #3812 from deepseek-harness/worktree/ci-reliability-master-followup-20260908
test(ci): stabilize asynchronous fixtures and benchmark budgets
2026-09-09 11:52:54 +08:00
gengruilin 454825ca38 Merge origin/master into fix/mcp-pagination-cycles 2026-09-09 11:49:04 +08:00
creatixchu 4b88085c2a style(feedback): refine dialog proportions 2026-09-09 11:41:24 +08:00
Tianyi Cui 2c0596c1ba docs(bench): clarify reviewed request-history limit 2026-09-09 11:29:05 +08:00
Tianyi Cui ba4b8fddeb test(bench): calibrate hosted cold Agent resume limit 2026-09-09 11:26:48 +08:00
Tianyi Cui 2567d35cdf docs(bench): synchronize request-history limit 2026-09-09 11:26:48 +08:00
Tianyi Cui 843029448a test(code-runtime): allow measured worker initialization time 2026-09-09 11:26:48 +08:00
Tianyi Cui d1b1488ed3 test(session): await durable live writes with owned teardown 2026-09-09 11:26:48 +08:00
Tianyi Cui bd24f8a17f test(app-boot): control user-patch HMR event delivery 2026-09-09 11:26:48 +08:00
Tianyi Cui dc14f5e4f9 test(web): await resized details geometry through its transition 2026-09-09 11:26:48 +08:00
Tianyi Cui 48007d76f2 test(bench): allow measured request-history runner variation 2026-09-09 11:26:48 +08:00
Tianyi Cui fd5d68586f test(web): wait for model selection menu closure 2026-09-09 11:26:48 +08:00
Turtle 9606b69545 Merge origin/master into turtle/issue-3760-zh-display-model-copy 2026-09-09 11:02:57 +08:00
Turtle 43846e7032 Merge pull request #3783 from deepseek-harness/turtle/weighted-approval
feat: enforce weighted pull request approvals
2026-09-09 11:00:39 +08:00
Turtle 9da63ca94d Merge pull request #3789 from deepseek-harness/turtle/issue-3757-settings-accessible-name
fix(client): name collapsed Settings trigger
2026-09-09 10:56:30 +08:00
creatixchu 6207453d36 Merge remote-tracking branch 'origin/master' into worktree/issue-3515-feedback-dialog 2026-09-09 10:44:25 +08:00
creatixchu d692289533 style(feedback): compact the dialog to a 540px card with lighter chips and a grown detail box 2026-09-09 10:42:06 +08:00
imccyu c57fb6f7ef Merge pull request #3798 from deepseek-harness/worktree-sidebarfeat
feat(client): document previews — HTML, PDF, Markdown and code
2026-09-09 10:41:39 +08:00
creatixchu 1094431de9 docs(feedback): document the FeedbackSurface fields for the export-jsdoc gate 2026-09-09 10:33:09 +08:00
creatixchu a25e5fd8a9 test(sdk): refresh the feedback expectations on the V3 base and restore the frozen v2 generation 2026-09-09 10:27:15 +08:00
creatixchu 3e53a08f36 fix(feedback): keep the category tuple out of types.ts, retire the toast with its entry, and answer the review 2026-09-09 10:27:12 +08:00
creatixchu f2f9700de2 feat(feedback): open one feedback dialog from /feedback and Dislike, with categories and a toast
Dislike and a bare /feedback open the Session's feedback dialog, which
collects one of seven fixed categories and an optional description and
records through the messageFeedback put or the new sessionFeedback
Remote; Like records at once. A recorded rating shows the filled glyph
and every submission is acknowledged by a toast. feedback/record and
MessageFeedbackItem carry the optional category; the note popover, its
layout scenario, and the clearNote/clear verbs are removed. ui-commands
gains the action command kind the /feedback decoration runs as.

Closes #3515
2026-09-09 10:20:24 +08:00
imccyu 64560eaff1 fix(client): remove stale preview contracts 2026-09-09 10:12:46 +08:00
imccyu 93b30b9765 fix(client): narrow document preview contracts 2026-09-09 10:12:46 +08:00
imccyu be58ae0577 test(web): await sidebar collapse before snapshots 2026-09-09 10:12:46 +08:00
imccyu 4d07fbcb85 fix(client): address document preview review feedback 2026-09-09 10:12:46 +08:00
imccyu ce28b0672f fix(client): simplify PDF observer cleanup 2026-09-09 10:12:46 +08:00
imccyu 39872bafe6 docs(client): record sidebar guide translation 2026-09-09 10:12:45 +08:00
imccyu c78fdb583a fix(ci): refresh document preview metadata 2026-09-09 10:12:45 +08:00
imccyu 693621dcad fix(client): streamline continuous PDF previews 2026-09-09 10:12:41 +08:00
imccyu dcfd8c299d refactor(client): rename document preview package 2026-09-09 10:12:40 +08:00
imccyu 5c283d27e2 fix(client): allow outside previews and streamline document readers 2026-09-09 10:12:39 +08:00
imccyu 4321766ead feat(client): add extensible document previews and sidebar defaults 2026-09-09 10:12:38 +08:00
Yichen Jiang e9b3f80f0b Merge pull request #3724 from deepseek-harness/worktree/pi-ai-settings-recovery
fix(llm-pi-ai): keep catalog-invalid settings repairable
2026-09-09 06:37:54 +08:00
Yichen Jiang d80891921b Merge remote-tracking branch 'origin/master' into worktree/pi-ai-settings-recovery
# Conflicts:
#	packages/llm/llm/README.i18n.yaml
#	packages/llm/llm/README.md
#	packages/llm/llm/README.zh.md
2026-09-09 06:18:13 +08:00
imccyu ab904f4b6b Merge pull request #3813 from deepseek-harness/worktree-nodeaddworkflow
ci(native): consolidate platform compatibility jobs
2026-09-09 02:45:46 +08:00
imccyu 063165a800 ci(native): consolidate platform compatibility jobs 2026-09-09 02:31:43 +08:00
fz 0ba6c25807 Merge pull request #3510 from deepseek-harness/feat/remove-str-replace-editor-from-minimal
feat(minimal): make editor opt-in and align bash output
2026-09-09 02:10:26 +08:00
fz 452fe6de55 Merge remote-tracking branch 'origin/master' into feat/remove-str-replace-editor-from-minimal 2026-09-09 01:49:09 +08:00
fz 887c1efd7a ci(npm): expose failed install HTTP diagnostics 2026-09-09 01:48:54 +08:00
fz 0f6e7442d7 perf(session): bundle migration verifier dependencies 2026-09-09 01:48:27 +08:00
Yudong Han 6635cddaa4 Merge pull request #3569 from deepseek-harness/fs/stream-bytes
feat(web): declare workspace deliveries and open source files
2026-09-09 01:33:20 +08:00
fz 40c9766a8d Merge origin/master into feat/remove-str-replace-editor-from-minimal 2026-09-09 01:22:09 +08:00
Yudong 228f3aef83 test(ci): stabilize completion waits and Session fixtures 2026-09-09 01:15:31 +08:00
yudshj 72549e91a0 test(present): pass the event to delivery matcher 2026-09-09 01:15:31 +08:00
yudshj cd2b9ca04a refactor(present): restore existing conversation coordinate handling 2026-09-09 01:15:31 +08:00
yudshj 207dce0bee docs(present): refresh module graph after removing attachments 2026-09-09 01:15:31 +08:00
yudshj c9038b4b31 refactor(present): declare and open workspace source files 2026-09-09 01:15:31 +08:00
yudshj 387e437af4 fix(web): use the preview-compatible stream promises entry 2026-09-09 01:15:31 +08:00
yudshj 6d8a400d79 fix(web): open delivered snapshots in the default application 2026-09-09 01:15:31 +08:00
yudshj 37d27fcdf9 feat(web): present immutable file deliveries with download cards 2026-09-09 01:15:31 +08:00
imccyu 4d831f2d14 Merge pull request #3771 from deepseek-harness/worktree-fixreactpeer
fix(web): move client dependencies to devDependencies
2026-09-09 01:15:27 +08:00
imccyu bfe82d4c2d Merge pull request #3784 from deepseek-harness/worktree-leftsideslot
feat(web): add panellist to left-sidebar
2026-09-09 00:59:11 +08:00
Dudu-0223 a4176ef851 Merge pull request #3674 from deepseek-harness/feat/parent-subagent-catalog-foundation
feat(subagent): record and observe parent-owned child catalogs
2026-09-09 00:37:47 +08:00
imccyu f39a37a523 fix(client): keep browser dependencies out of production installs 2026-09-09 00:30:37 +08:00
imccyu f3d7ef2b95 docs(client): define browser third-party build inputs 2026-09-09 00:30:36 +08:00
imccyu 58144ccf78 test(web): await command and settings readiness before assertions 2026-09-09 00:26:41 +08:00
imccyu e807447288 fix(client): re-read navigation cancellation after preparation 2026-09-09 00:26:41 +08:00
imccyu 713b1aacad docs(client): synchronize panel navigation APIs and contracts 2026-09-09 00:26:40 +08:00
imccyu 385f651c5f fix(test): release default slot runtime sources symmetrically 2026-09-09 00:26:36 +08:00
imccyu 8715fd2a87 fix(client): preserve the latest panel and session navigation 2026-09-09 00:26:36 +08:00
imccyu bc840b483e feat(client): simplify and exercise sidebar panel entries 2026-09-09 00:26:35 +08:00
imccyu 092d16d7ab style(client): satisfy panel lint rules 2026-09-09 00:26:35 +08:00
imccyu 9736136d95 fix(client): leave global panel entries empty by default 2026-09-09 00:26:34 +08:00
imccyu fbbcbf33fe docs(client): document global main-panel extension points 2026-09-09 00:26:34 +08:00
imccyu f95e781f3d test(client): migrate panel navigation fixtures and snapshots 2026-09-09 00:26:29 +08:00
imccyu fe460f7fd1 test(client): support panel selection in slot runtime 2026-09-09 00:26:29 +08:00
imccyu 581803bf57 feat(client): add global sidebar panels 2026-09-09 00:26:28 +08:00
fz b42b5b5e94 fix(ci): align minimal prompt-history expectations with shell-only turns 2026-09-08 23:57:15 +08:00
gengruilin 594305ce19 fix(mcp): reject repeated tool discovery cursors
Refs: https://github.com/deepseek-ai/deepseek-harness/discussions/3660
2026-09-08 23:33:23 +08:00
fz 25d675fcf3 Merge origin/master into feat/remove-str-replace-editor-from-minimal 2026-09-08 23:31:51 +08:00
Dudu-0223 4977ccc965 chore(chunked-list): follow master release version 2026-09-08 23:29:58 +08:00
fz 3c05dcb537 fix(ci): refresh persistent bash fixtures and synchronize LSP lifecycle test 2026-09-08 23:29:03 +08:00
Dudu-0223 5ab91467e2 test(cli): include catalog facts in profile expectations 2026-09-08 23:28:50 +08:00
Dudu-0223 79dda6cf45 test(subagent): align catalog snapshots with Session V3 2026-09-08 23:28:50 +08:00
Dudu-0223 e2fa69f5e2 test(snapshot): bind sibling roles to catalog publication order 2026-09-08 23:28:50 +08:00
Dudu-0223 9f69a7fb16 refactor(subagent): extract persistent chunked list utility 2026-09-08 23:28:50 +08:00
Dudu-0223 661135fe29 fix(subagent): reject invalid catalogs and preserve snapshot event order 2026-09-08 23:28:50 +08:00
Dudu-0223 ba731d1c9e fix(subagent): handle rejected runs after catalog failure 2026-09-08 23:28:50 +08:00
Dudu-0223 867c47c415 docs: drop unrelated projection README whitespace changes 2026-09-08 23:28:50 +08:00
Dudu-0223 59623c8ff4 docs(subagent): refresh event declaration references 2026-09-08 23:28:50 +08:00
Dudu-0223 0274a6dd75 fix(subagent): preserve catalog augmentation in declarations 2026-09-08 23:28:50 +08:00
Dudu-0223 924282cbcd fix(subagent): retain catalog event types in host exports 2026-09-08 23:28:50 +08:00
Dudu-0223 532e712c7b refactor(subagent): expose catalog through existing projection views 2026-09-08 23:28:50 +08:00
Dudu-0223 3dcabbba44 refactor(session-query): return all projection states by default 2026-09-08 23:28:50 +08:00
Dudu-0223 e3cb6dd352 refactor(session): limit hydration views to all or none 2026-09-08 23:28:50 +08:00
Dudu-0223 80e34ce709 perf(subagent): list parent catalog in event order 2026-09-08 23:28:50 +08:00
Dudu-0223 99462aef98 fix(subagent): preserve catalog citations and skip unrequested views 2026-09-08 23:28:50 +08:00
Dudu-0223 399d7313c4 test(session): cover historical catalog comparison failures 2026-09-08 23:28:50 +08:00
Dudu-0223 2db4bdd31d feat(subagent): record and observe parent-owned child catalogs 2026-09-08 23:28:50 +08:00
imccyu 5dda764ed3 Merge pull request #3809 from deepseek-harness/worktree/release/dsh-0.1.5-alpha.1
release: [email protected]
2026-09-08 23:25:45 +08:00
fz 94ff82f57b Merge origin/master into feat/remove-str-replace-editor-from-minimal 2026-09-08 23:22:25 +08:00
imccyu 2faa751be9 release(dsh): 0.1.5-alpha.1 2026-09-08 23:06:34 +08:00
imccyu 96a66ba478 Merge pull request #3790 from deepseek-harness/worktree-ci-0908
fix(CI): update spec timeout and behavior
2026-09-08 23:04:59 +08:00
Tianyi Cui 7b1c989332 Merge pull request #3631 from deepseek-harness/release/session-log-v3
feat(session): 建立 V3 日志迁移协作基线与版本升级 cookbook
2026-09-08 23:03:39 +08:00
Tianyi Cui edcde102e9 Merge pull request #3808 from deepseek-harness/integrate/v3-master-e5f3-refresh
ci(session): sync latest master e5f3ccebbd with V3 content admission
2026-09-08 22:56:44 +08:00
Tianyi Cui 5ad38e5b94 Merge remote-tracking branch 'origin/master' into integrate/v3-master-refresh-345248 2026-09-08 22:44:51 +08:00
Tianyi Cui 6982a8f53c Merge remote-tracking branch 'origin/release/session-log-v3' into integrate/v3-master-refresh-345248 2026-09-08 22:44:49 +08:00
Tianyi Cui f7a4f0b95c Merge pull request #3805 from deepseek-harness/session-v3/content-admission-fix
fix(session): 补齐 V2→V3 所有内容入口的迁移审计
2026-09-08 22:41:35 +08:00
Tianyi Cui 5212603a4b fix(session): audit every historical content carrier before V3 migration 2026-09-08 22:38:04 +08:00
imccyu 2c21c7a03e ci: 1 2026-09-08 22:31:16 +08:00
imccyu 93a51e4dc2 Merge pull request #3804 from deepseek-harness/worktree/release-nativesystem-0.1.2
release(node-addon-system): 0.1.2
2026-09-08 22:25:46 +08:00
Tianyi Cui bb407e309d Merge master into session-log-v3 release
Merge 3ea52fc3e475a3e7c430812bde4209258416e57b into a0a61a8237f61344a01448a97954df603d8fff73. Retain the V2-to-V3 migration dependency alongside native system flock support, removing the replaced fs-ext dependency. Union the lockfile workspace importer entries; frozen installation validates the result without regeneration.

Preserve release publint async lane-signal cancellation, close ownership, and spawn-error regressions, satisfying the incoming CI budget intent. Keep canonical, prompt, preset, and latest migration regression behavior. Rename an arbitrary preset fixture value to custom-agent to avoid the inherited vendor-rescope false positive without changing test semantics.

Validation: frozen install; full build including Darwin addon; focused V3/persistence/prompt/publint and runtime tests; built migration, two-process lease, and loader smokes; native flock and package-matrix tests; touched dependency and CI owner tests; all hygiene leaves (vendor residue repaired and rechecked); doc-sync 34/34.
2026-09-08 22:21:18 +08:00
imccyu 9ddc35c26b release(node-addon-system): 0.1.2 2026-09-08 22:11:41 +08:00
Tianyi Cui 08f42810b9 Merge pull request #3781 from deepseek-harness/worktree/ci-reliability-master-20260908
test(ci): honor test budgets and clean up fixture processes
2026-09-08 22:08:50 +08:00
imccyu 9ea82286f2 Merge pull request #3708 from deepseek-harness/worktree-fixgyp
fix(native): use prebuilt flock over fs-ext
2026-09-08 22:08:03 +08:00
Tianyi Cui 11ec7cc52a Merge pull request #3799 from deepseek-harness/session-v3/migration-coverage
test(session): 补齐 V3 迁移组合回归并统一升级规格
2026-09-08 22:03:56 +08:00
Tianyi Cui 92d4410ada Merge pull request #3801 from deepseek-harness/worktree/ci-reliability-release-v3-20260908
test(web): align SSH replay with V3 release fixtures
2026-09-08 22:03:21 +08:00
Tianyi Cui ae4919634d test(web): align SSH replay with V3 release fixtures 2026-09-08 22:00:57 +08:00
Tianyi Cui cadd3ac05a Merge current V3 release into migration coverage audit 2026-09-08 21:51:09 +08:00
Tianyi Cui 5924d4c152 test(session): audit V3 migration composition and centralize upgrade spec 2026-09-08 21:51:06 +08:00
Tianyi Cui e72c9e4b13 Merge pull request #3797 from deepseek-harness/integrate/v3-master-refresh-345248
ci(session): merge latest master 345248f470 into V3 release
2026-09-08 21:45:12 +08:00
Tianyi Cui 36997d853c test(ci): inherit runner budgets in publint and LSP fixtures 2026-09-08 21:35:18 +08:00
Tianyi Cui 59ec2d3e94 test(ci): clean up fixture workers after test timeouts 2026-09-08 21:35:18 +08:00
Tianyi Cui 475f5648b3 test(ci): wait for owned completion in master tests 2026-09-08 21:35:18 +08:00
fz a0656e24b3 Merge pull request #3787 from deepseek-harness/feat/upgrade-codex-claude-runtimes
chore(subagent): upgrade Codex to 0.153.4 and Claude Code to 2.1.263
2026-09-08 21:24:33 +08:00
Tianyi Cui 0aa1ef0d1e Merge remote-tracking branch 'origin/release/session-log-v3' into integrate/v3-master-refresh-345248 2026-09-08 21:23:29 +08:00
Tianyi Cui 537102a052 Merge pull request #3636 from deepseek-harness/session-v3/canonical-envelopes
refactor(session): 在 V2→V3 中规范化事件 envelope
2026-09-08 21:21:09 +08:00
Tianyi Cui e11b2a5558 merge: refresh session-log-v3 from master 345248f470 2026-09-08 21:15:06 +08:00
Turtle f830cfd66a Merge remote-tracking branch 'origin/master' into turtle/weighted-approval
# Conflicts:
#	.github/review-ownership/README.md
2026-09-08 21:06:57 +08:00
Turtle c2a5540ddb fix(web): distinguish plugin configuration instances 2026-09-08 21:05:37 +08:00
Turtle 555c04bdfc fix(web): localize Chinese model copy 2026-09-08 21:05:31 +08:00
Turtle b4983e92df Merge pull request #3788 from deepseek-harness/turtle/fix-approved-review-rerequest
fix(ci): do not re-request approved reviewers
2026-09-08 20:55:17 +08:00
CreatixChu 03f439df9e Merge pull request #3673 from deepseek-harness/worktree/typert-forward-reexport
修复 Typert 对包内类型转发的误判
2026-09-08 20:49:23 +08:00
imccyu 97e7223d5f refactor(native): expose Landlock through its capability subpath 2026-09-08 20:49:10 +08:00
imccyu a2784a223e test(web): synchronize theme writes and focus assertions 2026-09-08 20:49:10 +08:00
imccyu 3a445b802d test(ci): stabilize storage and subprocess lifecycle checks 2026-09-08 20:49:10 +08:00
imccyu d927cbff99 feat(native): add prebuilt Node-API flock support 2026-09-08 20:49:10 +08:00
imccyu 7264906f99 refactor(native): rename package family to node-addon-system 2026-09-08 20:49:10 +08:00
imccyu 336ebb235e refactor(native): move Landlock workspace to native/system 2026-09-08 20:49:09 +08:00
_Kerman bcdaed38cc Merge pull request #3295 from deepseek-harness/xtr/explicit-agent-context
refactor(agent): make runtime identity explicit
2026-09-08 20:40:12 +08:00
Turtle 3c21d4c28c fix(client): name collapsed Settings trigger 2026-09-08 20:38:10 +08:00
Turtle c4855581c3 fix: preserve weighted approval review semantics 2026-09-08 20:19:29 +08:00
_Kerman 3a98d05a3d refactor(subagent): keep preset teardown outside identity changes 2026-09-08 20:19:19 +08:00
_Kerman d5e6b4e2b2 chore: remove unrelated PTY test repair from agent refactor 2026-09-08 20:19:09 +08:00
_Kerman 5045631a9a chore: remove unrelated sidebar test notes from agent refactor 2026-09-08 20:18:59 +08:00
Turtle fde15a8394 fix(ci): do not re-request approved reviewers 2026-09-08 20:14:34 +08:00
fz ace0c4619e chore(subagent): upgrade Codex and Claude Code runtimes 2026-09-08 20:12:38 +08:00
creatixchu 606b85cd58 refactor(typert): track forwarding visits without a delimiter 2026-09-08 20:04:09 +08:00
creatixchu b72919827a fix(typert): distinguish forwarding visits by export name 2026-09-08 19:56:33 +08:00
_Kerman 3e0e419bd2 Merge remote-tracking branch 'origin/master' into xtr/explicit-agent-context
# Conflicts:
#	apps/web/tests/queue-actions.e2e.ts
#	docs/subsystems/tools.i18n.yaml
#	docs/subsystems/tools.md
#	docs/subsystems/tools.zh.md
#	packages/extensions/tool-cordis/src/api-catalog.ts
#	packages/visualizer/tool-visualizer/README.i18n.yaml
#	packages/visualizer/tool-visualizer/README.md
#	packages/visualizer/tool-visualizer/README.zh.md
#	packages/visualizer/tool-visualizer/src/index.ts
#	packages/visualizer/tool-visualizer/tests/loader-composition.spec.ts
#	packages/visualizer/tool-visualizer/tests/model-surface.spec.ts
2026-09-08 19:54:59 +08:00
creatixchu 657482d1dd Merge remote-tracking branch 'origin/master' into worktree/typert-forward-reexport 2026-09-08 19:51:29 +08:00
fz 1f1537914f feat(minimal): align persistent bash output with the one-shot shell contract
The minimal compositions serve the same models that trained against a
one-shot `bash` tool; three surface differences remained visible to them.

- Every settled command now appends `[Command finished with exit code N]`,
  including exit code 0, instead of `[exit code: N]` only on failure. A
  timeout appends `[Command timed out or OOM]` after the partial output.
- Trailing newlines are all dropped before the status trailer rather than
  only the last one.
- The `bash` description in the `minimal` preset and the `sdk-minimal`
  bundle replaces the two fixed network lines with a single environment-
  dependent line; the pwsh description is unchanged.

Tests, READMEs, the web minimal-preset schema snapshot, and the packaged
Python minimal model-visible snapshot follow the new wording. The
standalone `persistent-tools` SDK replay fixture keeps its own copy of the
old description since it is a per-launch customization, not the profile.
2026-09-08 19:48:21 +08:00
_Kerman 6c87f030a3 fix(checks): preserve visualizer composition preset identifiers 2026-09-08 19:46:52 +08:00
_Kerman 36bd297293 fix(visualizer): keep model registration independent of agent identity 2026-09-08 19:46:51 +08:00
_Kerman 795a9cc226 test(web): sample queue alignment in one layout 2026-09-08 19:46:50 +08:00
_Kerman 55660e8a9e test(terminal): decouple descendant identity from startup 2026-09-08 19:46:12 +08:00
_Kerman 8fda2f620a Merge pull request #3671 from deepseek-harness/fix/session-prose-local-media-display
fix(web): display local media paths referenced in session prose
2026-09-08 19:43:21 +08:00
_Kerman 44008a79ca test(team): await mailbox acknowledgement flushes before teardown 2026-09-08 19:24:08 +08:00
Turtle 4550bb6e69 feat: enforce weighted pull request approvals 2026-09-08 19:08:08 +08:00
_Kerman 404097f813 test(subagent): reap SDK startup before readiness fixture cleanup 2026-09-08 18:59:11 +08:00
_Kerman 939e6907da test(shell): gate consuming PowerShell reads on parent acknowledgement 2026-09-08 18:59:04 +08:00
_Kerman 71e96aebae test(subagent): preserve ACP readiness budgets and teardown ownership 2026-09-08 18:56:50 +08:00
_Kerman b76a6d9963 fix(web): keep animated connection dots hidden on hover 2026-09-08 18:27:12 +08:00
_Kerman a433eec5e7 test(web): await editor credential state before snapshots 2026-09-08 18:24:32 +08:00
_Kerman c846beaf95 merge: sync reverted visualizer base from master 2026-09-08 18:20:48 +08:00
Tianyi Cui eda67c4a64 Merge pull request #3778 from deepseek-harness/revert-3337-feat/visualizer-host-plugin
Revert "feat(visualizer): add dormant Host capability"
2026-09-08 18:12:31 +08:00
Tianyi Cui 92b3b02622 Revert "feat(visualizer): add dormant Host capability" 2026-09-08 18:12:15 +08:00
_Kerman e186c218c0 test(web): release workflow gates after failed submissions 2026-09-08 18:04:56 +08:00
_Kerman 7599652627 merge: sync origin/master 2026-09-08 18:00:55 +08:00
_Kerman c26350c303 Merge remote-tracking branch 'origin/master' into xtr/explicit-agent-context 2026-09-08 18:00:35 +08:00
_Kerman 0f9d944f98 test(worker): account for the dockkit browser CSS entry 2026-09-08 17:57:44 +08:00
_Kerman 7627622c7a test(session): await durable cold projection cache writes 2026-09-08 17:56:00 +08:00
_Kerman 3ec2191246 test(web): await feedback submit replies before snapshots 2026-09-08 17:55:54 +08:00
_Kerman 19d87778a1 test(web): hold workflow children through live navigation checks 2026-09-08 17:55:48 +08:00
_Kerman e7bde97aa0 fix(tool-subagent): await agent-started preset cleanup 2026-09-08 17:55:17 +08:00
Ziya b4c69b0f64 Merge pull request #3337 from deepseek-harness/feat/visualizer-host-plugin
feat(visualizer): add dormant Host capability
2026-09-08 02:54:50 -07:00
_Kerman 180bdede47 fix(test): retain child turn diagnostics when log reads time out 2026-09-08 17:27:59 +08:00
_Kerman f7ef7103f3 test(subagent): await the image capability read before draining 2026-09-08 17:27:52 +08:00
_Kerman f7c9170b3b fix(web): dismiss tooltips when composer actions become disabled 2026-09-08 17:21:13 +08:00
_Kerman 314ccf08af Merge remote-tracking branch 'origin/master' into xtr/explicit-agent-context
# Conflicts:
#	packages/bundle/headless/tests/headless.spec.ts
#	packages/core/agent-loop/src/agent.ts
#	packages/subagent/subagent/tests/continuation.spec.ts
2026-09-08 17:12:51 +08:00
_Kerman ef8f166ccc test(ci): preserve the lane budget for invariant verifier children 2026-09-08 17:00:41 +08:00
Tianyi Cui 3fc9027a01 docs(session): refresh replay config source location 2026-09-08 16:56:53 +08:00
Tianyi Cui 53f42a781b test(session): close canonical envelope CI gaps 2026-09-08 16:56:53 +08:00
Tianyi Cui c4d8ee5ff2 test(session): canonicalize headless expected system replacements 2026-09-08 16:56:52 +08:00
Tianyi Cui 920e917988 fix(session): retain unknown required events for vocabulary validation 2026-09-08 16:56:52 +08:00
Tianyi Cui b7622e9f13 chore(session): refresh canonical API catalog after integration 2026-09-08 16:56:52 +08:00
Tianyi Cui 756b10fcfe test(session): cover composed canonical and PTC restoration 2026-09-08 16:56:52 +08:00
Tianyi Cui c28639587a test(session): keep historical fixtures outside current V3 encoding 2026-09-08 16:56:52 +08:00
Tianyi Cui 657e68186a fix(session): canonicalize V3 envelopes through adjacent migration 2026-09-08 16:56:52 +08:00
Tianyi Cui 7cbb052661 Merge pull request #3711 from deepseek-harness/integrate/v3-latest-master-for-canonical
ci(session): merge latest master into V3 for canonical review
2026-09-08 16:50:33 +08:00
ZiyaZhang 8e468c13a0 test(visualizer): remove redundant host web replay 2026-09-08 01:40:11 -07:00
ZiyaZhang 934d4b6501 refactor(visualizer): trust settled widget contents 2026-09-08 01:40:11 -07:00
ZiyaZhang e7dc1322a3 fix(visualizer): leave motion to presentation choice 2026-09-08 01:40:11 -07:00
ZiyaZhang b80e22ec2d docs(visualizer): require self-contained widget sources 2026-09-08 01:40:11 -07:00
ZiyaZhang b75b8ce49e chore(visualizer): align release metadata and snapshots 2026-09-08 01:40:11 -07:00
ZiyaZhang 7729e0ffee refactor(visualizer): simplify host contract 2026-09-08 01:40:11 -07:00
ZiyaZhang b17e90f78a fix(visualizer): validate fragment contracts precisely 2026-09-08 01:40:11 -07:00
ZiyaZhang f1f6ca1c77 feat(visualizer): add dormant Host capability 2026-09-08 01:40:11 -07:00
_Kerman 839a6fa995 test(web): await mutation replies before capturing settled UI 2026-09-08 16:35:16 +08:00
_Kerman 3aee29c657 test(lsp): hold queued source reads behind a response barrier 2026-09-08 16:35:01 +08:00
Turtle 189d96920c Merge pull request #3769 from deepseek-harness/turtle/auto-repair-issue-labels
fix(ci): auto-repair invalid Issue labels
2026-09-08 16:29:28 +08:00
Yichen Jiang da1bc2523a Merge branch 'master' into worktree/pi-ai-settings-recovery 2026-09-08 16:28:15 +08:00
Turtle 1d6b898ef6 Merge pull request #3764 from deepseek-harness/turtle/request-review-live-smoke
feat: rank review owners by changed LOC
2026-09-08 16:13:35 +08:00
_Kerman e33834f522 test(web): await session and responsive layout readiness 2026-09-08 16:12:14 +08:00
_Kerman 999b677e18 merge: sync origin/master 2026-09-08 16:08:28 +08:00
Yichen Jiang dd0fe585dd Merge remote-tracking branch 'origin/master' into worktree/pi-ai-settings-recovery 2026-09-08 16:07:59 +08:00
Turtle 614ff04842 fix: reconcile automated review requests 2026-09-08 16:05:09 +08:00
Turtle f8828b2ce1 fix(ci): auto-repair invalid Issue labels 2026-09-08 16:01:57 +08:00
Turtle f9ec0c28ed Merge pull request #3753 from deepseek-harness/turtle/package-summary-100-word-gate
docs: constrain package README summaries
2026-09-08 15:55:30 +08:00
Turtle f96fbba2db fix: cap counted review requests at one 2026-09-08 15:50:36 +08:00
Yichen Jiang c9a702a267 Merge remote-tracking branch 'origin/master' into worktree/pi-ai-settings-recovery 2026-09-08 15:42:48 +08:00
Yichen Jiang dad135dd41 Merge remote-tracking branch 'origin/master' into worktree/pi-ai-settings-recovery 2026-09-08 15:42:25 +08:00
Kaige-Gao babf22b4cf Merge pull request #3557 from deepseek-harness/slash-command-i18n
feat(web): localize slash command descriptions
2026-09-08 15:38:00 +08:00
_Kerman 8932b8670e test(ci): make Lefthook lock replacement deterministic 2026-09-08 15:36:59 +08:00
_Kerman a189104d81 docs: refresh session controller module dependencies 2026-09-08 15:36:55 +08:00
Turtle a04bffb7ed feat: rank review owners by changed LOC 2026-09-08 15:35:53 +08:00
Turtle f37eb3de47 test: exercise request-review routing 2026-09-08 15:16:08 +08:00
Turtle e19f62a553 merge: sync origin/master 2026-09-08 15:11:19 +08:00
Turtle 5e7c984663 Merge pull request #3752 from deepseek-harness/turtle/request-review-smoke
fix: reconcile automated review requests
2026-09-08 15:11:09 +08:00
Tianyi Cui be9d401c33 test(web): await action acknowledgements before following controls 2026-09-08 15:00:53 +08:00
Turtle 7d8546b4db fix: cap reviewers per pull request 2026-09-08 14:37:54 +08:00
Tianyi Cui 6c0e258b27 test(web): await observed browser settlement in replay scenarios 2026-09-08 14:35:11 +08:00
Turtle 0b43d89d5f fix: cap review owners per module 2026-09-08 14:31:23 +08:00
_Kerman cb3df20cf3 docs(api): remove obsolete media path restrictions 2026-09-08 14:25:50 +08:00
_Kerman 3f1f7da7c3 Merge origin/master into fix/session-prose-local-media-display 2026-09-08 14:25:21 +08:00
Turtle fe834c7f92 fix: reconcile automated review requests 2026-09-08 14:15:41 +08:00
lsdsjy 0707f4af3e Merge pull request #3700 from deepseek-harness/fix/open-in-app-ssh
fix(open-in-app): hide workspace app actions over SSH
2026-09-08 14:11:41 +08:00
Tianyi Cui d058899194 test(snapshot): isolate child-turn diagnostic timeout from harvesting 2026-09-08 13:59:47 +08:00
Turtle f1c1ff5a08 docs: constrain package README summaries 2026-09-08 13:52:40 +08:00
fz 61cd1a3f91 Merge origin/master into feat/remove-str-replace-editor-from-minimal 2026-09-08 13:51:47 +08:00
Turtle c41b2895eb test: exercise request-review routing 2026-09-08 13:51:31 +08:00
Turtle 06c01ce2e8 Merge pull request #3684 from deepseek-harness/turtle/custom-review-ownership
chore: automate changed-file review ownership
2026-09-08 13:47:15 +08:00
Tianyi Cui 1c06f1d3ac test(snapshot): declare spill command fixture plugin types 2026-09-08 13:40:49 +08:00
Tianyi Cui 154b2a3cd6 test(snapshot): reconcile V3 fixtures with isolated master replay 2026-09-08 13:36:12 +08:00
Yichen Jiang da313e4fdc fix(llm-pi-ai): preserve actionable model diagnostics 2026-09-08 13:35:09 +08:00
Kaige-Gao aed565f382 Merge master into slash-command-i18n 2026-09-08 13:32:55 +08:00
Turtle f121b09fb1 Merge pull request #3680 from deepseek-harness/turtle/strip-think-summary-bold-markers
fix(web): strip bold markers from think summaries
2026-09-08 13:30:04 +08:00
Tianyi Cui 2b64ea5f1a test(web): align V3 seeded stats with absent decode timing 2026-09-08 13:20:43 +08:00
Tianyi Cui 96fa1dfac8 Merge pinned master 84bde6c7 into V3 readiness repair 2026-09-08 13:16:35 +08:00
Huanqi Cao a39d309187 fix(directory-picker-native): foreground-activate the Win32 folder dialog via a synthesized Alt press 2026-09-08 13:10:03 +08:00
Tianyi Cui 0bb083d898 Merge pull request #3646 from deepseek-harness/fix/pr-ci-reliability-20260906
fix(ci): 隔离临时存储并稳定测试夹具
2026-09-08 13:06:58 +08:00
Xu Hanxiang 66ac8cc094 Merge pull request #3485 from deepseek-harness/issue-1424-goal-resume-activation
fix(goal): keep manual pause authoritative and show activation
2026-09-08 13:02:47 +08:00
Yudong Han 612afd1eaa Merge pull request #3726 from deepseek-harness/skills/playwright-video-gif
feat(skills): record browser GIFs with Playwright Videos
2026-09-08 13:02:11 +08:00
Kaige-Gao ea60e1c8a7 chore(web): remove command description gate 2026-09-08 13:01:29 +08:00
Turtle b08310ac1d fix(web): strip bold markers from think summaries 2026-09-08 12:56:21 +08:00
_Kerman 40c5ef4fc3 refactor(api): reuse attachment limits for file responses 2026-09-08 12:55:57 +08:00
mektpoy 0dc6ce26d7 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation 2026-09-08 12:48:51 +08:00
Turtle dfae5f0351 Merge pull request #3686 from deepseek-harness/turtle/from-default-profile
feat(cli): create custom profiles from shipped templates
2026-09-08 12:45:58 +08:00
lsdsjy 5b8c8b781f test(open-in-app): scope SSH snapshot to the session header 2026-09-08 12:43:55 +08:00
_Kerman 88ab8e9133 fix(ui): show authored text when markdown images fail 2026-09-08 12:06:43 +08:00
_Kerman b52966922a fix(api): serve bounded files through the filesystem provider 2026-09-08 12:06:11 +08:00
Yichen Jiang 8dc30d270c test(llm-pi-ai): cover recovery diagnostics and document repair limits 2026-09-08 12:04:18 +08:00
yudshj 614cffda8f docs(skills): preserve browser-control workflow preference 2026-09-08 11:52:37 +08:00
yudshj e57e7dc57f feat(skills): record browser GIFs with Playwright video 2026-09-08 11:52:37 +08:00
Turtle 7263193655 Merge pull request #3517 from deepseek-harness/turtle/issue-2029-root-marker-stat-error
fix(agent-instructions): surface root marker stat errors
2026-09-08 11:49:13 +08:00
Turtle 371dce2469 Merge pull request #3523 from deepseek-harness/turtle/issue-2421-reject-empty-prompt
fix(session-controller): reject empty prompts
2026-09-08 11:48:49 +08:00
Turtle e970408acd chore: automate static review ownership 2026-09-08 11:37:58 +08:00
lsdsjy a8d960ecb6 Merge master into fix/open-in-app-ssh 2026-09-08 11:37:46 +08:00
Yudong Han c153123bdd Merge pull request #3720 from deepseek-harness/docs/windows-wsl
docs: explain Windows and WSL development environments
2026-09-08 11:37:44 +08:00
lsdsjy 28d478a80d Merge pull request #3681 from deepseek-harness/fix/busy-send-button-follows-setting
fix(web): make the running Send button follow the busy-Enter setting
2026-09-08 11:35:25 +08:00
Yifffan 012475f7ae Merge pull request #3699 from deepseek-harness/fix/input-placeholder-stat-ui-polish
fix(web): composer polish — menu layering, placeholders, spacing, and two-pill session stats
2026-09-08 05:35:20 +02:00
fz ad05ed6ad8 docs(minimal): describe current editor availability 2026-09-08 11:33:24 +08:00
lsdsjy 7f47954cad fix(open-in-app,directory-picker): share inherited SSH detection 2026-09-08 11:32:36 +08:00
mektpoy 514f92ba53 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation
# Conflicts:
#	packages/goal/goal/tests/projection.spec.ts
2026-09-08 11:23:08 +08:00
Yichen Jiang 5bc792f629 refactor(llm): keep diagnostics in configurable provider metadata 2026-09-08 10:55:53 +08:00
Turtle a56619d9f7 fix(session): reject empty queue edits 2026-09-08 10:48:32 +08:00
Turtle 40b20be9f5 docs(context): record root marker failure policy 2026-09-08 10:48:15 +08:00
Turtle 99a49712e6 test(agent-instructions): model provider absence in resolve 2026-09-08 10:48:15 +08:00
Turtle 08edb3cf10 fix(agent-instructions): surface root marker stat errors 2026-09-08 10:48:15 +08:00
Turtle ae19d9383b fix(session-controller): reject empty prompts 2026-09-08 10:47:36 +08:00
Yichen Jiang a12d30df2a refactor(llm-pi-ai): reuse settings validation for startup recovery 2026-09-08 10:47:05 +08:00
Yichen Jiang 642b538fe0 Merge remote-tracking branch 'origin/master' into worktree/pi-ai-settings-recovery 2026-09-08 10:34:14 +08:00
Yichen Jiang fe03b0686d fix(llm-pi-ai): keep catalog-invalid settings repairable 2026-09-08 10:28:45 +08:00
HYD@OVERTON 76235ecfb7 docs: align Chinese WSL use cases with English 2026-09-08 09:36:19 +08:00
Yif 0ffbd65843 test(web): follow hero headline nesting and Tool definitions copy in e2e 2026-09-08 01:42:35 +08:00
Yifffan 7005d500b4 Merge branch 'master' into fix/input-placeholder-stat-ui-polish 2026-09-07 19:18:33 +02:00
Yif bbd899d478 fix(client): count IconGaugeOutline16 in the icon-set pin; keep the hero headline text addressable
The icon-set spec still pinned 74 exports after IconGaugeOutline16
landed (a hand-drawn product glyph — the set is now eight of those).
Moving the preview badge inside the hero title group had merged the
headline into one text node with the badge, which broke exact text
lookup (hmr-live e2e); the headline gets its own span again.
2026-09-08 01:16:56 +08:00
HYD@OVERTON a5a9746277 docs: explain Windows and WSL development environments 2026-09-08 00:57:15 +08:00
Tianyi Cui c389f96bf3 Merge pull request #3713 from deepseek-harness/fix/workspace-browser-race
test(web): 等待种子 Session 归属投影后再选择
2026-09-08 00:46:19 +08:00
Yif 256afa848c Merge remote-tracking branch 'origin/master' into fix/input-placeholder-stat-ui-polish
# Conflicts:
#	packages/client/ui-chat/src/client/locale.ts
#	packages/client/ui-chat/tests/gate-branch-tails.client.spec.tsx
2026-09-08 00:45:29 +08:00
Tianyi Cui eec9c3b694 test(snapshot): avoid duplicate projection registry setup 2026-09-08 00:37:58 +08:00
Yif 2c45dfe71e fix(client): address review — pill accessible names, static untimed pill, exclusive stat dialogs
StatsPills buttons carry explicit aria-labels separating segments with
' · '; a log with no timed figure renders the counts pill as a static
reading instead of a button opening an empty dialog; the pills row owns
one exclusive open slot so sibling dialogs never stack. ContextMeter
restores the '~' approximation prefix (usedTokens prefers heuristic
projectedTokens). ModelSelect's jscpd:ignore now names the real gap
(useAnchoredPosition places from the left edge only). The pills Agent
Note's stale facts (locale keys, context occupancy, golden ownership)
are rewritten in place, en+zh. plan-review.e2e.ts parks the pointer
after Approve so the ContextMeter tooltip cannot leak into the aria
captures; affected goldens refreshed.
2026-09-08 00:35:04 +08:00
Tianyi Cui 47434e8554 fix(session-format): align v3 migration with merged release version 2026-09-08 00:32:02 +08:00
Tianyi Cui e73906d06f test(web): await seeded workspace membership before selection 2026-09-08 00:28:25 +08:00
Tianyi Cui ccb861d0e2 Merge branch 'master' into fix/pr-ci-reliability-20260906 2026-09-08 00:23:08 +08:00
Tianyi Cui 5b039c1796 Merge master 822041865d into Session V3 release 2026-09-08 00:17:14 +08:00
Tianyi Cui 3ef3bc17c5 Merge pull request #3483 from deepseek-harness/feat/system-prompt-in-history
feat(agent-loop): append a changed system prompt in history on capable routes
2026-09-08 00:06:45 +08:00
imccyu de01754f1e Merge pull request #3588 from deepseek-harness/worktree-sidebar
feat(client): right Sidebar arch — docking surface, tab types, resource model, workspace files
2026-09-07 23:47:39 +08:00
Tianyi Cui 4eebc70df2 test(agent-loop): account for route switch notice during prompt admission
The plain-to-capable transition emits the model-selection notice inherited from master. Preserve the exact in-history system ordering and assert both the admitted user input and the single durable notice instead of expecting the obsolete five-message request. Reproduces the identical Linux and Windows CI failure; all 57 adjacent admission, projection, reconstruction and selection tests pass.
2026-09-07 23:29:49 +08:00
fz 707d0e7e52 Merge origin/master into feat/remove-str-replace-editor-from-minimal 2026-09-07 23:25:03 +08:00
imccyu 08cfbd8970 chore(api): remove stale session controller file dependencies 2026-09-07 23:13:10 +08:00
imccyu 4a60189a63 fix(layout): prepare destination widths before fullscreen retreat 2026-09-07 23:00:56 +08:00
fz b92cc94122 test(minimal): cover documented editor opt-in 2026-09-07 22:56:48 +08:00
imccyu 77690644b5 fix(sidebar): show full file paths and refine split and fullscreen controls 2026-09-07 22:37:45 +08:00
imccyu 755e3ceca7 test: cover file subscription and tab lifecycle edge cases 2026-09-07 22:17:56 +08:00
Yif e939a482e9 Merge origin/master: reconcile placeholder rewording with steer-all and note archival
Master archived three Agent Notes this branch had fact-updated (archived
copies restored to their frozen master content; the pills note now links
the archived path), extended the steer-all placeholder to continuable
children (spec and subagent e2e take master's behavior with this branch's
reworded copy), and dropped the session-sharing sentence from feedback
acks (goldens re-refreshed with the new placeholder).
2026-09-07 22:01:06 +08:00
lsdsjy 5e19460c28 docs(notes): sync the continuable-subagent Send clause and tighten the label-state enumerations
The 2026-08-06 continuable-subagent interrupt note said the child's Send
always queued; it now names the busy-Enter delivery and cross-links the
busy Send button note, which links back. The new note's and bench's
plain-Send enumerations now exclude the ordinary running empty/blocked
draft, whose seat is Stop.
2026-09-07 21:43:55 +08:00
imccyu 4fef2786a9 chore: regenerate catalogs, dependency lock, and translation hashes 2026-09-07 21:29:49 +08:00
imccyu fe5aee7e71 test(web): cover Sidebar interactions and refresh recorded UI expectations 2026-09-07 21:29:42 +08:00
imccyu bd4199f48c test: cover filesystem resources and Sidebar domain behavior 2026-09-07 21:29:42 +08:00
imccyu 508831624f chore(web): assemble Sidebar domains and register workspace packages 2026-09-07 21:29:41 +08:00
imccyu a7c7e99652 feat(deliverables): open produced files through Sidebar resources 2026-09-07 21:29:41 +08:00
imccyu 108a7478c9 refactor(tool-ui): route file navigation and remove ToolDetails 2026-09-07 21:29:41 +08:00
imccyu 7e017046ca refactor(chat): open file resources in the Sidebar and remove Details 2026-09-07 21:29:41 +08:00
imccyu d10af0654f feat(textpreview): add paged file tabs and retained reader state 2026-09-07 21:29:41 +08:00
imccyu b24ebc8cce feat(sidebar-files): add lazy workspace file tree tabs 2026-09-07 21:29:40 +08:00
imccyu b67e0a838c feat(sidebar): add tab navigation, injected information, and fullscreen shell 2026-09-07 21:29:40 +08:00
imccyu 4909550782 feat(conversation): provide the session header corner slot 2026-09-07 21:29:40 +08:00
imccyu 9241e10a47 feat(layout): add responsive right column and width concessions 2026-09-07 21:29:40 +08:00
imccyu 9e7c570094 feat(dockkit): add reversible docking engine and pointer interactions 2026-09-07 21:29:40 +08:00
imccyu 9f2b07cea8 feat(remotes): expose workspace file operations to the Client 2026-09-07 21:29:39 +08:00
imccyu 4ce4f0bac4 feat(workspace-files): add dual-face file API and Host-resolved resources 2026-09-07 21:29:39 +08:00
imccyu 3a85ac6d81 feat(resources): add Client resource registry and retained subscriptions 2026-09-07 21:29:39 +08:00
imccyu 4a4b86d9b0 feat(workspace-path): define Session and absolute file resource addresses 2026-09-07 21:29:39 +08:00
imccyu 4429763445 feat(fs-e2b): implement cancellable sandbox byte windows 2026-09-07 21:29:39 +08:00
imccyu bc2174e3aa feat(fs-local): implement bounded local byte windows 2026-09-07 21:29:38 +08:00
imccyu f7b6a13321 feat(fs): define bounded byte-range reads 2026-09-07 21:29:38 +08:00
_Kerman b0a7d2ce3b Merge pull request #2672 from deepseek-harness/xtr/durable-inbox-recovery
refactor(agent): keep projection-backed Inbox loop-internal
2026-09-07 21:24:32 +08:00
Yif ad38d63626 fix(client): ellipsize the composer placeholder — one docked line, two hero lines
A long placeholder wrapped and clipped against the docked composer's 36px
floor; the hero's 52px floor fits exactly two lines.
2026-09-07 21:18:22 +08:00
lsdsjy 4a89178785 fix(open-in-app): hide workspace app actions over SSH 2026-09-07 21:14:19 +08:00
_Kerman dbb9db5f34 docs(session-controller): refresh translation pairing record 2026-09-07 21:05:29 +08:00
Yif 3997f36999 feat(client): replace the stats strip with two icon pills and click-open stat dialogs
The A/B winner over the single-line StatsLine: a gauge pill (counts + TPS,
opening the session-stats dialog) and a database pill (billed total +
cache-hit share, opening the exact token-usage dialog), sharing a new
stat-dialog module. StatsLine and its dead locale keys are deleted, the
gauge icon is optically centered, and the composer keeps its 4px clearance
through the data-composer-stats contract. Agent Note added; stale
StatsLine references across implemented notes updated in place.
2026-09-07 20:59:19 +08:00
lsdsjy 2cb684c754 test(web): pin the failed-upload Send label and document the bench mirror scope 2026-09-07 20:56:34 +08:00
Turtle 267d2f8eb9 Merge remote-tracking branch 'origin/master' into turtle/from-default-profile
# Conflicts:
#	apps/cli/README.i18n.yaml
#	apps/cli/README.md
#	apps/cli/README.zh.md
#	packages/boot/app-boot/README.i18n.yaml
#	packages/boot/app-boot/README.md
#	packages/boot/app-boot/README.zh.md
2026-09-07 20:53:53 +08:00
_Kerman 68643a07f9 docs(session-controller): unwrap zh readme paragraph 2026-09-07 20:52:09 +08:00
_Kerman 753effe602 fix(bench): rely on testkit session projection mounting
mountAgentLoopTestDependencies registers SessionProjectionRegistry, so benchmark workers must not mount it again before resuming agents.
2026-09-07 20:52:06 +08:00
Turtle 2555474a7d refactor(cli): simplify profile option forwarding 2026-09-07 20:47:47 +08:00
Turtle 7a7b7d5a53 fix(cli): make profile template creation exclusive 2026-09-07 20:46:40 +08:00
07akioni ba05b7d49d Merge pull request #3413 from deepseek-harness/feat/electron
feat(desktop): add managed Electron distribution
2026-09-07 20:46:31 +08:00
lsdsjy 8935c3d725 fix(web): keep plain Send while a file upload is pending
Review follow-up: the mode label predicate now includes !uploadsPending,
so a running draft whose file is still uploading (or failed) keeps the
plain Send label on its disabled button, matching the documented
'enabled button' condition. Test pins pending vs ready upload states;
the Agent Note and README pair name the upload gate.
2026-09-07 20:43:12 +08:00
_Kerman 0348599f04 Merge remote-tracking branch 'origin/master' into dshw/pr-deepseek-harness-deepseek-harness-2672
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	packages/acp/acp/tests/harness.ts
#	packages/api/session-controller/README.i18n.yaml
#	packages/api/session-controller/README.md
#	packages/api/session-controller/README.zh.md
#	packages/api/session-controller/tests/commands-queue-attachment.host.spec.ts
#	packages/context/agent-instructions/tests/agent-instructions.e2e.ts
#	packages/fs/tool-fs/tests/harness.ts
#	packages/preset/agent-presets/tests/invariant.spec.ts
#	packages/preset/agent-presets/tests/mount.spec.ts
#	packages/preset/agent-presets/tests/remote.spec.ts
#	packages/test-support/agent-loop-testkit/package.json
2026-09-07 20:22:24 +08:00
Turtle dd25e1e6b3 feat(cli): create profiles from shipped templates 2026-09-07 19:58:41 +08:00
fz 110db78707 Merge origin/master into feat/remove-str-replace-editor-from-minimal 2026-09-07 19:53:33 +08:00
07akioni 016af7c67b Merge release 0.1.3-alpha.2 and reconcile desktop composition 2026-09-07 19:49:36 +08:00
07akioni 8d0d729091 Merge master native containment updates into feat/electron 2026-09-07 19:45:55 +08:00
Yichen Jiang 82a5fd61a7 Merge pull request #3685 from deepseek-harness/worktree/release-dsh-0.1.3-alpha.2
release: [email protected]
2026-09-07 19:45:35 +08:00
Tianyi Cui 053bf8aaad Merge branch 'feat/system-prompt-surface-node' into feat/system-prompt-in-history 2026-09-07 19:45:32 +08:00
Tianyi Cui 34832ddb2e Merge published V3 repair root into system-message branch
Include the root merge from #3678 without altering the previously validated implementation tree. Preserve structural V3 system messages and the current native-runtime recordings.
2026-09-07 19:45:32 +08:00
Tianyi Cui 98c043ab0f Merge branch 'master' into fix/pr-ci-reliability-20260906 2026-09-07 19:44:51 +08:00
fz 5c98a81a50 test(benchmarks): explicitly compose the SDK file editor 2026-09-07 19:43:49 +08:00
fz d3281d0218 docs(minimal): explain editor opt-in configuration 2026-09-07 19:33:48 +08:00
lsdsjy 2f630626b8 fix(web): name the running Send mode only for a plain message draft
Review follow-up. The mode label predicate lacked `!empty`, so a running
continuable child with an empty draft showed a disabled "Queue message";
and a claimed slash command or a `/` line headed for adjudication executes
a command rather than delivering a message, so naming Queue/Steer there
misdescribed the click. The label now names the mode only when the click
would deliver a plain message: running, steer-capable, enabled, non-empty,
unclaimed, and not a `/` line. Tests pin the empty-draft child, the slash
line, and the claimed command; the Agent Note, README pair, and
ComposerKeyboard.submit JSDoc state the exact predicate.
2026-09-07 19:33:20 +08:00
fz 71a291cbc4 Merge origin/master into feat/remove-str-replace-editor-from-minimal 2026-09-07 19:28:12 +08:00
Yichen Jiang e379fa8bdd release(dsh): 0.1.3-alpha.2 2026-09-07 19:27:06 +08:00
Tianyi Cui 4bcabe6da4 test: pair spill cleanup roots with concurrent run results 2026-09-07 19:20:39 +08:00
Tianyi Cui 23b48b7577 Merge pull request #3678 from deepseek-harness/fix/v3-benchmark-reliability
fix(ci): integrate latest master and repair V3 performance/readiness checks
2026-09-07 19:14:22 +08:00
lsdsjy 9a5ed6fb60 fix(web): make the running Send button follow the busy-Enter setting
The ui-conversation.busyEnter setting selected Queue or Steer for plain
Enter only; the running draft's Send button always submitted through the
public InputActions.submit() face, which is fixed to Queue, while labeled
"Send message". A user who chose Steer got Steer from Enter and Queue
from the button beside the same draft with nothing explaining why.

InputBar now resolves the primary click through the same `enter` gesture
and steer-availability predicate as the keyboard path (ordinary Sessions
and continuable children) and submits via ComposerKeyboard.submit(mode).
While that delivery is available the button's tooltip and accessible name
state it ("Queue message" / "Steer message"; 排队发送 / 插话发送), so the
mode is never hidden; idle sessions, one-shot children, and locked
composers keep the plain Send label. The composer bar inject face
publishes the live preference as hooks.busyEnter instead of a resolver
closure, and resolveSubmitMode is a pure function taking the preference
explicitly, so label and delivery derive from one value in one render and
the label follows live Settings changes. The Settings row is retitled
"Send behavior while busy" with a description that names both Enter and
the button; the busyEnter field, its default, and the Host schema are
unchanged.

Tests pin both preferences on the running button for ordinary sessions
and continuable children, the live relabel, the idle Queue path, and the
pure resolver; the settings-chrome ARIA goldens and the live-interactions
running-draft and queue-actions failed goldens carry the new copy. A new
Agent Note owns the decision and reverses the pointer-ignores-preference
clause of the archived 2026-08-20 running-draft note.
2026-09-07 19:14:21 +08:00
Tianyi Cui f3c98e4539 test(web): settle queue tooltip and select exact seeded session 2026-09-07 19:03:25 +08:00
Tianyi Cui 89bafdb945 Merge native subprocess containment into in-history updates
Preserve both sdk-minimal-in-history and native runner smoke scenarios. Record the current Cordis inspection through the actual upper headless owner while retaining upstream V2 bytes and strict prompt admission semantics.
2026-09-07 18:49:19 +08:00
Tianyi Cui 90307dd7d6 Merge native containment master into V3 system-message layer
Preserve strict live-smoke challenges and structural system messages while adopting the native subprocess runtime. Regenerate only the current Cordis inspection recording from the upstream V2 source to retain its no-ordinary-PID coverage; predecessor bytes match master.
2026-09-07 18:46:59 +08:00
Tianyi Cui 1dc95884a1 Merge frozen native containment master f6132bd into V3 repair
Preserve the root V3 current-writer, PTC dispatch identity, and reliability fixes while incorporating provider-owned native ranges and the private packaged runner bootstrap.

Refresh only the current cordis-inspect-jsdoc V3 owner through the built headless profile so upstream subprocess API coverage is exercised. Preserve incoming master V2 bytes and all other fixtures and benchmark thresholds.
2026-09-07 18:42:02 +08:00
pku-xht c7e29f4b68 Merge pull request #2825 from deepseek-harness/codex/subprocess-native-containment
fix(subprocess): contain escaped descendants with native owners
2026-09-07 18:30:37 +08:00
Tianyi Cui b000ca44f6 Merge branch 'feat/system-prompt-surface-node' into feat/system-prompt-in-history 2026-09-07 18:20:03 +08:00
Tianyi Cui 3ae70558e7 test: make publint assertion callbacks explicitly void 2026-09-07 18:19:45 +08:00
Tianyi Cui f4e10a61b1 test: make publint assertion callbacks explicitly void 2026-09-07 18:19:44 +08:00
Tianyi Cui 0deeec02c4 Merge current master and CI readiness repairs into in-history updates
Preserve prepared-route admission and V3 prompt semantics while adopting latest master. Regenerate the new model-switch recording at its actual upper-layer title ordering, retain the V2 predecessor, and keep queued-image and publint lifetime assertions strict.
2026-09-07 18:18:08 +08:00
Tianyi Cui 153d54a2f2 ci: retain shared persistent npm cache 2026-09-07 18:14:33 +08:00
Tianyi Cui d792a694ef test: bind publint subprocess lifetime to lane cancellation 2026-09-07 18:14:17 +08:00
Tianyi Cui 710823fd24 Merge current master and benchmark repairs into V3 system messages
Adopt current model-switch notices, lazy observation, and open-in-app integration while preserving structural V3 admission. Regenerate only the new model-switch owner’s native V3 recording, prompt-count manifest and expected delimiter; keep the master V2 predecessor byte-exact.
2026-09-07 18:14:14 +08:00
Tianyi Cui f91f33094a test: bind publint subprocess lifetime to lane cancellation 2026-09-07 18:13:07 +08:00
Tianyi Cui c4ad45378d test(web): await admitted queue image before snapshot 2026-09-07 18:07:13 +08:00
Tianyi Cui 07b9d2e780 test(web): await admitted queue image before snapshot 2026-09-07 18:06:55 +08:00
Tianyi Cui 89f4acbd74 Merge frozen master 777d73f into V3 benchmark repair
Bring model-switch notices, lazy observations, and open-in-app into the root V3 integration without importing the child structural header changes. Preserve V3 migration, PTC, and all predecessor fixtures.

Refresh only the model-switch-notice owner through dsh --profile headless to harvest native current-writer session.v3.jsonl. Keep the master session.v2.jsonl byte-exact; existing header pin and versioned writer helpers require no changes.
2026-09-07 18:04:19 +08:00
_Kerman 67c5136c7e fix(api): refuse non-regular files before open and bound full streams
- A media-named FIFO or device node is refused before the open would
  block on it (pre-open isFile check); POSIX FIFO regression test added.
- The full-body stream is bounded to the stat'ed size so concurrent
  appends cannot exceed the declared Content-Length.
- Error responses carry no body for HEAD requests.
- Docs no longer overclaim the replacement race: the stat-identity
  comparison narrows (does not fully close) the replacement window, and
  the earlier realpath-to-stat window is acknowledged. Pairs re-recorded.
2026-09-07 18:04:07 +08:00
pku-xht 0f83a2cdc0 Merge remote-tracking branch 'origin/master' into codex/subprocess-native-containment 2026-09-07 18:02:44 +08:00
_Kerman ba4a536030 fix(api): honor only bytes ranges and ignore malformed or multi-range headers
range-parser never validates the range unit, so /api/file now parses only
headers that start with the bytes unit: unsatisfiable ranges answer 416,
while malformed, unknown-unit, and multi-range headers are ignored for a
full 200 body per RFC 9110. The filesystem-root workspace case stays
POSIX-only in tests (a Windows drive-root spelling cannot be constructed
portably); containment already treats any separator-terminated root the
same. Docs (README pair, Agent Note pair) re-recorded.
2026-09-07 18:01:29 +08:00
creatixchu 5acf3cd09b fix(typert): try explicit forwarding edges before star edges and reuse the resolution cache
Review follow-up. A forwarding module's explicit re-exports are tried
before its star re-exports and an entered module is skipped on later
edges, so a star edge that loops back no longer hides the explicit
re-export beside it. Import resolution outside the checker goes through
the face's shared compiler host and module-resolution cache, and an
import naming an unregistered package fails the public-export check
instead of throwing a TypeError. Tests pin the looping star, the
relative-only cycle exit, namespace re-exports, and re-exported
namespace imports.
2026-09-07 18:00:39 +08:00
ihsiang 9292dd8a2d feat(workspace): open the workspace in local apps from the web UI (#3409)
Add the first-party open-in-app host and client packages with a localized Open In menu in the Web Session header.

Resolve installed applications on macOS, Windows, and Linux, launch workspace directories through platform-specific adapters, and remember the selected application.

Closes #1500.

Co-authored-by: ihsiang <[email protected]>
2026-09-07 17:58:11 +08:00
pku-xht e9f1b6c53e Merge remote-tracking branch 'origin/master' into codex/subprocess-native-containment
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.md
#	.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.zh.md
#	.agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.i18n.yaml
#	.agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.i18n.yaml
#	.agents/notes/implemented/architecture/2026-09-06-embedded-stream-record-readers.i18n.yaml
#	.agents/notes/implemented/bug-fix/2026-09-03-normalized-unread-fs-tool-diagnostic.i18n.yaml
#	.agents/notes/implemented/bug-fix/2026-09-06-windows-python-console-spawn-wait.i18n.yaml
#	.agents/notes/implemented/feature/2026-08-26-generic-file-upload.i18n.yaml
#	.agents/notes/implemented/feature/2026-09-07-model-switch-notice.i18n.yaml
#	.agents/notes/implemented/process/2026-09-03-semantic-issue-templates-and-policy.i18n.yaml
#	packages/shell/bash-local/tests/executor.spec.ts
#	packages/subprocess/subprocess-local/README.i18n.yaml
#	packages/subprocess/subprocess-local/README.md
#	packages/subprocess/subprocess-local/README.zh.md
#	packages/subprocess/subprocess-local/src/spawn.ts
#	packages/subprocess/subprocess-local/tests/spawn.spec.ts
#	packages/subprocess/win32-process/package.json
2026-09-07 17:43:45 +08:00
Dudu-0223 9d93c57053 Merge pull request #3672 from deepseek-harness/perf/session-observation-lazy-events
perf(session-query): materialize live observation events on first read
2026-09-07 17:40:45 +08:00
Tianyi Cui 4ee338532a ci: retain shared pnpm store across runner instances 2026-09-07 17:28:12 +08:00
_Kerman 8b8a051c7a fix(api): address /api/file review findings
- HEAD never opens a file stream; GET streams are destroyed on client
  abort and are never opened for already-aborted requests.
- Validation and reading bind to the same opened file: pre-open and
  opened stat identities are compared, so replacement/re-linking races
  are refused (dev/ino check, read through the FileHandle).
- Workspace containment compares path components, so a filesystem-root
  workspace serves files instead of doubling the separator.
- Multi-range headers are ignored for a full 200 body instead of a
  mislabeled single-segment 206; single-range behavior unchanged.
- Tests now cover the reviewed edges (empty path, multi-range, root
  workspace, HEAD+range, mid/early abort, unreadable file, explicit
  unregister-on-dispose, private outside-target directories); module
  coverage is back at 100/100/100/100.
- Agent Note bilingual facts and the ui-primitives/session-controller
  README pairs are synced to the shipped behavior (pairs re-recorded).
2026-09-07 17:27:57 +08:00
_Kerman 1780d0d355 Merge remote-tracking branch 'origin/master' into xtr/explicit-agent-context 2026-09-07 17:25:46 +08:00
Tianyi Cui 2c2092e2c6 Merge branch 'feat/system-prompt-surface-node' into feat/system-prompt-in-history 2026-09-07 17:21:56 +08:00
Tianyi Cui dbd28a8071 fix(benchmarks): keep composer focus during streamed input 2026-09-07 17:21:56 +08:00
Tianyi Cui 9baebd8f3f fix(benchmarks): keep composer focus during streamed input 2026-09-07 17:21:55 +08:00
Tianyi Cui 09e56a4b4a Merge branch 'feat/system-prompt-surface-node' into feat/system-prompt-in-history 2026-09-07 17:18:19 +08:00
Tianyi Cui 201987b374 perf(llm): scan file content without per-array callbacks 2026-09-07 17:18:18 +08:00
Tianyi Cui a7661e2672 perf(llm): scan file content without per-array callbacks 2026-09-07 17:18:18 +08:00
Dudu-0223 5b91dbfba0 perf(session-query): materialize live observation events on first read 2026-09-07 17:15:35 +08:00
creatixchu 3599ff5119 Merge remote-tracking branch 'origin/master' into worktree/typert-forward-reexport 2026-09-07 17:15:32 +08:00
Tianyi Cui d718965f00 Merge branch 'feat/system-prompt-surface-node' into feat/system-prompt-in-history 2026-09-07 16:58:53 +08:00
Tianyi Cui f277ec0e06 Merge published V3 root after master integration approval
Include the root merge ancestry from #3669. Preserve the already validated system-message child recording rather than restoring the root’s header-system representation. The resulting tree is unchanged from the preceding representation head.
2026-09-07 16:58:52 +08:00
CreatixChu cb602a0df5 Merge pull request #3507 from deepseek-harness/worktree/3410-model-switch-notice
feat(agent): announce model switches
2026-09-07 16:55:45 +08:00
_Kerman ead14339bc refactor(ui-chat): fold local-path media mapping into AssistantMarkdown
A single-consumer pure helper does not earn its own file: the mapping
now lives beside the prose vocabulary it serves (same shape as the
deliverables file-mention logic), and its unit cases merged into the
component spec.
2026-09-07 16:46:46 +08:00
Tianyi Cui 7ef325619f Merge branch 'master' into fix/pr-ci-reliability-20260906 2026-09-07 16:46:31 +08:00
Tianyi Cui 930e4d67ea Merge pull request #3669 from deepseek-harness/fix/spkv-root-latest-master
ci(session): bring protected V3 integration onto latest master
2026-09-07 16:45:19 +08:00
_Kerman 4b009e7f94 refactor(api): shrink media-references surface and reuse maintained libs
- /api/file module now exports only the SessionMediaReferences plugin
  contribution; MIME and range policy helpers are module-private and
  exercised entirely through the registered route.
- Replace the hand-rolled media extension table with mime-types (served
  categories image/video/audio, excluding image/svg+xml) and the
  hand-rolled Range parser with range-parser; keep the fail-closed
  workspace containment policy.
- Spec rewritten as route-level behavior tests (12 cases) covering the
  same branches; Agent Note facts updated in the same change.
2026-09-07 16:35:15 +08:00
_Kerman f81c5072bd fix(api): close coverage edges in media-references route 2026-09-07 16:20:10 +08:00
creatixchu 48cc1cf1d6 feat(agent): announce model switches 2026-09-07 16:19:59 +08:00
Tianyi Cui b0ba955be2 Merge branch 'feat/system-prompt-surface-node' into feat/system-prompt-in-history 2026-09-07 16:17:19 +08:00
Tianyi Cui 476918da0a Merge latest master teardown and migration waiter fixes
Observe actual shared-preparation waiter admission and settle both callers before cleanup, preserving current V3 migration expectations. Adopt master’s cross-platform teardown regressions without changing budgets or Session data.
2026-09-07 16:15:57 +08:00
Tianyi Cui a062772d7d Merge latest master teardown and migration waiter fixes
Observe actual shared-preparation waiter admission and settle both callers before cleanup, preserving current V3 migration expectations. Adopt master’s cross-platform teardown regressions without changing budgets or Session data.
2026-09-07 16:15:57 +08:00
_Kerman b685a9a6b0 fix(api): satisfy oxlint same-type operand rule in range header 2026-09-07 16:02:14 +08:00
07akioni 5fd247f64c Merge latest master into feat/electron 2026-09-07 16:02:13 +08:00
creatixchu b2a3a0335d fix(typert): follow package-local forwarding modules in cross-package references
A type imported by relative path from a module of the same package that
re-exports it from another package failed as a cross-package reference
without an explicit package import. The analyzer now resolves the relative
specifier, follows re-exports while the file stays inside the referencing
package, and applies the public-export check to the package specifier the
chain reaches. Relative paths into other packages and forwarded private
exports still fail.

Fixes #3525
2026-09-07 15:58:40 +08:00
_Kerman 7a715e7919 refactor(api): serve /api/file media by extension allowlist only
Drop the byte-signature sniff duplicated from fs/tool-fs's read_image tool:
the cross-file duplication gate forbids the clone, and no shared owner
exists without widening the attachment package's public API. The
extension allowlist keeps non-media content out; corrupt image payloads
fail in the browser, not on the route. Agent Note facts updated in the
same change.
2026-09-07 15:53:54 +08:00
_Kerman 0c823f4b6f chore(docs): re-record config catalog translation-pair record 2026-09-07 15:53:53 +08:00
Tianyi Cui 4ac4e3d014 Merge pull request #3668 from deepseek-harness/fix/windows-subagent-teardown-ci
test(ci): synchronize Windows waiters and complete teardown
2026-09-07 15:52:01 +08:00
Tianyi Cui 7ebde31dde Merge current master human inbox controls into in-history updates
Preserve in-history request ordering and native V3 system heads while incorporating master’s human inbox controls. Regenerate only the current SDK child recording through its actual owner; retained V2 predecessor bytes match master.
2026-09-07 15:50:05 +08:00
Tianyi Cui d9042f61e1 test(snapshot): refresh V3 human-steering child recording
Record current V3 output from master’s human inbox control scenario while retaining the V2 predecessor unchanged. No additional product behavior or validation change.
2026-09-07 15:48:25 +08:00
Tianyi Cui b7f66f4440 test(sdk): record native V3 human-steering inbox transitions
Refresh the current V3 child recording through the actual SDK scenario after master’s inbox-control change. Preserve the V2 predecessor inherited from master and retain system-message admission and current references.
2026-09-07 15:47:27 +08:00
Tianyi Cui 50cce9c28d Merge latest master human inbox controls into system-prompt layer
Preserve the V3 PTC SDK assertion and enable the new human-steering runtime fixture while carrying master’s inbox lifecycle changes. Retain prior deterministic CI repairs and immutable predecessor ownership.
2026-09-07 15:45:09 +08:00
Tianyi Cui fffd39b101 Merge latest master human inbox controls into V3 integration
Preserve the V3 PTC scenario while enabling the current subagent human-steering fixture environment. All product changes are inherited from master; no V3 migration semantics are altered.
2026-09-07 15:44:17 +08:00
_Kerman 2aaa88ca1a chore(docs): regenerate config catalog after session-controller import shift 2026-09-07 15:42:16 +08:00
Tianyi Cui ce9f124e0e Merge branch 'feat/system-prompt-surface-node' into feat/system-prompt-in-history 2026-09-07 15:40:52 +08:00
Tianyi Cui e2b3800a7e fix(python): challenge fresh file state in live SDK smoke 2026-09-07 15:40:51 +08:00
Dudu-0223 96ead6091d feat(subagent): align human inbox controls (#3223)
* feat(subagent): align continuable human inbox controls

* fix: repair rebase documentation and close test persistence

* docs: refresh rebased module dependency graph
2026-09-07 07:39:39 +00:00
_Kerman 9da174c304 fix(web): display local media paths referenced in session prose
Assistant prose that references a workspace-contained local media path
(e.g. `![](/Users/.../x.png)`) now renders through a same-origin
`GET|HEAD /api/file?path=` route instead of inert alt text.

- ui-primitives: MarkdownText gains a settled-only MarkdownPathImages
  vocabulary gate (same posture as file mentions); no vocabulary means
  byte-identical output.
- ui-chat: AssistantMarkdown supplies a page-stable rewrite vocabulary
  for absolute POSIX paths (local-path-media.ts).
- session-controller: SessionMediaReferences plugin contribution mounts
  the route on the authenticated connection.fetch channel; per-request
  policy = workspace-root containment after realpath, regular file,
  allowlisted media extension (images additionally signature-checked),
  range/HEAD streaming, private no-store + nosniff, fail-closed statuses.
- Agent Note added (feature/2026-09-07-session-prose-local-media-display).

Closes #3662.
2026-09-07 15:34:19 +08:00
Tianyi Cui 275ff714cf Merge branch 'feat/system-prompt-surface-node' into feat/system-prompt-in-history 2026-09-07 15:03:33 +08:00
Tianyi Cui f7b1658ff2 fix(benchmarks): reserve system heads in generated V3 histories 2026-09-07 15:03:32 +08:00
Tianyi Cui 0d0914b814 fix(agent-loop): import message type for freeze provenance
Restore the explicit Message type import needed by master’s per-agent WeakSet after composing it with the in-history request builder.
2026-09-07 14:56:45 +08:00
Tianyi Cui 70ae2354d0 Merge latest master performance work and V3 preset migration
Freeze exactly the post-admission derived message array using the inherited per-agent provenance cache, preserving the prepared-route ordering and retry semantics. Adopt the root’s legacy preset migration without changing native V3 custom preset behavior. Request freeze, admission, projection and reconstruction regressions pass58 tests.
2026-09-07 14:55:12 +08:00
Tianyi Cui 19d167cec2 Merge latest master request-freeze and frontend performance work
Preserve the V3 system-prompt projection while adopting master’s per-agent frozen-message provenance and frontend performance gates. Keep benchmark workload admission and diagnostics fixes intact, and retain both migration and first-open/reopen lifecycle guarantees.
2026-09-07 14:53:00 +08:00
Tianyi Cui 95400aa52c Merge V3 preset-reference migration into system-prompt representation
Compose the root’s exact legacy code-to-ptc preset conversion with the existing structural system-head migration. Keep dense source events, audited payload admission, local reference mapping, and native V3 extension behavior unchanged. Preserve the historical preset migration fixture byte-for-byte and test unsupported sparse/opaque sources explicitly.
2026-09-07 14:51:05 +08:00
Tianyi Cui 85dcebcda4 Merge remote-tracking branch 'origin/master' into fix/spkv-root-latest-master 2026-09-07 14:48:39 +08:00
Tianyi Cui 8d0f45febc Merge remote-tracking branch 'origin/release/session-log-v3' into fix/spkv-root-latest-master 2026-09-07 14:47:55 +08:00
Tianyi Cui 5608528e14 Merge pull request #3637 from deepseek-harness/perf/frontend-scenarios
test(perf): gate long-session browser and reconnect workflows
2026-09-07 14:42:15 +08:00
Tianyi Cui b53c95e458 Merge pull request #3664 from deepseek-harness/fix/scroll-follow-pending-sample
fix(chat): preserve pinned scroll-follow across layout changes
2026-09-07 14:38:43 +08:00
Tianyi Cui 4023879df7 test(codex): finish captured cleanup after sibling failures 2026-09-07 14:30:31 +08:00
Tianyi Cui a1d11f213f test(session): observe shared waiter admission before cancellation 2026-09-07 14:30:29 +08:00
Tianyi Cui 5b2c9ba2d2 Merge pull request #3666 from deepseek-harness/worktree/session-v3-preset-rename
fix(session): migrate legacy code preset references to ptc
2026-09-07 14:30:24 +08:00
Tianyi Cui 1ca0df2e24 test(python): synchronize advanced snapshot workflow membership 2026-09-07 14:26:30 +08:00
Tianyi Cui 0ff0850678 Merge branch 'feat/system-prompt-surface-node' into feat/system-prompt-in-history 2026-09-07 14:21:50 +08:00
Tianyi Cui d1e9254454 fix(web-tests): author preset and stats seeds in current format
Generated V0 logs put user surfaces before the first step and cannot migrate to a protected V3 system head without changing chronology. Author native current headers, open the first step before the empty system head and user, keep title sequence references aligned, and supply embedded assistant streams.

Give the preset child a current identified user message. Preserve all paging, geometry, preset assertions and committed historical fixtures. Validated both generators red/green through the source seed reader, one full build, all preset/stats/trajectory browser tests (11), and scoped type-aware lint.
2026-09-07 14:21:50 +08:00
07akioni 4a9c180e2d Merge branch 'master' into feat/electron 2026-09-07 14:21:23 +08:00
Tianyi Cui dda0f05999 fix(web-tests): generate native system head before chat users
The long-chat builder emitted current V3 with user/message before system/message, so seed restoration rejected its protected head before browser assertions ran. Open the first step and append the system head before the user surface; keep Session-assigned title and tool-result references.

Add an independent seed-reader regression for current version, protected head order, title/tool references and closed turns. Observed protected-head failure before the fix; focused regression and full configured type-aware lint pass. Existing browser scroll assertions are unchanged; full built owner runs follow.
2026-09-07 14:17:08 +08:00
Tianyi Cui 12dd429331 Merge remote-tracking branch 'origin/master' into fix/spkv-root-latest-master 2026-09-07 14:02:51 +08:00
Tianyi Cui 2eccae5631 Merge branch 'release/session-log-v3' into worktree/session-v3-preset-rename 2026-09-07 14:00:22 +08:00
Tianyi Cui 73865675a4 docs(system-prompt): combine cache guarantees in model-experience field
Keep the merged in-history and stable suffix guarantees within the required single KV Cache effect paragraph. No behavior or guarantee changes.
2026-09-07 13:58:41 +08:00
Tianyi Cui c1be95a0cd Merge branch 'feat/system-prompt-surface-node' into feat/system-prompt-in-history 2026-09-07 13:56:15 +08:00
Tianyi Cui a4f6250be9 Merge remote-tracking branch 'origin/release/session-log-v3' into feat/system-prompt-surface-node 2026-09-07 13:56:08 +08:00
Tianyi Cui 086b94d4f6 Merge pull request #3655 from deepseek-harness/fix/v3-pwsh-current-fixtures
test(session): 同步最新 master 并修复 V3 PowerShell fixtures
2026-09-07 13:53:21 +08:00
Yichen Jiang ff33f79eb1 fix(session): migrate legacy code preset references to ptc 2026-09-07 13:52:22 +08:00
mektpoy 21db102cea refactor(ui-goal): keep activation slot types private 2026-09-07 13:50:11 +08:00
Tianyi Cui d43d93d89f test(agent-loop): use current persona slots in admission harness
Adopt master’s explicit personaPrefix/personaSuffix configuration in the in-history test harness. The assembly override and all admission assertions remain unchanged; this fixes the typed build integration rather than weakening the tests.
2026-09-07 13:46:33 +08:00
Tianyi Cui 9ef426d729 fix(chat): keep genuine near-floor scroll gestures pending 2026-09-07 13:46:30 +08:00
Tianyi Cui 421e3b075c test(subagent): preserve lane budgets and await teardown completion 2026-09-07 13:39:56 +08:00
Tianyi Cui a4e445236f Merge latest master prompt placement into in-history updates
Keep prepared-route in-history append, clear-all, and normalization semantics while adopting named persona prefix/suffix and late environment facts from master. Resolve documentation against the derived system-message history and retain the existing strict migration behavior.
2026-09-07 13:39:12 +08:00
Tianyi Cui d3ed6d6f88 Merge remote-tracking branch 'origin/master' into feat/system-prompt-surface-node 2026-09-07 13:35:06 +08:00
Tianyi Cui 57885bd73d Merge latest master prompt placement through V3 integration
Preserve system/message persistence while adopting named persona prefix/suffix and environment facts after reusable instructions. Resolve the Web assertion against the logged system message, not retired header.system. Keep the existing protected V3 integration PR as the root publication path; no rules are bypassed.
2026-09-07 13:34:43 +08:00
Tianyi Cui cbdf32447e fix(benchmarks): calibrate repeated hosted browser open median 2026-09-07 13:29:38 +08:00
Tianyi Cui 1a3af89a8d fix(benchmarks): calibrate hosted paging and trajectory endpoints 2026-09-07 13:29:38 +08:00
Tianyi Cui 620c2b0b27 fix(benchmarks): calibrate hosted frontend endpoints and preserve input overlap 2026-09-07 13:29:38 +08:00
Tianyi Cui 0ac1d4d865 test(perf): align browser provisioning with hosted benchmark runner 2026-09-07 13:29:38 +08:00
Tianyi Cui c51c16cdac test(perf): respect browser failover provisioning policy 2026-09-07 13:29:38 +08:00
Tianyi Cui 00e452aa03 docs(perf): confirm repeated frontend CI calibration 2026-09-07 13:29:38 +08:00
Tianyi Cui 82cd35467a docs(perf): record first frontend CI calibration 2026-09-07 13:29:38 +08:00
Tianyi Cui 9369585872 test(perf): bound browser observers to active response 2026-09-07 13:29:38 +08:00
Tianyi Cui 2927034ffe test(perf): retain successful CI measurement output 2026-09-07 13:29:38 +08:00
Tianyi Cui 7ac5e08246 test(perf): measure real history streams and live input overlap 2026-09-07 13:29:38 +08:00
Tianyi Cui 6ad74db2e3 test(perf): gate long-session browser and active reconnect workflows 2026-09-07 13:29:38 +08:00
Tianyi Cui 843c8723e5 docs(perf): link active hosted request calibration 2026-09-07 13:29:37 +08:00
Tianyi Cui e2b81cf8bf docs(perf): distinguish hosted request and catalog budgets 2026-09-07 13:29:37 +08:00
Tianyi Cui 8e270960ed test(perf): calibrate request history on standard hosted CI 2026-09-07 13:29:37 +08:00
Tianyi Cui 73edce1ae7 perf(agent-loop): reuse proven message freezes per agent 2026-09-07 13:29:37 +08:00
Tianyi Cui 84914c316d test(perf): calibrate baseline requests for hosted CI 2026-09-07 13:29:37 +08:00
Tianyi Cui 2f0088357d test(perf): calibrate tool continuation for hosted CI 2026-09-07 13:29:37 +08:00
Tianyi Cui daa7f60630 test(perf): calibrate catalog for standard hosted CI 2026-09-07 13:29:37 +08:00
Tianyi Cui 1507f82888 docs(perf): record backend CI evidence and align workload prose 2026-09-07 13:29:37 +08:00
Tianyi Cui c599ef87c4 test(perf): baseline tool-heavy backend workflows 2026-09-07 13:29:37 +08:00
Tianyi Cui e335d6af08 Merge V3 seed and coverage fixes from system-prompt parent
Preserve valid native V3 system heads in resumed fixture seeds and inherit the scanner coverage repair. Regenerate only upper-layer owner-local expected output through the actual loop so fallback title follows header/context. All five affected expected cases pass refresh; no historical Session generation or assertion is weakened.
2026-09-07 13:27:59 +08:00
Tianyi Cui 6c4cd033e3 Merge pull request #3280 from deepseek-harness/fix/ci-node-compile-cache-data-disk
ci: redirect Node compile cache to data-volume runner temp
2026-09-07 13:24:49 +08:00
Tianyi Cui fa6bf62a98 fix(chat): settle pinned scroll deliveries before layout growth 2026-09-07 13:24:04 +08:00
07akioni 6d55da993d Merge master into feat/electron after scope cleanup 2026-09-07 13:21:45 +08:00
07akioni 4879a8a33a refactor(desktop): remove unrelated changes and own host dependencies 2026-09-07 13:16:04 +08:00
Tianyi Cui 74a6d30aba test(cli): seed resumed native V3 sessions with protected system heads 2026-09-07 13:15:38 +08:00
Tianyi Cui cbbbb30214 Merge remote-tracking branch 'origin/master' into release/session-log-v3 2026-09-07 13:15:00 +08:00
Tianyi Cui 78f03ffef9 fix(session): cover V3 admission and keep compressed fixture migratable
Keep the synthetic compressed historical fixture step-first without changing frozen generation data or shared fixtures. Pin its migrated empty system head and unchanged source bytes. Exercise malformed native system rows before and after recoverable damage through scanner and read/write handles. Remove the unreachable duplicate unsupported-format catch after current-row admission; preserve its owned rejection and generic error path.

Validation: original zstd regression red; admission-bypass negative control 3/3 red; five focused specs 314/314 pass with format.ts 100% statements/branches/functions/lines. Final admission cleanup 15/15 pass. Full build-backed lint found one matcher typing error; exact identifier oracle replaces it and focused type-aware lint passes.
2026-09-07 13:14:18 +08:00
Tianyi Cui 25b28a14cd Merge branch 'feat/system-prompt-surface-node' into feat/system-prompt-in-history 2026-09-07 13:12:53 +08:00
Tianyi Cui 76cf592234 Merge commit 'd1e5b724d71e9a6f675232caa760395710826b81' into feat/system-prompt-surface-node 2026-09-07 13:12:46 +08:00
Tianyi Cui ef11a4e007 Merge pull request #3644 from deepseek-harness/fix/environment-prompt-suffix
fix(system-prompt): move environment facts behind reusable instructions
2026-09-07 13:12:22 +08:00
Tianyi Cui f68c4239e4 Merge remote-tracking branch 'origin/master' into release/session-log-v3 2026-09-07 13:09:36 +08:00
Tianyi Cui 7340438fe7 Merge latest master integration from system-prompt parent
Propagate the V3 parent and current master CI reliability fixes without changing in-history semantics, performance budgets, or recorded predecessor ownership. PR-owned CLI seed and source-coverage repairs follow in their lower owning layer.
2026-09-07 13:09:27 +08:00
Tianyi Cui fdd6380503 Merge latest master V3 integration into system-prompt representation
Retain the protected system-message fixture representation while incorporating the latest master PowerShell, browser timezone, asynchronous subscription and Python-runtime CI fixes through the V3 parent. Existing parent V3 successor refreshes are preserved without rewriting predecessor bytes beyond upstream master.

Local build and pwsh one-shot refresh passed. Persistent PowerShell completes the model turn but times out during process exit on both this layer and the updated V3 parent; an exact-master control is running before attributing that failure. PR-owned seed and coverage repairs are isolated follow-ups.
2026-09-07 13:08:26 +08:00
07akioni 0125f9019e revert: remove pwsh changes from desktop PR 2026-09-07 13:08:11 +08:00
Tianyi Cui 3d54bd6d58 Merge branch 'master' into fix/ci-node-compile-cache-data-disk 2026-09-07 13:06:30 +08:00
Tianyi Cui 403b978c6c Merge pull request #3626 from deepseek-harness/optimize/ci-compatible-selfhosted
ci: run isolated Node compatibility jobs on self-hosted Linux
2026-09-07 13:05:07 +08:00
_Kerman 78ee959a5b Merge remote-tracking branch 'origin/master' into xtr/explicit-agent-context 2026-09-07 12:58:58 +08:00
07akioni 694d250f7a Merge master and retain upstream CI synchronization fixes 2026-09-07 12:44:25 +08:00
Tianyi Cui a7ea2d74de docs: remove redundant compatibility runner guide 2026-09-07 12:42:02 +08:00
Tianyi Cui ac4fa3d6f5 docs: clarify compatibility runner scope and verification 2026-09-07 12:42:02 +08:00
mektpoy 03ce9c2ab3 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation
# Conflicts:
#	packages/terminal/terminal-bash/tests/local.spec.ts
#	snapshots/session/persistent-pwsh-tool-turn/session.v2.jsonl
#	snapshots/session/pwsh-tool-turn/session.v2.jsonl
2026-09-07 12:41:49 +08:00
Tianyi Cui a137256f80 ci: set compatibility toolcache after runner environment export 2026-09-07 12:41:23 +08:00
Tianyi Cui f7a18f49ff ci: isolate compatibility Node jobs on self-hosted Linux 2026-09-07 12:41:23 +08:00
Tianyi Cui fd9debed10 Merge branch 'master' into fix/environment-prompt-suffix 2026-09-07 12:41:16 +08:00
Tianyi Cui c379894af8 fix(ci): isolate routing test setup and correct scheduling docs 2026-09-07 12:40:40 +08:00
Tianyi Cui ab1ee99685 ci: defer macOS ARM runtime and Wine checks to master 2026-09-07 12:40:40 +08:00
07akioni fbb385c58f test(web): pin replay timezone and await UI settlement 2026-09-07 12:40:26 +08:00
mektpoy d006772ab6 fix(goal): enforce durable pause at execution time 2026-09-07 12:39:54 +08:00
Tianyi Cui d49cbed379 Merge master and retain independent PR CI reliability fixes 2026-09-07 12:38:27 +08:00
Tianyi Cui b648d3712f Merge remote-tracking branch 'origin/master' into release/session-log-v3 2026-09-07 12:34:13 +08:00
Tianyi Cui 31090e240a Merge pull request #3643 from deepseek-harness/fix/ci-python-runtime-smoke-retry
fix(ci): 加固 Python runtime 构建——安装重试与凭据隔离
2026-09-07 12:29:43 +08:00
mektpoy 8188dc55f9 test(snapshot): make ACP diagnostic wait deterministic 2026-09-07 12:19:54 +08:00
mektpoy 35bc3a3c60 test(web): normalize browser timezone in snapshots 2026-09-07 12:12:02 +08:00
winewill 541dc51e9e fix(desktop): allow fs-ext in generated projects 2026-09-07 12:11:34 +08:00
_Kerman 8551b04e95 test(tool-subagent): use current session format in fixture 2026-09-07 12:11:18 +08:00
_Kerman b759ad91e8 Merge remote-tracking branch 'origin/master' into xtr/explicit-agent-context
# Conflicts:
#	packages/subagent/subagent/src/continuation.ts
2026-09-07 12:09:06 +08:00
07akioni 8b250f5df5 test: synchronize console and shell readiness and pin browser timezone 2026-09-07 12:08:29 +08:00
mektpoy ed3c7efade test: sync pwsh snapshots and readiness 2026-09-07 12:02:24 +08:00
Tianyi Cui 24f6b30d10 test(web): isolate browser timezone and settle reference fixture queries 2026-09-07 12:00:18 +08:00
Tianyi Cui 60d3e32069 fix(test): await lazy grammar registration notifications 2026-09-07 11:54:10 +08:00
07akioni 1ed20364cd test(snapshot): refresh PowerShell fixtures 2026-09-07 11:51:59 +08:00
Tianyi Cui 571ee55ca6 test(web): pin recorded Cordis browser timezone 2026-09-07 11:38:36 +08:00
mektpoy ab62273984 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation 2026-09-07 11:37:52 +08:00
Tianyi Cui 64dfd7a425 fix(test): await Client Console subscription delivery 2026-09-07 11:35:13 +08:00
Tianyi Cui 313a8958c4 fix(test): pin minimal PowerShell fixtures and wait for exact prompt readiness 2026-09-07 11:23:54 +08:00
Tianyi Cui f5302b2b4d fix(test): isolate recorded Web browser timezone 2026-09-07 11:17:42 +08:00
07akioni 31b3f3bc44 Merge remote-tracking branch 'origin/master' into feat/electron
# Conflicts:
#	.agents/notes/archived/manifest.json
#	.agents/notes/archived/simplification/2026-07-31-drop-user-message-edit-stub.i18n.yaml
#	.agents/notes/archived/simplification/2026-07-31-drop-user-message-edit-stub.md
#	.agents/notes/archived/simplification/2026-07-31-drop-user-message-edit-stub.zh.md
#	.agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.i18n.yaml
#	.agents/notes/implemented/bug-fix/2026-09-05-nested-terminal-cards.i18n.yaml
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.zh.md
#	packages/boot/app-boot/README.i18n.yaml
#	packages/boot/app-boot/README.md
#	packages/boot/app-boot/README.zh.md
#	packages/client/connection/src/index.ts
#	packages/client/connection/tests/node-half.host.spec.ts
#	packages/shell/tool-pwsh-persistent/README.i18n.yaml
#	packages/shell/tool-pwsh-persistent/README.md
#	packages/shell/tool-pwsh-persistent/README.zh.md
#	pnpm-lock.yaml
#	tsconfig.host.json
2026-09-07 11:10:46 +08:00
Tianyi Cui 8def94aa5a test(sdk): record in-history admission in composed V3 PTC scenario
Capture the inherited SDK PTC scenario under the upper loop lifecycle using the real current writer. The shared V3 dispatch vocabulary and protected system head remain unchanged; title follows admitted header/context as in the other upper recordings.
2026-09-07 11:09:40 +08:00
Tianyi Cui 691861091f test(python): record upper V3 native event ordering
Regenerate current Python Session expectations through the real macOS arm64 SEA executable built from fdd44667b4b496093e765af57d3751dfb917d834. The native writer emits session/title after request/header and request/context. Update only five current V3 logs; result.json, minimal/model-visible.json, and minimal-in-history/prompt-history.json regenerate identically. All five V2 predecessors remain byte-identical to b2b300f9.

Build evidence: LEFTHOOK=0 pnpm install --frozen-lockfile --offline; pnpm exec tsx scripts/build-exe-for-python-sdk.ts --targets node24-macos-arm64 (full build, no skip-build): passed. file dist-exe/deepseek-harness-sdk-runtime-macos-arm64: Mach-O 64-bit executable arm64.

Smoke evidence: export PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=python/sdk/src:python/sdk-runtime/src; PY=/Users/cty/dsh-deploy/.agents/worktrees/sp-kv-sdk-evidence/tmp/py-sdk-venv/bin/python. For each scenario in sdk-snapshot sdk-restart sdk-minimal sdk-minimal-in-history, ran "$PY" scripts/smoke-python-runtime.py --exe dist-exe/deepseek-harness-sdk-runtime-macos-arm64 --scenario "$scenario" --update-snapshots, then the same command without --update-snapshots: all eight passed.

Helpers: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=python/sdk/src:python/sdk-runtime/src uv run --offline --no-project --python /Users/cty/.local/share/uv/python/cpython-3.14.5-macos-aarch64-none/bin/python3 --with pytest --with "pydantic>=2.12,<3" python -m pytest python/sdk/tests/test_smoke_model.py -q: 28 passed. git diff --quiet b2b300f9 -- "scripts/snapshots/python-sdk-single-exe/**/*.v2.jsonl" and git diff --cached --check passed. No source, migration, test, or launcher changes.
2026-09-07 11:09:40 +08:00
Tianyi Cui 6cb0bc1e69 test(session): record upper V3 PowerShell admission order
Refresh both PowerShell native V3 cases with the installed PowerShell runtime so fallback title follows admitted request metadata consistently with the other upper-layer recordings. Refresh and independent replay both pass; historical inputs and output content remain unchanged.
2026-09-07 11:09:40 +08:00
Tianyi Cui afec36839d test(snapshot): refresh upper V3 ACP and Web event ordering 2026-09-07 11:09:40 +08:00
Tianyi Cui b2d1cd942e docs(token-meter): distinguish projection cache from Session V3
Align the in-history ownership note with compact projection checkpoint version4. Both PRs use Session format3; the projection cache version is independent and invalidates scalar caches without introducing another persistence format.
2026-09-07 11:09:40 +08:00
Tianyi Cui 1fb187b31e test(session): record final V3 admission order across native profiles
Regenerate only native V3 Session/output oracles through the shipped headless and SDK profiles. These outputs retain system-message admission before users, bind request metadata before title fallback, and record real V3 delivery acknowledgments. Historical V0/V1/V2 replay inputs remain unchanged; pinned scenarios keep separate writer outputs.

The upper headless/SDK refresh covered109 cases; the only initial failure used macOS system Python3.9 for the PTC Python scenario, which passed with the declared CPython3.14 PATH. No assertion or runtime behavior was changed to accommodate it.
2026-09-07 11:09:40 +08:00
Tianyi Cui 179699a8c8 test(snapshot): mark in-history scenarios as native V3 2026-09-07 11:09:40 +08:00
Tianyi Cui 621d03d003 test(trajectory): pass partial-window state to the assembler fixture
Forward the new headerless-window regression flag to replaceWindow instead of silently ignoring an extra test-helper argument. This makes the regression exercise a real incomplete history window and fixes the aggregate test typecheck without changing production behavior.
2026-09-07 11:09:40 +08:00
Tianyi Cui cea0aff474 fix(web): display known prompts in headerless history windows
Give appended Chat system messages their own cards and suppress the following initial or same-step update header card. Preserve replacement/header ownership and conservative unknown surface ordering. Trajectory uses prompt-only presentation when no request header is loaded, never fabricated provider, model, or tools; prepend deduplicates against real request changes. Test-first regressions showed missing Chat cards and missing trajectory prompt data; 148 focused tests and affected client project typechecks pass.
2026-09-07 11:09:40 +08:00
Tianyi Cui 4574602c07 fix(token-meter): distinguish compact caches from parent scalar version
The parent representation fix now correctly invalidates header-based caches with scalar state version3. The dependent in-history projection has a different compact live-surface schema and must not reuse that version. Advance it to4 and prove that a lower-layer version3 cache is discarded and refolded, alongside the existing version2 regression. No historical Session migration or compatibility mechanism is added.

Addresses ds-review-bot cache-version thread3921300994 across the stack. Validation:62 focused projection, adapter and admission tests passed; context.ts and breakdown-projection.ts each have100% exact-source coverage; paired README record updated.
2026-09-07 11:09:40 +08:00
Tianyi Cui 85421f31bc fix(agent-loop): detect first resumed pre-step replacement
Seed the request surface watermark from the attached session so a replacement before the first resumed request consolidates retained prompt versions. An unchanged resume still continues the series. Actual-loop replacement regression fails before the fix; 53 focused tests and the agent-loop project typecheck pass.
2026-09-07 11:09:40 +08:00
Tianyi Cui c562a4193c test(web): omit throughput for zero-duration skill seed
The normalized embedded stream in the skill seed contains no positive decode interval. Its rendered metrics correctly omit throughput rather than invent a rate. Refresh only the owning ARIA expectation after the full Web lane isolated this final mismatch; user/model/skill content and metric calculation remain unchanged.

Validation: owning refresh and subsequent read-only browser replay pass. The preceding full Web run had only this one expectation mismatch.
2026-09-07 11:09:40 +08:00
Tianyi Cui 6861ac7459 refactor(client): trust narrowed surface event markers
The in-operator narrows SessionEvent to events whose surfaceOp is required. Remove redundant undefined checks from both target Definitions; retain append-versus-replacement discrimination and shared prompt interpretation. This deletes dead conditions reported by the full type-aware CI lint gate without adding fallback behavior.

Validation: both Chat and Trajectory definition regression suites pass with the simplified predicates.
2026-09-07 11:09:40 +08:00
Tianyi Cui 044777fc2b docs(prompt): remove stale representation claims after integration
State the implemented empty-head reservation and messages-only summarization input in the feature note. Align the Chinese Chat contract with the shared surviving-surface interpretation rather than chronological predecessor selection. These localized corrections remove stale claims left by independently merged fixes without changing code or tests.

Validation: both bilingual pairs re-recorded and normal pairing hooks pass; the referenced runtime behavior is covered by the already executed empty-head, compaction and partial-window regressions.
2026-09-07 11:09:40 +08:00
Tianyi Cui f7b3f237bd test(session): target the admitted request header in spill replay
Synchronous admission finalization moves the first request/header to seq10 before the deferred title. Read that actual header rather than seq11 request/context so the spill scenario exercises a large canonical request record. Keep the inherited dynamic-locator verification and independent file-content oracle; the test now requires a real successful read and SPILL_CANONICAL_OK rather than recording shell failure.

Validation: targeted built refresh and subsequent read-only replay both pass with complete spilled JSON equal to the live request/header and the session_event_search schema present.
2026-09-07 11:09:40 +08:00
Tianyi Cui af87e576da test(token-meter): preserve shadow-price mismatch rejection coverage
The breakdown refactor correctly stopped consuming scalar shadow claims, but its old negative test was the only coverage of the pressure fold rejection path. Exercise the remaining real pressure consumer with mismatched start and end claims, preserving the runtime invariant rather than deleting or ignoring its guard.

Validation: Linux and Windows CI reported the two uncovered locations in surface-projection.ts. All118 token-meter tests pass and the exact pressure fold file now has100% statement, branch, function and line coverage.
2026-09-07 11:09:40 +08:00
Tianyi Cui 42955a346a test(python): record final admitted-input notification order
Refresh advanced and restart expectations through the final native packaged runtime. Synchronous request finalization places deferred fallback-title events after header/context in parent and child logs; expected SDK notifications must reflect that actual lifecycle instead of forcing the old incidental scheduling order.

Validation: the advanced mismatch was reproduced against the built macOS ARM64 executable, both owning scenarios refreshed, then the complete keyless --scenario all passed, including the new in-history prompt evidence and independent shell/file effects. No SDK runtime or normalizer behavior changes in this commit.
2026-09-07 11:09:40 +08:00
Tianyi Cui fc1bc118e9 docs: align generated admission contracts and SDK evidence
Regenerate the source-owned service and persistence catalogs after prepared-route admission and clear semantics changed. Synchronize exact bilingual declaration blocks and replace the obsolete SDK evidence gap with links to the recorded TypeScript notifications and Python prompt history. Keep generated descriptions tied to the source instead of preserving the old previous-context decision rule.

Validation: both changed catalog/note pairs passed scoped pairing and exact type-equivalence/graph checks passed in the preceding isolated documentation repair. Complete documentation gates are rerun on the final integrated tree.
2026-09-07 11:09:40 +08:00
Tianyi Cui 326f5ef869 test(session): refresh admitted-input ordering across shipped profiles
Request preparation now precedes durable user admission and finalization is synchronous. The title service intentionally defers fallback publication, so titles naturally follow request/header and request/context instead of landing in an incidental await gap. Refresh the actual headless, SDK, ACP and CLI recordings rather than adding a synthetic yield or changing title ownership to preserve obsolete ordering.

Keep every model response, user input, tool effect and identity relationship; review reordered title/header facts and remapped references. Current master also removes the base editor contribution, so shared schema pins follow the actual shipped profile. Historical generations remain unchanged: their test-only comparison orders title facts independently while preserving title payloads and references. Normalize only generated stream clocks in refreshed fixtures.

Validation: owning refresh runs passed current scenarios, CLI expected tier28/28, Web minimal/replay11/11 and targeted SDK in-history1/1. Read-only full built corpus passed127 cases with2 unavailable-PowerShell skips; its sole failure is the separately repaired historical invalid-citation negative control on the lower PR. Six retained historical comparison cases pass. No production behavior is changed in this commit.
2026-09-07 11:09:40 +08:00
Tianyi Cui 627747d8fa docs: synchronize prompt admission contracts and repair lifecycle diagram
Copy the current SessionEventMap prompt and route JSDoc into both subsystem references so type-equiv validates the prepared-route and clear-all semantics. Remove the Mermaid statement delimiter from the generated retry note while retaining the same lifecycle meaning; regenerate graph artifacts and confirm both bilingual pairs.

Validation: verify-type-equiv, verify-mermaid, verify-doc-graphs, scoped verify-translation-pairing, and git diff --check.
2026-09-07 11:09:40 +08:00
Tianyi Cui 2b363223da fix(agent-loop): clear noncanonical retained system content
A durable system message may contain multiple text blocks or other content. The runtime-context helper recognizes only one text block; treating an unrecognized system message as empty allowed clearing and incapable-route normalization to leave its instructions active. Keep undefined text distinct from genuinely empty content so every noncanonical node is replaced or cleared instead of silently skipped. Runtime-context snapshot equality remains unchanged.

Regression: a multiblock head and nontext tail previously survived a clear request; the new source-level case fails before this fix. Both system-prompt projection and actual-loop admission suites pass (21 tests).
2026-09-07 11:09:40 +08:00
Tianyi Cui 99cffb4de7 test(client): construct immutable multi-block system fixture
The system message content is readonly. Build a replacement fixture value for the multi-block extraction test instead of assigning into a readonly message property. Preserve the exact behavioral assertion without weakening production types or adding a cast that hides mutation.

Validation: aggregate client build exposed TS2540 at the mutation; all seven system prompt interpretation tests pass with immutable fixture construction.
2026-09-07 11:09:40 +08:00
Tianyi Cui 84e94d8394 test(token-meter): narrow optional projection state before checkpoint checks
The session projection API can return undefined when a unit is not registered. Assert the registered test fixture produced state before inspecting compact entries, rather than assuming a value that the current master type does not guarantee. This preserves the retained-state regression and adds no production fallback.

Validation: the aggregate build identified three TS2532 errors in this test; all context-breakdown projection cases pass after narrowing. Full build is rerun separately.
2026-09-07 11:09:40 +08:00
Tianyi Cui 1721a9c566 test(compaction): expect admitted instructions on metered retry
The meter regression deliberately rewrites the system node during request-error recovery. After the retry reconciliation fix, the next request must restore the captured admitted prompt rather than trust that temporary replacement. Keep the replacement stimulus and zero-delta metering assertions, but compare the retried prompt with the initial request so the two independently corrected components are tested together.

Validation: the combined regression run exposed this obsolete retry-text expectation while 945 other cases passed; all eight compaction-loop-repro cases pass with the admitted-prompt assertion.
2026-09-07 11:09:39 +08:00
Tianyi Cui 7e253f3995 test(llm-deepseek): isolate in-history cache retention evidence
Namespace prompt prefixes per invocation and compare appended updates against an identical warm request. Check exact pre-dispatch message prefixes and stopped responses; use the same latest prompt for rewritten-head control, without an artificial Updated prefix or assumed cache block size. This measures provider behavior, not loop capability selection.

Validation: serialize.spec.ts 54 passed; adapter.spec.ts 154 passed after offline dependency install resolved collection failures; focused e2e selector collected and skipped without standard key/model configuration; focused staged-config lint and git diff --check passed. No live provider result claimed.
2026-09-07 11:09:39 +08:00
Tianyi Cui b3116b6048 fix(client): derive effective system prompts from surviving surface nodes
Chronological lookup keeps B after compaction shadows it even though the model sees surviving head A and no system event is emitted. Share pure extraction and compact immutable surface interpretation through uiConversation; target-owned Definitions preserve historical cards. Track inherited surface positions in a map containing only surviving replacement endpoints. No full-log scans or prompt work on ordinary messages/chunks.

A partial window cannot infer the order of older unindexed endpoints: pre-window [head seq5, tail seq3], followed by replacements 3->6 and 5->7, must not report seq7 as effective. Withhold subsequent prompt text until prepend reconstructs the prefix; exact pure and both target regressions cover unavailable -> C. Drop shadowed replacement-index entries; repeated rewriting one node keeps one entry, while historical prefix maps remain immutable. Current replacement work is O(S+P), where S is surviving system nodes and P surviving replacement endpoints; history retains per-prefix copies, not an unbounded linked chain.

Coverage includes A->B->C, A->B->compaction->A without a system event in replay/live/partial windows, chained nonmonotonic replacements, empty tails, head rewrites, unknown ordering, inherited prompt withholding, and index pruning. Focused suites total 89 passing cases; rebuilt trajectory smoke 3 passed. Affected client types/lint/bundles, diff checks, and 33/33 doc-sync gates passed. README EN/ZH and owning note updated. Parent owns final GUI/recorded-session evidence; no server started.
2026-09-07 11:09:39 +08:00
Tianyi Cui 9c8884284f test(sdk): record in-history system prompt updates in both clients
Cover the missing SDK projections through shipped dsh profiles. TypeScript reuses the headless read-completion composition and records SDK notifications. Python all includes a focused minimal-profile variant with an ordinary prompt section updated after shell completion, unchanged tools, persisted/subscribed append events, and independently checked editor output.

Observed: focused TS refresh and built replay passed (1 test); Python sdk-minimal-in-history and sdk-minimal passed against apps/cli/lib/bin.js using uv; unchanged-prompt negative control failed as expected then restored scenario passed; corpus 3 tests, doc-sync 33 gates, and lint:contracts-ready passed. Host-only build initially left SDK built startup incomplete; build:lib:client completed the prerequisites. Native packaged/wheel and Windows validation remain pending parent integration.
2026-09-07 11:09:39 +08:00
Tianyi Cui 8d0bf14eb6 docs(notes): remove superseded in-history prompt proposal
The proposed and implemented 2026-09-02 feature triplets record the same decision. Keeping the proposal active presents obsolete node-0/config-change rules as live work even though PR3483 already shipped the capability. Delete the complete proposed EN/ZH/sidecar triplet rather than archive a proposal or retain a redundant rejection.

Read both complete bilingual notes before consolidation. The implemented owner already retains the motivation, all five proposal alternatives, cache cost and proxy/model risks, capability validation, and current snapshot/e2e evidence. Preserve the still-valid unchanged-prompt/resume lifecycle verification and both SDK typed appended-event expected-output requirement in its Testing paragraph. Explicitly identify missing SDK appended-event coverage instead of treating the headless snapshot as SDK evidence. Do not revive the obsolete plan-mode fixture or absolute cache-hit inequality; the implemented note records the shipped fixture and comparative e2e assertion.

Only the implemented Testing paragraph and pairing record change. Runtime, accounting, UI, and frozen archived notes are untouched. Active inbound references already target the implemented owner, so no link retarget is necessary. This commit addresses only the reviewed lifecycle/consolidation finding.

Focused evidence (all exit 0): pnpm install --frozen-lockfile; pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.md (1 record written); pnpm run verify-translation-pairing .agents/notes/implemented/feature/2026-09-02-in-history-system-prompt-replacement.md (1 named pair consistent); pnpm run verify-md-links (1381 files, all links/fragments resolve); pnpm run verify-agent-note-format (246 notes conform); git diff --check; git diff --cached --check. Full combined doc-sync remains with the parent integration branch after runtime fixes; no full gates, push, rebase, or hook bypass.
2026-09-07 11:09:39 +08:00
Tianyi Cui 095c51aa1c fix(ui-trajectory): compare consecutive prompt updates with latest state
An in-history route can append A, B, and C without another request/header. The system-message Definition read only the prior real header, so C incorrectly reported A as its previous prompt. Select the newer real or synthetic header through the existing indexed predecessor reader; preserve target-owned Definitions and avoid any log scan.

Add replay and per-event live A -> B -> C regressions. Both fail before the fix with previous=A and pass with previous=B. All 13 trajectory Definition tests pass; focused staged lint, bilingual pairing, and diff checks pass. Update the trajectory README pair and owning design note.
2026-09-07 11:09:39 +08:00
Tianyi Cui 6525195953 fix(token-meter): classify surviving prompts in surface order
Scalar shadow prices cannot restore an earlier effective prompt when compaction removes the newest system node: subtracting that price from messages can permanently make the published bucket negative. Reuse the positional measurement planner over compact current surface entries and choose the last nonempty system by surface order, not event sequence or provenance citations.

Explicitly trade the scalar checkpoint for O(current retained surface) state, dropping shadowed entries and message bodies. Version 3 invalidates old scalar checkpoints; pure transitions preserve wire identity for same-price rewrites. Cover newest/middle removal, reversed sequence ranges, extra sources, empty fallback nodes, replay and late registration, cache version rejection, and route-independent heuristic totals. Document the bounded-state exception and rejected prompt-only ancestry approach in both languages.
2026-09-07 11:09:39 +08:00
Tianyi Cui 4028686136 fix(agent-loop): clear every retained system instruction
Use the same logged per-node normalization for an empty rendering as for incapable routes and broken request series: empty each active later system node, then empty the first node. Clearing only the latest node exposes stale earlier instructions, including converter-demoted user text. Dormant empty tails neither override effective text nor produce repeated replacements.

Keep the cleared structural head and ordinary restoration semantics: a capable continuing series may append new nonempty instructions, while incapable or broken-series requests refill the head. No initial empty-head creation change, deletion event, or rollback machinery.

Tests: capable/plain clearing after three active prompt versions fails before the fix and passes afterward; repeated clear and seeded resume remain empty without duplicate system events, restoration includes only new instructions, pi-ai conversion has no stale prompt, and source-event replay reconstructs every request. Final 395 loop tests pass with exact agent.ts/runtime-context.ts coverage at 100% all metrics; source tsc and focused lint pass. Fix new test discriminant narrowing discovered by focused compiler audit. Update EN/ZH consumers and owning rationale, seven pairs verified; parent owns broad gates and generated catalog/SDK/GUI updates.
2026-09-07 11:09:39 +08:00
Tianyi Cui 425a0a55e3 fix(agent-loop): reconcile prompts after retry compaction
Every same-step attempt resolves its bound route and reconciles the accepted rendered prompt against the current surface before deriving history. Preserve assembly, pre-step admission and entered users exactly once; compaction retries must not resurrect an older surviving prompt.

Normalize a broken request series to the current head plus dormant empty later system nodes, even if later versions survive or the effective text is unchanged. This removes the later-survivor exception without a delete operation and avoids appending instructions after already-admitted users on retry. Capture surface generation after reconciliation so subsequent ordinary retries do not emit phantom series headers.

Tests: both compaction cases fail before the fix (stale head, or stale later survivor), then pass with real loop/MockAdapter, pi-ai conversion and source-event reconstruction. Assert two retries keep one assembly/pre-step/user admission, preserve rendered text across section changes, and log one series boundary. Add unchanged-text explicit/tool series regressions. 391 loop tests with exact agent.ts/runtime-context.ts coverage pass at 100%; final admission spec has 11 passing cases. Source tsc and focused lint pass. Update EN/ZH implementation and owning rationale plus lifecycle retry documentation.
2026-09-07 11:09:39 +08:00
Tianyi Cui 2ce9738564 fix(agent-loop): admit prompts under the prepared route
Resolve agent/request and prepareCall inside the accepted open step before committing system and user input. Preserve prompt-assembly model selection, bind capability and dispatch to the same prepared adapter, then log the envelope and derive the request synchronously. Preparation cancellation leaves a balanced empty step with no admitted input.

Normalize incapable-route retained prompt versions with logged per-node empty replacements and a current head, including unchanged rendering and resumed history. Dormant empty tails do not override the effective prompt. No new event or delete operation.

Tests: 389 agent-loop cases pass with exact agent.ts/runtime-context.ts coverage at 100% for all metrics; tsc -b packages/core/agent-loop/tsconfig.json passes. Seven actual-loop MockAdapter cases exercise pi-ai conversion, source-event reconstruction, both route transitions, resume, cancellation barriers, and bound selection. Stale-capability negative control fails all three transition regressions. Update EN/ZH request visibility, lifecycle generator, and owning rationale. Broad catalogs, recorded SDK/GUI and aggregate gates remain parent-owned.
2026-09-07 11:09:39 +08:00
Tianyi Cui c988a6796f feat(agent-loop): append system prompt changes on capable routes
Consolidate the existing in-history capability, loop, UI and artifacts into one baseline. Preserve the reviewed tree so each independently verified correction has a subsequent rationale-rich commit.
2026-09-07 11:09:39 +08:00
Tianyi Cui fcbadb07db fix(benchmarks): keep Session opening fixture migratable to V3
Begin each synthetic step before its user surface message so the structural V2-to-V3 migration can reserve its protected system head without reordering historical events. Keep the workload size, frame partition, original chunk provenance, and every timing/heap budget unchanged.

Add a small real persistence migration/publication/reopen prerequisite that preserves all user and assistant content and original V0 bytes. Both this regression and bounded stderr-headline regression fail before the fix and pass afterward. Worker errors retain a bounded head and tail instead of hiding migration refusal behind a generic stack tail.

Validation: full Session-opening benchmark16/16 passed, including all six128MB completion cases; focused full type-aware lint passed. First Agent resume median178.7ms and reopen27.4ms are below unchanged450/100ms budgets.
2026-09-07 11:09:36 +08:00
Tianyi Cui 237b3d5edf fix(test): synchronize pwsh completion and refresh profile snapshots 2026-09-07 11:07:19 +08:00
Tianyi Cui f7c5621db6 test(snapshot): refresh current V3 PowerShell fixtures
Refresh both current-writer successors with the real PowerShell runtime and existing headless composition. Align their owned prompt/schema pins with installed tools; retain every historical Session generation and the recorded model/tool behavior.
2026-09-07 10:54:56 +08:00
Tianyi Cui 15345af731 fix(test): synchronize console enablement and verify fresh SDK file content 2026-09-07 10:43:46 +08:00
Tianyi Cui beb23febfd Merge branch 'master' into fix/environment-prompt-suffix 2026-09-07 10:43:43 +08:00
Tianyi Cui cc69d5fcac fix(ci): isolate Playwright cache and installation locks per runner 2026-09-06 22:59:11 +08:00
Tianyi Cui 4158a81188 test(snapshot): cover cleanup when spill allocation fails 2026-09-06 22:55:17 +08:00
Tianyi Cui 362ee7931d fix(test): isolate recorded spill and sandbox fixture storage 2026-09-06 22:44:54 +08:00
Tianyi Cui f50dce316c fix(ci): isolate persistent pnpm indexes on runner data volumes 2026-09-06 22:16:00 +08:00
Tianyi Cui 350dcad963 fix(test): allocate sandbox snapshot outside temp grants on runner volume 2026-09-06 22:04:52 +08:00
Tianyi Cui e61d9fc0c7 fix(ci): isolate npm caches and synchronize ACP snapshot completion 2026-09-06 21:47:55 +08:00
Tianyi Cui 6ad0799419 test(cli): seed diagnostic parent with native system head 2026-09-06 21:35:03 +08:00
Tianyi Cui 4107ae7516 test(sdk): record combined V3 PTC system-message notifications
Refresh the inherited SDK PTC scenario through the native V3 writer so its protocol oracle includes the protected system head. The generated Session remains unchanged and independent replay passes.
2026-09-06 21:35:03 +08:00
Tianyi Cui 71b0d83822 Merge current V3 PTC vocabulary into system-prompt representation
Compose the shared release branch PTC rename with the structural system-head migration in the existing V2-to-V3 stage. Audit source payloads and remap local coordinates before renaming dispatch vocabulary and owned plugin attribution; retain original message identities and generation-qualified references. Native V3 validation combines the same system and PTC lifecycle semantics through a private released-validation view.

Reuse the V3 row-admission owner in current JSONL scanning before recoverable-tail suppression, so malformed rows cannot hide retired required PTC tags or header.system. The new corruption-prefix regressions and all173 existing JSONL scanner tests pass. Combined migration/catalog/persistence suite:300 tests; executable V3 migration source has100% coverage. No released generation, prior migration implementation, shared release branch, benchmark or CI workflow is modified by this integration.
2026-09-06 21:33:35 +08:00
Tianyi Cui 5c8e1b53de Merge latest master into fix/ci-node-compile-cache-data-disk 2026-09-06 21:26:37 +08:00
Tianyi Cui 1439887241 fix(ci): keep PR temporary files under runner cleanup 2026-09-06 21:24:09 +08:00
Tianyi Cui 5f2c676581 test(cli): author native v3 inheritance replay fixture 2026-09-06 21:19:41 +08:00
Tianyi Cui a4dcff874e fix(scripts): validate historical fixture layout with source codecs 2026-09-06 21:18:49 +08:00
Tianyi Cui 83b11feb70 Merge pull request #3635 from deepseek-harness/session-v3/ptc-durable-vocabulary
feat(session): 在 V2→V3 中迁移 PTC 持久化词汇
2026-09-06 21:18:26 +08:00
Tianyi Cui 2890cf3a18 docs(replay): regenerate catalog after removing notification shim
Keep the generated configuration source pointers aligned with the smaller replay module. No configuration semantics or public runtime behavior changes.
2026-09-06 21:16:39 +08:00
Tianyi Cui b47bfa711b test(session): pin structural v3 chain expectations 2026-09-06 21:12:50 +08:00
Tianyi Cui ab74a93ed3 test: compare current notification outputs without legacy migration shim 2026-09-06 21:11:39 +08:00
Tianyi Cui 449fb9c71e docs(notes): remove duplicate promoted system-prompt proposal
The implemented owner at .agents/notes/implemented/architecture/2026-09-02-system-prompt-as-surface-node.md retains the decision, alternatives, consequences, and verification. Remove only the reintroduced pre-promotion triplet under the lifecycle rules in .agents/notes/README.md; the dependent feature proposal already links to the implemented owner. No proposal archival or body rewrite is needed.
2026-09-06 21:06:54 +08:00
Tianyi Cui cfc10f7e1f test(session): keep migration assertions type-aware
Treat Vitest asymmetric matchers as unknown expected values and spell void assertion callbacks explicitly. This preserves the migration identity and refusal checks under the full type-aware lint configuration without relaxing validation or suppressing a rule.
2026-09-06 21:00:21 +08:00
Tianyi Cui e9957a2671 test(python): record native V3 delivery provenance
Regenerate advanced and restart expectations through the shipped macOS arm64 SEA runtime built from 0521815d45. Real delivery-accepted events now record sessionFormatVersion 3 in the five V3 logs and advanced SDK notifications. Restart result.json and requests.json regenerate identically. Preserve all five V2 predecessors byte-for-byte from b2b300f9; no production, migration, launcher, or test changes.

Evidence (macOS arm64): pnpm exec tsx scripts/build-exe-for-python-sdk.ts --targets node24-macos-arm64 passed, including the full pnpm build. file dist-exe/deepseek-harness-sdk-runtime-macos-arm64 reports Mach-O 64-bit executable arm64.

For each SCENARIO=sdk-snapshot,sdk-restart: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=python/sdk/src:python/sdk-runtime/src /Users/cty/dsh-deploy/.agents/worktrees/sp-kv-sdk-evidence/tmp/py-sdk-venv/bin/python scripts/smoke-python-runtime.py --exe dist-exe/deepseek-harness-sdk-runtime-macos-arm64 --scenario SCENARIO --update-snapshots passed; the same two commands without --update-snapshots passed.

PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=python/sdk/src:python/sdk-runtime/src uv run --no-project --python /Users/cty/.local/share/uv/python/cpython-3.14.5-macos-aarch64-none/bin/python3 --with pytest --with pydantic>=2.12,<3 python -m pytest python/sdk/tests/test_smoke_model.py -q: 28 passed. Earlier helper invocations lacked pytest or SDK imports; corrected environment passed without source changes. git diff --quiet b2b300f9 -- scripts/snapshots/python-sdk-single-exe/**/*.v2.jsonl and git diff --cached --check passed.
2026-09-06 20:58:57 +08:00
Tianyi Cui 49e1050092 fix(session-format): narrow repair identities for native validation
Require a string call identity before constructing the private repair-validation prefix; do not stringify arbitrary durable JSON. Remove a redundant narrowed version comparison and use explicit void test callbacks.

Verified full type-aware package Oxlint (90 rules), all 71 focused cases with 100% exact V3 statements/branches/functions/lines, and host TypeScript build. No coverage ignores or broad lint exceptions.
2026-09-06 20:58:57 +08:00
Tianyi Cui 9e5f8a1e44 test(session-format): cover V3 durable admission branches
Exercise malformed source envelopes, feedback metadata, file attachments, native system ownership, protected head replacement, started versus repaired tools, dangling coordinate mappings and successful compaction ranges. The focused package suite now has 71 cases with exact V3 source coverage at 100% statements, branches, functions and lines.

Remove unreachable rechecks after owned payload validation instead of adding artificial tests or coverage ignores. Unseeded inherited markers already fail at arrival; message arrays and IDs are validated before observation. Bind the unchanged frozen decoder run callback without an unreachable wrapper.
2026-09-06 20:58:57 +08:00
Tianyi Cui 5c48f8101a test(session): retain positive predecessor migration lifecycle coverage
Construct supported historical inputs with the first surface inside step/start instead of weakening publication, singleflight, packed-row, and read-handoff assertions into refusal cases. Account for the inserted empty system head and shifted event sequence when V2 rows become V3; preserve exact native V3 expectations and original source bytes.
2026-09-06 20:52:37 +08:00
Tianyi Cui 6579d53a97 test(sdk): preserve current V3 output and shared-base message spacing
Keep structural system-message V3 recordings when taking the release branch spacing fix, rather than reintroducing retired header.system snapshots. Refresh native SDK delivery evidence and the retained multi-turn writer oracle; historical V2 inputs remain byte-for-byte inherited from the release base. Document generation-aware fixture storage checks so current child invariants stay enforced without rewriting retired historical roles.
2026-09-06 20:51:27 +08:00
Tianyi Cui 8f48afe851 test(session): record native V3 writer oracles without rewriting history
Retained V0/V1 fixtures remain replay inputs while writer.expected JSONL records the actual current V3 output. Record these through the shipped headless scenarios rather than reverse-normalizing system messages back into historical headers. Preserve generation-qualified reference provenance, and correct the unreleased PowerShell seed to start its step and protected system head before user surface input.

Validation: the structural migration, real persistence, corpus and snapshot-support gate passed616 tests with one intentional skip; all91 headless refresh cases pass after the audited assistant-attempt source handling. Every predecessor path remains restored to the shared V3 base, and generated changes are confined to V3/output oracles and current tool schema pins.
2026-09-06 20:45:00 +08:00
Tianyi Cui ab7f19cd3d test(session): refuse frozen pre-step fixture at current open
Current V3 promotion must preserve chronology, so historical user surfaces before the first step are unsupported. Assert refusal for read and write opens, preserve source bytes and identity, and forbid intermediate or current publication. Frozen codec validation remains in its existing owner tests; V2 no-downgrade coverage lives in v2-system-migration.spec.ts.
2026-09-06 20:45:00 +08:00
Tianyi Cui c09ca68e6f test(session): pin deliberate historical corpus refusals
Keep supported generations and native V3 restoration mandatory. Enumerate only chronology-preserving migration refusals by source path, generation and exact typed reason; retain headerless harness protocol examples separately. Verify source bytes remain unchanged and reject stale, widened, or current-generation exceptions.
2026-09-06 20:45:00 +08:00
Tianyi Cui 3d898cb954 test(session): cover V2 system prompt persistence migration 2026-09-06 20:45:00 +08:00
Tianyi Cui d551f5a118 test(session-snapshot): pin migrated empty system head 2026-09-06 20:45:00 +08:00
Tianyi Cui e6499cd2cc test(session-snapshot): preserve historical retired fixture roles 2026-09-06 20:45:00 +08:00
Tianyi Cui 6f5fc05ea3 fix(session-format): admit audited V2 corpus payloads
V2 assistant attempts have no V0 semantic dispatch case: validate their exact V2 members and positive step coordinates locally while preserving the embedded stream. Explicitly classify agent-message relay attribution and file attachment metadata; both preserve foreign identities and non-Session byte counts, and reject unknown members.

Native V3 request headers retain current extension fields while rejecting retired header.system, independently of the closed V2 migration inventory. Add direct and multihop attempt regressions, exact source/file negative cases, and native header roundtrip coverage. All 41 focused tests and host tsc pass; scoped lint and bilingual pairing pass.
2026-09-06 20:45:00 +08:00
Tianyi Cui 9fa3c8e7f6 build(session): link V3 source-validation dependency
The structural V2-to-V3 edge reuses the frozen V0 payload and relationship helpers through their public package exports. Record the explicit workspace dependency so clean installs resolve the same validation code without editing a released migration package.
2026-09-06 20:45:00 +08:00
Tianyi Cui e04cfc4c87 feat(session-format): migrate V2 prompts into V3 system surfaces
Stream an empty protected head after the first step and replace it before changed or cleared request headers, without moving source events. Remap only audited local sequence references, derive inherited cuts after upstream cardinality changes, and preserve generation-qualified captures and message identities.

Refuse pre-step surfaces and out-of-step prompt changes rather than invent lifecycle events. Reject unclassified migration payloads and detect deterministic generated-ID collisions in either source order. Native V3 accepts empty and in-history system messages, protects only the head, and reuses frozen relationships through a private nonescaping projection; historical repair IDs remain opaque.

Keep released codecs untouched and distinguish migration admission from native extension admission. V3 structural payload preflight cannot disappear behind recoverable row corruption. Validation: 35 focused tests, host TypeScript build, focused Oxlint, documentation quick gates and paired README recording. Parent owns installed-core/catalog/persistence integration and lockfile propagation.
2026-09-06 20:45:00 +08:00
Tianyi Cui 9efabace86 docs(snapshot): separate historical inputs from V3 writer oracles
Keep retained canonical generations selected for replay and compare native V3 output against dedicated writer expectations. Remove the reverse historical projection claim; official migration correctness remains independent of native event layout.
2026-09-06 20:45:00 +08:00
Tianyi Cui a592e70ebc test: compare packed history using its released codec expansion 2026-09-06 20:45:00 +08:00
Tianyi Cui 1a9bef60c2 test: separate native V3 writer expectations from historical replay 2026-09-06 20:45:00 +08:00
Tianyi Cui 19fdc37448 docs(session): define V3 system-head migration guarantees
Record order-preserving structural conversion and strict refusal instead of an identity edge; distinguish native writer layout and local references from historical delivery facts. Keep released generations frozen and one evolving unreleased V3 target, with canonical envelopes composing afterward.
2026-09-06 20:45:00 +08:00
Tianyi Cui 8cdc6eba02 test(session): preserve released fixtures with corrected V3 successors
Restore all 147 historical canonical fixtures changed by the lower branch to exact shared base 220ff708e3628a9be46d9747d09af6d8cd742f0d bytes (145 V2 and two V0). All 180 committed V0/V1/V2 canonical files now have zero diff against that base, including unchanged Python, test-support and preview sources.

Preserve corrected lower writer bodies in 146 V3 successors across 119 owner directories: replace 135 unreleased V3 counterparts and add 11 siblings. Change only each copied Session header version; preserve all body bytes, raw model streams, inline images, IDs, references and historical delivery generation markers. Remove two unshipped V2 additions after creating their V3 sibling: record-suite/rec-pin and empty-response-retry-current.

Keep six explicitly historical snapshot owners pinned with no V3 sibling. Restore the two pre-step V0 record child sources without synthesizing current output. Fix seven embedded Session header versions in exactly five test-support behavior owners whose output filenames already select V3. Leave protocol expectations, shared references, sidecars, consumer scripts and production migration/normalization code untouched.

Validation: purpose-built temporary Python inventory and verifier checked 337 canonical headers, 3714 successor JSON rows, message roles, contiguous child roles, exact successor bodies, all 180 historical base bytes and zero git diff, noncanonical JSONL immutability, six retained owners and six unchanged preview fixtures. git diff --cached --check passed. Temporary generators removed. Strict migration, native refresh and replay remain pending parent integration; unsupported pre-step sources are reported separately.
2026-09-06 20:45:00 +08:00
Tianyi Cui 7af8a596ce test(llm-pi-ai): keep rejection assertions type-safe
Use a typed expected failure object and the current toThrow matcher in the new leading-system-image regression. This preserves the rejection test while avoiding deprecated matcher and unsafe-any diagnostics from the full type-aware lint gate.
2026-09-06 20:44:39 +08:00
Tianyi Cui eba829784b fix(token-meter): invalidate header-based breakdown caches
Address ds-review-bot thread 3921300994 (PRRT_kwDOS3Pfcs6eyLsu). contextBreakdown now folds system/message instead of request/header.system, so version-2 checkpoints have different semantics even though their numeric fields still pass the current schema. Bump the lower projection to stateVersion 3 so cache-only reads omit old values and restore replays the full log; derived caches are not covered by the Session-log persistence compatibility waiver. No migration or fallback is added.

Regression seeds a schema-valid v2 row at the current watermark with stale system/message prices. Before the bump, cache views returned it, restoreFloor selected seq 2 rather than 0, and restore retained system=0/message=17 instead of system=8/message=9. After the bump, the 13-test owning suite passes and exact src/breakdown-projection.ts coverage is 100% statements, branches, functions, and lines; refreshed rows equal a fresh fold at version 3. Existing token-meter README prose documents the current system/message fold without a version literal, so it needs no edit.

Propagation requirement: the upper layer already uses version 3 for a different compact cache representation. Advance that layer to version 4 when propagating this fix to avoid assigning one version to two schemas.
2026-09-06 20:44:39 +08:00
Tianyi Cui 454b80b90e fix(llm-pi-ai): reject leading system images before splitting
Address ds-review-bot thread 3921300999 (PRRT_kwDOS3Pfcs6eyLsz). The synchronous conversion removed a leading system message before its image check, silently discarding image-only, mixed, and nested image content. Reuse assertSupportedImageRoles on the unsplit history, matching the image-aware path without changing text prompt precedence or user-image storage requirements.

Regression: all three leading-system image cases failed against 8082f4a950 (expected rejection, received a context). The focused context suite now passes 20 tests, including both conversion paths, no attachment reads on rejection, empty/text leading prompts, later systems, and explicit options.system precedence. Exact src/context.ts coverage is 100% statements, branches, functions, and lines. Updated the paired README limitation and synchronous JSDoc.
2026-09-06 20:44:39 +08:00
Tianyi Cui fe2ac749b9 test(web): refresh plan and goal recorded session metadata
These two current fixtures already contain system/message, so searching
only for stale request/header.system misses their persisted replay drift.
Both omit the shipped standard agentPreset. Plan exit must replace the
first system message (sequence 10), not append a second system prompt.
The Goal fixture's first get_goal result must reference its own tool call
at sequence 18 rather than the preceding bash call at sequence 16.

Refresh both owning browser scenarios. Retain the writer's canonical
embedded Assistant stream packing and refreshed timing where repacking
requires it. Expanded stream chunks, all 44 user/model/tool messages and
calls, and the deliberate shuf command failure remain unchanged. The
plan title remains before request/header on this lower branch. No UI,
runtime, normalizer, test-driver, or frozen v0/v1 files change.

Evidence at lower d29574fed9, reusing the dedicated tree's own prior build
(the intervening subagent spacing edits do not affect these owners):
- DSH_SNAPSHOT=replay pnpm exec vitest run --config vitest.web.config.ts apps/web/tests/{plan-review,goal-multi-turn-actions}.e2e.ts: before refresh, both owners failed persisted-session comparisons.
- DSH_SNAPSHOT=refresh pnpm exec vitest run --config vitest.web.config.ts apps/web/tests/{plan-review,goal-multi-turn-actions}.e2e.ts: 2 files passed, 4 tests passed, 1 record-only test skipped (10.24s).
- DSH_SNAPSHOT=replay pnpm exec vitest run --config vitest.web.config.ts apps/web/tests/{plan-review,goal-multi-turn-actions}.e2e.ts: 2 files passed, 4 tests passed, 1 record-only test skipped (10.24s).
- JSON payload comparison: all 44 messages/calls and expanded chunk content
  across all 14 Assistant streams preserved; stream timing is excluded.
- git diff --check passed; only the two current session.v2.jsonl files changed.
2026-09-06 20:42:44 +08:00
Tianyi Cui f92eff58e0 test(web): align seeded expectations with resumed system prompts
Require exactly two System prompt controls for the unchanged-header resume fixture, and pin the repeated prompt in both collapsed and expanded subagent history. Keep all branch eligibility, disabled action, cancellation, disclosure, and inventory assertions intact.

Refresh stale July 25 clocks only where canonical fixture createdAt=0 already selects the seedSession near-now anchor. Preserve nonzero historical timestamps and the existing normalizer: do not conceal calendar differences globally. Update navigation read paths to the recorded workspace subdirectory and omit decode throughput for the zero-duration Bash cancellation stream.

Evidence: own frozen install and full build; baseline eight-file replay 10 failed, 37 passed, 3 record skips plus stale question teardown; six-file ARIA refresh 36 passed, 2 record skips; final read-only eight-file replay 47 passed, 3 record skips after separately authored Web fixture prerequisite eaa5277d82. Baseline exact count rejected 2 versus 1 and old date/prompt goldens rejected actual output. No Session generation, helper, runtime, or normalization edits in this commit. Live/question source mismatch is repaired solely by the prerequisite; their passing ARIA and skill goldens stay unchanged.
2026-09-06 20:42:44 +08:00
Tianyi Cui ae2be09813 test(web): refresh stale system-message session fixtures
Fourteen current Web v2 fixtures still store the system prompt in
request/header.system and omit system/message. The built Cordis owner
passes its five behavior assertions but fails persisted-session replay.
Refresh thirteen owning recorded scenarios and update the authored pwsh
seed input to carry the same system text as a message event.

Keep the lower branch's title-before-header order. Preserve all 90
user/model/tool messages and all 35 recorded Assistant streams, including
timing. Only the system event, header field removal, message identifiers,
and their sequence references differ. Frozen v0/v1, UI goldens, runtime,
and normalizers remain unchanged.

Evidence on macOS, base 8d66f7c917:
- pnpm install --frozen-lockfile && pnpm run build: passed.
- DSH_SNAPSHOT=replay pnpm exec vitest run --config vitest.web.config.ts apps/web/tests/cordis-tool-round.e2e.ts: before repair, persisted replay failed after 5 behavior tests passed.
- DSH_SNAPSHOT=refresh pnpm exec vitest run --config vitest.web.config.ts apps/web/tests/{approval-composer,cordis-tool-round,feedback-command,file-upload-round,replay-round-trip,lifecycle-chrome,live-interactions,permission-policy-context,ptc-round,question-composer,steering,turn-tail-actions,web-search-round}.e2e.ts: 13 files passed; 71 tests passed, 2 record-only tests skipped.
- PATH="/tmp/pwsh:$PATH" DSH_SNAPSHOT=refresh pnpm exec vitest run --config vitest.web.config.ts apps/web/tests/pwsh-terminal.e2e.ts: 2 tests passed with existing PowerShell 7.4.6.
- PATH="/tmp/pwsh:$PATH" DSH_SNAPSHOT=replay pnpm exec vitest run --config vitest.web.config.ts apps/web/tests/{approval-composer,cordis-tool-round,feedback-command,file-upload-round,replay-round-trip,lifecycle-chrome,live-interactions,permission-policy-context,ptc-round,pwsh-terminal,question-composer,steering,turn-tail-actions,web-search-round}.e2e.ts: 14 files passed; 73 tests passed, 2 record-only tests skipped (102.62s).
- Exact base/current JSON comparison: all 14 files equal base plus the system event, header.system removal and deterministic ID/sequence remapping.
- No current Web v2 request/header.system remains; git diff --check passed.
2026-09-06 20:42:44 +08:00
Tianyi Cui 7901c6bc9c test(replay): type decoded fixture records without unsafe any
Give JSON.parse results in the unexpected-header regression their actual record type before searching by event tag. Preserve the forbidden-field oracle while satisfying the full type-aware lint rules; do not weaken lint or production parsing.

Validation: exact-head Linux artifact CI reported unsafe-return and unsafe-member-access in this regression. The owning replay suite passes after the local typed result correction.
2026-09-06 20:42:44 +08:00
Tianyi Cui 616803de74 test(session): verify the live session-query spill locator
Replace the replay's fixed temporary-root find command with the existing fromRequest capture of the preceding session_event_read result. Quote the exact returned file and use portable grep -Fq/printf checks; emit SPILL_CANONICAL_OK only after request/header and session_event_search are present. Preserve the owning layer's seq11 request/header target.

Before cleanup or fixture refresh, require both successful tool results and the exact verification marker, read the returned spill file independently, and compare its complete JSON to the live request/header event. This prevents accepting a failed verification transcript or an unrelated/incomplete spill after event ordering changes. No runtime or error-text normalization changes.

Evidence: nonexistent recorded-root negative control fails at the marker assertion (bash exit 2 still carries isError:false). Focused keyless refresh, read-only source replay, built-profile replay, corpus ownership guard, and focused driver lint pass. Host/client library builds pass. Portable POSIX command reviewed; Linux CI remains the platform confirmation.
2026-09-06 20:42:44 +08:00
Tianyi Cui 77b6b10c21 fix(ui-chat): preserve prompt cards on resumed requests
A resume header starts a visible request series even when the system node text is unchanged. Include resume in the request-prompt visibility predicate so full history and an older-page prepend retain the restart card. Keep startsSeries handling and existing regression assertions unchanged; align the local JSDoc and README pair.
2026-09-06 20:42:43 +08:00
Tianyi Cui 237ed693c1 test(session): adapt upstream spill fixture to system surface node
Carry the newly merged current-writer spill recording through the representation change on its owning PR. Add the system surface message and remove header.system, while retaining the representation layer title-before-request order and every captured spill/source fact. The dependent admission PR separately records its changed title scheduling.

Validation: JSON records parse; the same recorded scenario was refreshed through the built integrated loop. Only layer-specific title order differs, and both variants are replayed before publication.
2026-09-06 20:42:43 +08:00
Tianyi Cui af07d59d10 test(session-reference): capture the actual pre-spill watermark
The source fixture now contains the system surface node, so a literal sequence13 no longer names its captured tail. Record the source watermark before saveText mutates the session and assert that exact independent observation. This continues proving the spill uses the pre-mutation capture without coupling the test to unrelated fixture event counts.

Validation: the newly merged upstream regression failed with expected13 versus actual14; the session-reference suite passes with the captured watermark assertion.
2026-09-06 20:42:43 +08:00
Tianyi Cui 1616c99dae test(snapshot): expect rejection of invalid historical citations
The historical-comparison negative control replaces title.messageSeqs with [0], which cites a non-human event. The current Session validator correctly rejects this before normalization; comparing the malformed result for inequality made the otherwise passing built snapshot lane fail.

Assert the specific earlier-human-message validation error for that malformed control. Keep the valid prompt and model difference comparisons, every citation field, and all production restoration and normalization logic unchanged.

Validation: full DSH_EXAMPLE_MODE=lib DSH_SNAPSHOT=replay pnpm exec vitest run --config vitest.snapshot.config.ts reproduced the lone negative-control failure, then passed all 6 files and 126 tests after repair (2 existing PowerShell availability skips). PATH used the existing uv Python 3.14.5 bin; no software installed.
2026-09-06 20:42:43 +08:00
Tianyi Cui b4d8a31ae8 test(session-snapshot): regenerate current rec-pin recording
The committed current rec-pin fixture held only request/header, so the corpus restore gate rejected it outside an open turn. Its owning scripted behavior already emits turn/start, step/start and the system surface message.

Regenerate the selected current fixture with ACP_SNAPSHOT_SPEC_BOOTSTRAP=1 and the focused rec-pin record test. Keep all retired parent and child generations unchanged. No parser, normalizer or production behavior changes.

Validation: the corpus restore test reproduced the missing-turn failure; documented owner bootstrap passed; pnpm exec vitest run packages/test-support/llm-replay/tests/session-format-corpus.spec.ts packages/test-support/session-snapshot/tests/suite.spec.ts passed (141 tests, one intentional skip).
2026-09-06 20:42:43 +08:00
Tianyi Cui dac85fada1 test(session-snapshot): close pin-turn step before replacement
The current Session relationship validator correctly rejects a second step/start while the previous step remains open. Both replay and refresh of the synthetic pin-turn scenario failed after the stricter master validation landed.

Add the missing step/end to the owning scripted behavior and resequence its later events. Regenerate only the current pin-turn fixture through defineAcpSnapshotSuite refresh mode. Preserve both system messages, replacement provenance, and all three request headers; do not relax migration validation or normalization.

Validation: reproduced both pin-turn failures with the focused suite filter; owning refresh passed; pnpm exec vitest run packages/test-support/session-snapshot/tests/suite.spec.ts passed (140 tests, one intentional record skip). Full build and doc-sync also passed before this fixture-only repair.
2026-09-06 20:42:43 +08:00
Tianyi Cui eba45d9add fix(rebase): preserve the complete replay plugin after migration API merge
Retain installLlmReplay, Config validation and apply when resolving the streaming migration API change. The representation layer requires no replay plugin source changes, so restore its complete current-master implementation rather than a truncated conflict fragment. Capability additions remain exclusively in the dependent feature layer.

Validation: the restored source is byte-identical to origin/master and the replay unit suite passes. The initial normal commit hook failed because this detached worktree had no dependency links; pnpm install --frozen-lockfile installs them before retrying the unchanged hook, without bypass.
2026-09-06 20:42:43 +08:00
Tianyi Cui db5e57347b fix(snapshots): separate historical replay inputs from current header pins
The default and retry header pins were retained pre-system-node logs, so preserving their historical header.system correctly exposed stale expectations across headless and shared SDK compositions. Move the default pin to tool-call-turn and add a current retry companion; retain every committed predecessor and keep readable sidecar ownership on text-turn.

Replace the historical blanket body-comparison skip with a headless-only semantic projection: current system nodes contribute historical header.system and event citations follow retained positions. Full normalized logs still compare, current-writer logs stay unadapted, and independent prompt/header checks remain strict. Negative controls preserve prompt, model and citation differences. Refresh only pi-ai metadata and Web minimal-preset current artifacts; no SDK outputs, Python fixtures or package oracles changed.

Validation: 18 focused headless/SDK/corpus tests; three pin, sidecar and historical mutation controls; Web minimal-preset persisted replay; focused oxlint; typecheck and client/Web builds. doc-sync:31 passed,2 failed on pre-existing token-meter/Cordis and config catalog freshness; no broad catalog rewrite. Full suite, browser interaction and platform matrix not rerun.
2026-09-06 20:42:43 +08:00
Tianyi Cui 0a02da4ba6 docs: regenerate catalogs for corrected prompt ownership
Regenerate source-owned catalogs after the oracle simplification and usage-anchor correction. The configuration catalog retains the same declared options while its source location follows removed compatibility stripping; the token-meter service docs now state that the usage anchor includes all admitted request inputs. Keep bilingual generated declarations aligned instead of retaining stale copied contracts.

Validation: pnpm run doc-sync identified only cordis catalog and config catalog freshness failures (31 other gates passed); pnpm run gen-cordis-catalog and pnpm run gen-config-catalog regenerated their owners, and the config pair was updated and recorded. Full layer documentation validation follows integration.
2026-09-06 20:42:43 +08:00
Tianyi Cui 4c9f5efc07 fix(agent-loop): reserve the initial empty system head
Cause: SystemPromptProjection skipped the first empty rendered prompt. The initial admitted user then occupied surface node zero, so a later nonempty prompt appended behind user history. Routes without in-history system support lost the leading system role; pi-ai demotes a non-leading system message to user content.

Fix: append the initial system node even when its content is empty. The existing loop commit order reserves node zero before admitted user messages; later prompt text replaces that node. Empty content still derives to no wire message. Keep retained-node replacement, clearing, multi-system handling, and pi-ai conversion unchanged; this addresses only the reviewed PR3476 initial-empty finding, not PR3483.

Tests: added initial-empty projection and two-turn loop regressions for empty wire output, reserved surface head, later leading system role, replacement intent, and series header. Negative control failed before the source fix. Focused projection/runtime-context/loop/request-reconstruction/session-surface/pi-ai-context suites passed 176 tests; exact runtime-context.ts coverage is 100% statements, branches, functions, and lines. test:docs passed all 15 gates. Updated README EN/ZH, architecture map and owning architecture note; recorded all three translation pairs. Broad doc-sync/lint stopped at parent request for combined-layer validation. No normalize.ts conflict-comment edit.
2026-09-06 20:42:43 +08:00
Tianyi Cui c29b97ad94 test(python): refresh system-node and packed restart expectations
The representation PR left child and restart recordings in the old header-system representation while the packaged writer emits system/message before entered user messages. Restart result expectations also retained standalone assistant/chunk notifications after the writer moved stream records into assistant/message. These are stale expected artifacts, not fields to erase in normalization.

Regenerate the owning advanced and restart scenarios through the native macOS ARM64 packaged dsh runtime. Retain messages, tool effects, typed feedback and packed streams; update only the missing system nodes and their sequence references, and remove obsolete standalone chunk notifications. The advanced parent result and parent session already match the writer after the rebase, so this commit changes only two child logs and the restart result/logs.

Validation: pnpm run build; pnpm exec tsx scripts/build-exe-for-python-sdk.ts --skip-build --targets=node24-macos-arm64; uv run --project python/sdk python scripts/smoke-python-runtime.py --scenario sdk-snapshot --exe dist-exe/deepseek-harness-sdk-runtime-macos-arm64 and the equivalent sdk-restart command each reproduced the mismatch, then passed with --update-snapshots and again without it. Both read-only reruns pass. Other native targets remain covered by exact-head CI.
2026-09-06 20:42:43 +08:00
Tianyi Cui 3607b320c7 test(snapshot): repair recorded child system message UUID
The rec-child fake-agent behavior used an 11-digit UUID tail for both copies of its shared system message. Supply the missing digit in both places without changing their identity relationship. This semantic correction is separate from the preceding five-file formatting-only change.

Add a focused owner-fixture assertion requiring two matching complete v4 UUIDs. It fails on the original short tail and passes after repair. Evidence: pnpm exec vitest run packages/test-support/session-snapshot/tests/suite.spec.ts: 140 passing, one intentional record-mode skip, including replay/record/refresh and UUID validation. No expected-output refresh or normalization change is needed.
2026-09-06 20:42:43 +08:00
Tianyi Cui bba5ec5f7a style(snapshot): restore one-event-per-line behavior fixtures
Compact each logged event onto one line in exactly five owner-local fake-agent behavior fixtures: record-suite rec-child/rec-pin and suite pin-turn/plain-turn/shared-pin. Keep wrapper structure readable so event sequencing and payload changes remain reviewable without hundreds of formatting-only lines.

Evidence: node deepStrictEqual compares parsed working-tree JSON against HEAD for all five changed files, with exactly five paths asserted; all semantic values and ordering are identical. git diff --check passes. The malformed rec-child UUID is deliberately retained here for a separate semantic repair commit. The unchanged fixture behavior passed the preceding suite.spec.ts run (139 passing, one intentional skip). No snapshot refresh was run.
2026-09-06 20:42:43 +08:00
Tianyi Cui e8e0ec4176 docs(snapshot): remove stale prompt scrubber conflict residue
Delete the leftover diff3 parent marker and both copies of the obsolete request-header prompt JSDoc. Keep only the current system/message tokenization contract. This is a local comment-only finding; neither oracle behavior nor fixture content changes.

Evidence: git diff --check is clean; focused normalize.spec.ts scrubSystemPrompts test passes (1 selected, 64 skipped). The earlier header-preservation commit intentionally retained this marker so the findings stay independent.
2026-09-06 20:42:43 +08:00
Tianyi Cui 7b182e95e1 fix(snapshot): enforce fixture storage for every selected role
sessionFixtures already selects the highest generation independently for each parent or child role. Filtering its output to files[0] silently exempted every child from prompt and schema fixed points and prompt-before-request ordering. Merge those assertions into the per-role loop and expose the actual checker for focused negative controls without mocking Vitest registration.

The three selected-child controls reject missing system/message, raw prompt text, and raw tool schemas; each resolved incorrectly with the parent-only filter. A positive mixed-generation case proves retained predecessors remain unselected. Correct the two versionless record-suite child fixtures that the restored enforcement exposes, including the retired-child copy used by recording tests. No released historical generation or broad recording is rewritten.

Evidence: pnpm exec vitest run packages/test-support/session-snapshot/tests/storage-policy.spec.ts packages/test-support/session-snapshot/tests/suite.spec.ts --coverage --coverage.include=packages/test-support/session-snapshot/src/suite.ts: 143 pass, one intentional record-mode skip, suite.ts 100% statements/branches/functions/lines. Update and re-record the session-snapshot README EN/ZH pair.
2026-09-06 20:42:43 +08:00
Tianyi Cui 1adcd8203a fix(token-meter): anchor usage after admitted prompt inputs
The loop appends step/start before system/message and the entered user
messages. Capturing nodes at step/start therefore omits inputs already
included in the provider's successful usage, then adds those inputs back
as a positive surface delta. Prompt replacement can also incorrectly add
or subtract the difference from the prior prompt on a completed call.

Snapshot the current priced surface immediately before assistant/message
commits. Keep provider output separate from the durable assistant node so
listener rewrites retain their signed delta. The invariant is zero delta
immediately after an unchanged successful output: provider usage already
includes every admitted prompt input. Later appends/replacements still
produce signed deltas, and low or absent usage keeps heuristic fallback.

Delete stepStart.nodes rather than adding prompt-specific corrections or
another request snapshot: the existing transactional surface fold already
contains the successful request inputs, including replacements made during
same-step retry recovery. Keep turn/step state and all overlap, mismatch,
and late-assistant lifecycle validation. Retry attempts are log-only and
request middleware changes configuration; injected messages remain queued
until admission. No loop, event format, projection, or retry policy changes.

Exercise the real loop with reported usage and initial, growing, shrinking,
and empty prompts; same-step failed attempt plus retry prompt replacement;
request middleware; eager observation and fresh seeded replay. The two
regressions fail before the fix with spurious deltas of +48 and +18 tokens.
Retain existing durable-output rewrite, route repricing, missing/low usage,
transactional failure, and lifecycle tests. Update README EN/ZH and the
existing system-prompt surface-node Agent Note, including pairing records.

Validation (dedicated worktree, no full unit suite):
- pnpm exec vitest run packages/llm/token-meter/tests packages/compaction/compaction-basic/tests/compaction-loop-repro.spec.ts --coverage --coverage.include='packages/llm/token-meter/src/index.ts'
  118 passed; exact changed runtime file 100% statements/branches/functions/lines.
- pnpm exec vitest run packages/core/agent-loop/tests/request-reconstruction.spec.ts packages/compaction/compaction-basic/tests/compaction-basic.spec.ts packages/compaction/compaction-basic/tests/loader-composition.spec.ts
  118 passed, including retry reconstruction and real Loader composition.
- pnpm run doc-sync: 33 gates passed.
- pnpm run test:docs: 15 gates passed.
- pnpm run lint: passed, 0 warnings/errors.
- git diff --cached --check: passed.

Baseline normalize.ts comment conflict marker is intentionally untouched.
2026-09-06 20:42:43 +08:00
Tianyi Cui 8bde913784 refactor(compaction): replay the derived system head as a message
The session already derives the protected system head as a Message, and both adapters accept leading system history. Passing it through a separate SummarizationInput.system string unnecessarily flattens that value and rebuilds the same wire message in the adapter. Prepend the derived head to messages and remove textContent, the separate field, and GenerateOptions.system plumbing from the summarizer.

Keep range selection, shadowed seq accounting, session head protection, routed tools, image references, target policy, and the model-visible compaction instruction unchanged. Empty-content heads still derive to null and contribute no request message, but their surface node remains protected. Update subclass consumers/tests, EN/ZH package and subsystem prose, and the existing system-prompt surface owning note with refreshed pairing records.

Evidence: pnpm exec vitest run packages/compaction/compaction-basic/tests packages/llm/llm-deepseek/tests/serialize.spec.ts packages/llm/llm-pi-ai/tests/context.spec.ts --coverage --coverage.include='packages/compaction/compaction-basic/src/region.ts' --coverage.include='packages/compaction/compaction-basic/src/summarizer.ts' passed 203 tests in 6 files; both changed sources have 100% statements, branches, functions, and lines. Region-to-default-summarizer cases pin exact prefix and tools for nonempty Unicode/multiline, empty, and absent heads. DeepSeek JSON byte equality and pi-ai context equality pin leading-message vs separate-system equivalence on text and image-capable conversion paths.

pnpm run doc-sync passed all 33 gates including doc-typecheck, documentation build, translation pairing and model-experience checks. git diff --check passed. Own dependencies installed with pnpm install --frozen-lockfile. An initial test iteration used a nonexistent ctx.dispose teardown on the in-memory fixture; corrected to its existing fixture lifecycle and reran successfully. No runtime/model behavior, normalizer marker, main worktree, push, or rebase changes.
2026-09-06 20:42:43 +08:00
Tianyi Cui be53ea7dff fix(snapshot): preserve unexpected request header fields
Remove both unconditional header.system erasures from log normalization and replay comparison encoding, including the unrelated Session-header deletion. The catalog owns released-format migration; comparison must not turn an unexpected field into equality or supply a compatibility shim.

Add direct log/snapshot and catalog-restoration controls that retain unexpected request/header.system and differ from the field-absent fixture. Preserve malformed provenance data as well, closing the owned normalizer coverage gap. Update the two package README pairs with this oracle obligation.

Evidence: pnpm exec vitest run packages/test-support/session-snapshot/tests/normalize.spec.ts packages/test-support/llm-replay/tests/llm-replay.spec.ts --coverage --coverage.include=packages/test-support/session-snapshot/src/normalize.ts --coverage.include=packages/test-support/llm-replay/src/index.ts: 205 tests pass, both files 100% statements/branches/functions/lines. Direct normalizer negative control fails before the fix. Baseline diff3 comment remains untouched for the separate cleanup finding.
2026-09-06 20:42:43 +08:00
Tianyi Cui ee956c720d refactor(session): represent the system prompt as surface node zero
Consolidate the representation-change PR and its rebase reconciliations into one baseline. Preserve the exact tree and keep the in-history feature in the dependent PR. Follow-up fixes remain separate.
2026-09-06 20:42:43 +08:00
Tianyi Cui 40792330c0 fix(system-prompt): keep model persona prefix and place cwd in suffix 2026-09-06 20:35:42 +08:00
Tianyi Cui 1dc50c492e fix(ci): harden Python runtime builds against transient failures
Master's windows-python-console-spawn-wait fix removed the plugin-add flake
this branch previously retried, so that retry is dropped entirely; the
branch keeps the changes that remain useful.

- Retry the immutable install step up to three attempts total with a
  ten-second pause (bash on every platform): node-gyp's Node-header
  download from nodejs.org intermittently times out, as observed on the
  hosted node24-macos-x64 cell.
- Keep checkout credentials out of the build tree (persist-credentials:
  false) so dependency-install scripts cannot read the embedded token.
- Failover runbook: drop the stray leading '#' before the Dependabot
  paragraph on both sides.
- Hosted-runtime note: name the PR/commit ownership and UTC timestamps of
  the cited runs and record the constraints a future self-hosted attempt
  must satisfy; new note records the install retry decision.
2026-09-06 20:31:01 +08:00
Tianyi Cui 3cc05093d2 Merge commit 'b2b300f9d5a5df24966a313bd5f9139620c1ae7b' into session-v3/ptc-durable-vocabulary 2026-09-06 20:25:31 +08:00
Tianyi Cui 573485e8b5 fix(snapshots): align V3 subagent message spacing 2026-09-06 20:23:43 +08:00
Tianyi Cui 320354a8e0 Merge commit 'adb605ba17936187320cac20bb145d4ee1edb387' into session-v3/ptc-durable-vocabulary 2026-09-06 20:22:48 +08:00
Tianyi Cui 6d11955852 Merge remote-tracking branch 'origin/master' into release/session-log-v3 2026-09-06 20:20:16 +08:00
Tianyi Cui 6ac3258390 Merge pull request #3640 from deepseek-harness/ci/benchmark-standard-runner
test(ci): move required benchmarks to standard GitHub runners
2026-09-06 20:13:05 +08:00
Tianyi Cui e28862db57 fix(system-prompt): place environment facts after reusable instructions 2026-09-06 20:08:19 +08:00
Tianyi Cui 88e4c3c235 Merge master and preserve hosted benchmark documentation 2026-09-06 19:58:19 +08:00
Tianyi Cui 6f21b112da fix: wait for the Python console runtime on Windows 2026-09-06 19:53:23 +08:00
Tianyi Cui 50b0511fe1 Merge pull request #3466 from deepseek-harness/feat/system-prompt-surface-node-notes
docs(agent-note): propose system prompt as surface node and in-history replacement
2026-09-06 11:39:05 +00:00
Tianyi Cui 86528bb8a4 Merge pull request #3642 from deepseek-harness/fix/python-runtime-hosted-windows
revert(ci): run Windows Python runtime CI on GitHub-hosted Windows
2026-09-06 19:34:47 +08:00
Tianyi Cui 083cef0aea docs(notes): record hosted Windows runtime decision, retire the proposal
The failover runbook's Windows switch scope returns to the native Windows jobs:
remove the Python runtime eligibility sentences, the pool Python prerequisite,
and the proposal links. The #3629 self-hosted Python runtime proposal is
retired (deleted as obsolete after its unmeasured-throughput run), and a new
implemented note records that the Windows x64 runtime lane stays on
GitHub-hosted Windows with the evidence and alternatives. Bilingual sidecars
re-recorded.
2026-09-06 19:18:38 +08:00
Tianyi Cui 6933eccdb0 docs(notes): record hosted Windows runtime decision, reject proposal
The failover runbook's Windows switch scope returns to the native Windows jobs:
remove the Python runtime eligibility sentences, the pool Python prerequisite,
and the links to the proposal. The self-hosted Python runtime proposal is
moved to rejected with its unmeasured-throughput verdict, and a new
implemented note records that the Windows x64 runtime lane stays on
GitHub-hosted Windows with the reasons. Bilingual sidecars re-recorded.
2026-09-06 19:17:28 +08:00
Tianyi Cui faa33c0ffa revert(ci): run Windows Python runtime CI on GitHub-hosted Windows
Windows x64 runtime builds resolve their hosted matrix.runner unconditionally
again (windows-2025 for pull-request CI). Remove the DSH_CI_FAILOVER_WINDOWS
selector, job-private Python toolchain, self-hosted dependency install and
post-step cleanup, the private setup script, and the routing spec introduced
in #3629. The Windows failover switch again covers only the native Windows
jobs in ci.yml.
2026-09-06 19:17:27 +08:00
Tianyi Cui cd5e872bed Merge branch 'master' into ci/benchmark-standard-runner 2026-09-06 18:46:12 +08:00
Tianyi Cui 3bb63f9e4e Merge pull request #3632 from deepseek-harness/perf/speed-up-skill
docs(skills): add evidence-driven performance optimization workflow
2026-09-06 18:38:27 +08:00
Tianyi Cui e29b6528c3 docs(ci): list benchmarks among fixed hosted dependencies 2026-09-06 18:35:15 +08:00
Tianyi Cui 368ec64489 Merge corrected Session V3 base into PTC vocabulary 2026-09-06 18:29:14 +08:00
Tianyi Cui b74411d9b8 test(bench): calibrate reopen budget for standard two-CPU CI 2026-09-06 18:24:42 +08:00
Tianyi Cui e53df8b64a fix(session): guard V3 delivery activation and smoke writer generation 2026-09-06 17:39:15 +08:00
Tianyi Cui 5895f46b34 fix(session): preserve unsupported V3 events during tail recovery 2026-09-06 17:29:21 +08:00
Tianyi Cui f75aabcb16 test(ci): run required benchmarks on standard hosted Linux 2026-09-06 17:10:30 +08:00
Tianyi Cui ce2197aa1d docs(agent-note): propose system prompt surface and in-history updates
Consolidate the existing notes-only PR into one review baseline. Preserve the exact reviewed tree; subsequent corrections remain separate commits with their own rationale and regression evidence.
2026-09-06 16:52:38 +08:00
Tianyi Cui eaae3502ae test(session): synchronize shared migration cancellation waiters 2026-09-06 16:17:42 +08:00
Tianyi Cui eece831b18 Merge pull request #3629 from deepseek-harness/optimize/python-runtime-selfhosted
ci: move Windows Python runtime CI to isolated self-hosted jobs
2026-09-06 15:56:01 +08:00
Tianyi Cui d8d86b7eb8 Cover PTC dispatches through explicit TypeScript SDK profile patch 2026-09-06 15:37:15 +08:00
Tianyi Cui 000cd7e762 Merge master and reconcile platform failover documentation 2026-09-06 15:35:49 +08:00
Tianyi Cui eb4259e405 test(session): distinguish frozen PTC tags from current inventory 2026-09-06 15:31:46 +08:00
Tianyi Cui d15aaee271 Merge pull request #3627 from deepseek-harness/optimize/release-rehearsal-selfhosted
ci: route trusted release rehearsals to self-hosted Linux
2026-09-06 15:22:44 +08:00
Tianyi Cui 37d3ec1681 ci: address Windows runtime routing and isolation review 2026-09-06 15:07:17 +08:00
Tianyi Cui ed183b1bd1 Merge pull request #3630 from deepseek-harness/fix/agent-message-spacing
fix(subagent): add space after agent message prefix
2026-09-06 15:03:27 +08:00
Tianyi Cui a1188bbf3f ci: contain release temporary installs and document shared routing 2026-09-06 14:57:11 +08:00
Tianyi Cui ceb3136bef ci: size PR previews on measured standard hosted runners (#3628)
* ci: measure hosted preview runner sizes [preview-sizing-benchmark]

* ci: type benchmark job keys explicitly [preview-sizing-benchmark]

* ci: size PR previews on measured standard hosted runners
2026-09-06 14:56:30 +08:00
Tianyi Cui bad4254d71 Rename durable PTC vocabulary with identity-preserving v2 migration 2026-09-06 14:53:16 +08:00
Tianyi Cui 6cc750b006 docs(skills): route performance evidence through decision note 2026-09-06 14:50:53 +08:00
Tianyi Cui 7c3d47d4d6 test(subagent): refresh message spacing snapshots 2026-09-06 14:48:27 +08:00
Tianyi Cui 82ed067354 fix(session): synchronize V3 graph and preview fixtures 2026-09-06 14:34:42 +08:00
Tianyi Cui 7a1cf325b8 docs(skills): add evidence-driven performance optimization workflow 2026-09-06 14:14:30 +08:00
Tianyi Cui d56f2d2cb4 test(session): use explicit void callbacks in migration assertions 2026-09-06 14:11:49 +08:00
Tianyi Cui 4cacd5829d docs(session): register V3 migration in generated config catalog 2026-09-06 14:06:56 +08:00
Tianyi Cui 705f84f952 docs(session): document format upgrades and advance current V3 fixtures 2026-09-06 14:01:01 +08:00
Tianyi Cui f7a6221158 feat(session): add identity V2-to-V3 migration and writer skeleton 2026-09-06 13:52:21 +08:00
Tianyi Cui 3a79abedec ci: use UTF-8 Python text on self-hosted Windows 2026-09-06 13:49:19 +08:00
Tianyi Cui 754a65ab2d fix(subagent): separate message prefix from body 2026-09-06 13:47:37 +08:00
Tianyi Cui 69b1e315b4 ci: use isolated self-hosted Windows Python runtime builds 2026-09-06 13:21:26 +08:00
Tianyi Cui 81dcacbb44 Merge pull request #3537 from deepseek-harness/perf/03-client-stream-fold
perf: read embedded Assistant streams per compact record
2026-09-06 13:17:51 +08:00
Tianyi Cui f66dd78ff7 ci: route trusted release rehearsals to self-hosted Linux 2026-09-06 13:01:55 +08:00
Tianyi Cui 07245b9e88 docs(llm): scope the record readers' early-exit claims; state that readers trust the static record type
Reflect the review feedback on the reader list: assistantStreamFirstTokenTime and the has-visible readers stop at the first qualifying member, while lastAssistantStreamChunk, assistantStreamChunks, and joinAssistantStreamText scan the whole stream; assembleAssistantStream feeds a BlockAssembler one joined delta per run. Record-level readers trust the static record type; expandAssistantStream is the validating path.
2026-09-06 12:46:19 +08:00
Tianyi Cui 53c2ed9916 Merge pull request #3618 from deepseek-harness/fix/session-reference-spill
fix(session-reference): spill complete truncated snapshots for retrieval
2026-09-06 12:44:37 +08:00
Tianyi Cui 165cc31eb8 perf(llm,host): read embedded Assistant streams per compact record
Session format v2 embeds each attempt's compact stream in
assistant/message and assistant/attempt, but Host and client consumers
still expanded it into per-member TimedStreamChunk arrays and did
per-member work; expandAssistantStream materializes the full array before
find/toReversed/break can answer. Session Stats (the projection phase of
every Session open), the token meter's usage and provider-assembly folds,
the subagent output fold, and the Session Controller image lookup still
paid O(members) allocation and time per settlement.

The Chat and Trajectory definitions were already settled from
message.content on master; the remaining per-member folds stay.

dsh-llm now exports record-level readers (first token, visible content,
visible text, last raw chunk of a type, raw chunks of a type, joined
text, run-aware assembly, per-run first-token/first-visible times) that
scan the compact records once with early exit. Session Stats reads
assistantStreamFirstTokenTime, the token meter reads
lastAssistantStreamChunk(stream, 'usage') and assembles through
assembleAssistantStream, the subagent output fold appends
joinAssistantStreamText, and the Session Controller scans
assistantStreamChunks(stream, 'block-end').

expandAssistantStream is deliberately not memoized: retaining expansions
costs roughly ten times the compact stream for the Session's lifetime.
It remains the validating path at durable boundaries.

Synthetic 200-turn v0 migration benchmark, median of five: first-open
projection 28.0 ms -> 5.4 ms, first-open total 76.9 -> 50.0 ms, peak RSS
137.2 -> 94.9 MB; reopen projection 17.8 -> 5.6 ms; all phase budgets and
the 128 MB heap constraint keep passing.
2026-09-06 12:41:25 +08:00
Tianyi Cui e12ca5fdf0 test(session-reference): preserve complete regression suite after rebase 2026-09-06 12:17:12 +08:00
Tianyi Cui 539b5cd93d fix: normalize JSON-escaped Windows spill locators 2026-09-06 12:17:12 +08:00
Tianyi Cui 52475cbf50 fix: spill truncated session-reference captures for retrieval 2026-09-06 12:17:12 +08:00
Tianyi Cui 72ce6964ac fix(session-reference): retain fallback for adapterless routes 2026-09-06 12:17:11 +08:00
Tianyi Cui 36a3a1188d fix(session-reference): size default budget from selected model 2026-09-06 12:17:11 +08:00
imccyu 450d98b398 Merge pull request #3586 from deepseek-harness/session-migration-preparation
perf(session): prepare historical reads before publication
2026-09-06 02:35:49 +08:00
imccyu 80306f51a6 Merge pull request #3585 from deepseek-harness/session-migration-streaming
perf(session): stream released format migrations
2026-09-06 02:34:12 +08:00
Tianyi Cui 53066fd640 Merge pull request #3535 from deepseek-harness/perf/01-session-open-benchmarks
test(perf): gate opening large Sessions with synthetic CI benchmarks
2026-09-06 02:32:09 +08:00
imccyu 591d12ce86 docs(session): document preparation-first restoration 2026-09-06 02:10:28 +08:00
imccyu 9b78f99dec perf(session): transfer frozen persistence reads into restore 2026-09-06 02:10:23 +08:00
imccyu a3e5edbdbf perf(session-persistence): prepare historical reads before publication 2026-09-06 02:08:48 +08:00
imccyu 98d2baf2e5 docs(session): document streaming format migration 2026-09-06 02:06:22 +08:00
imccyu 84c11c7243 perf(client): avoid replaying settled assistant streams 2026-09-06 02:05:52 +08:00
imccyu ec2f63dbdb perf(session-persistence): stream migration publication and verification 2026-09-06 02:05:40 +08:00
imccyu 46196d6f95 perf(session-format): stream released v0-to-v2 migrations 2026-09-06 02:05:27 +08:00
imccyu a84a8da9e1 refactor(session-format): introduce streaming migration stages 2026-09-06 02:05:09 +08:00
imccyu a548150f86 test(perf): isolate benchmark dependencies 2026-09-06 01:01:04 +08:00
imccyu 422f5a19af test(perf): calibrate CI benchmark budgets 2026-09-06 01:01:04 +08:00
imccyu 356a332195 test(perf): run benchmarks against built artifacts 2026-09-06 01:01:04 +08:00
imccyu ec954d495e test(perf): freeze released benchmark rows 2026-09-06 01:01:04 +08:00
imccyu 47a6fa0f28 test(perf): centralize lifecycle benchmarks 2026-09-06 01:01:03 +08:00
Tianyi Cui c53b0bb5ed test(perf): double the CI cost in the migration budget
The migrating first open measured 1,963 ms on the CI runner under the
128 MB heap limit; 4,000 ms keeps a 2x margin while the repeated-snapshot
implementation still fails by heap exhaustion and would need ~10 s.
2026-09-06 01:01:03 +08:00
Tianyi Cui 3285850ee5 test(perf): allow the joined-text share in the fold scaling bound
A records-proportional fold still joins 20x more text in the large window,
which measured about 2.5x the small fold; the per-delta replay measured
about 11x. A 5x bound separates the two on a noisy runner.
2026-09-06 01:01:03 +08:00
Tianyi Cui 9048e8ee11 test(perf): size the migration budget for the CI runner
The migrating first open of the synthetic log costs about 1 s on the
reference machine under the 128 MB heap limit and about twice that on the
CI runner, so 3,000 ms keeps headroom while staying far below the ~5 s
(~10 s on CI) of the repeated-snapshot implementation.
2026-09-06 01:01:03 +08:00
Tianyi Cui 74e27c97d0 test(perf): list the bench config among proxy-setup Vitest inventories
scripts/test-proxy-environment.spec.ts pins the Vitest configs that declare
setupFiles so the proxy isolation setup is never dropped; the benchmark
lane declares it too.
2026-09-06 01:01:03 +08:00
Tianyi Cui 2395f112d8 test(perf): gate opening large Sessions with synthetic CI benchmarks
Add a benchmark lane (`vitest.bench.config.ts`, `pnpm run test:bench`,
gate mode `ci-bench`) and a required `node 24 / benchmarks` CI job that
runs it alone. Benchmarks synthesize their input in-process from fixed
parameters and fail on documented budgets:

- `open-generation.bench.ts`: a 200-turn released-v0 log with 500 text
  and 125 reasoning deltas per reply (127,400 events, ~2.8 MB) encoded
  through the frozen v0 codec; the migrating first `open()` must finish
  within 2,000 ms in a child process capped at 128 MB of old space, and a
  fresh process must open the published current generation within 500 ms.
- `conversation-fold.bench.client.ts`: 200 replies whose compact streams
  hold 2,000 text + 500 reasoning deltas each, folded through every Chat
  Definition by the real assembler; the fold must finish within 150 ms
  and stay within 3x the fold of the same window with 100 deltas per
  reply.

On this commit both gates fail: the migration exhausts the 128 MB heap
(4.8 s and 696 MB peak RSS without the cap; the pre-stack decode of the
same bytes took 34 ms and 168 MB) and the fold scales 11x with the delta
count. The stacked fixes bring both paths to O(records).
2026-09-06 01:01:03 +08:00
fz 40539e9002 Merge origin/master into feat/remove-str-replace-editor-from-minimal 2026-09-06 00:58:49 +08:00
Tianyi Cui cd4a23c5df Merge pull request #3529 from deepseek-harness/turtle/redesign-issue-pr-templates-policy
Redesign issue and pull request templates and simplify policy
2026-09-06 00:44:02 +08:00
fz 4acdf8e5bb Merge pull request #3611 from deepseek-harness/feat/sdk-disable-str-replace-editor
feat(base): remove str_replace_editor from default tools
2026-09-06 00:21:42 +08:00
Tianyi Cui a6e157c0a3 Merge pull request #3605 from deepseek-harness/fix/ptc-bash-cards
fix(web): show Bash terminal cards in PTC mode
2026-09-06 00:09:29 +08:00
fz 17d8507b87 Merge origin/master into feat/sdk-disable-str-replace-editor 2026-09-05 23:57:47 +08:00
Tianyi Cui cef72f2f27 fix(spill): publish notice through standard pure source entry 2026-09-05 23:52:59 +08:00
Tianyi Cui b25d4faaaa fix(spill): share persisted notice formatting with client recognition 2026-09-05 23:52:59 +08:00
Tianyi Cui 314cd13971 fix(web): keep spilled shell previews generic without guessing status 2026-09-05 23:52:59 +08:00
Tianyi Cui 739b38c973 docs(web): describe nested terminal details eligibility 2026-09-05 23:52:59 +08:00
Tianyi Cui 46a08db381 fix(web): render terminal cards for PTC bash subcalls 2026-09-05 23:52:59 +08:00
Tianyi Cui ce0a1e4253 Merge pull request #3368 from deepseek-harness/fix/directory-picker-win32-overread
fix(directory-picker-native): decode the Win32 picker path without a fixed 32KiB view
2026-09-05 23:51:08 +08:00
Tianyi Cui eae5c6b896 Merge pull request #3598 from deepseek-harness/feat/feedback-otel-fallback
feat(telemetry): submit explicit feedback through OTel for all users
2026-09-05 23:48:54 +08:00
fz 36a4665144 feat(base): remove str_replace_editor from default tools 2026-09-05 23:37:13 +08:00
Tianyi Cuiandzhanglunet 141d72d7cf fix(directory-picker-native): decode the Win32 picker path without a fixed 32KiB view
Replace the external ArrayBuffer view and manual UTF-16 scan with native Koffi decoding through a pointer-width buffer. Preserve the original address for CoTaskMemFree.

Exercise production resultPath with real Koffi decoding of live UTF-16 buffers. Cover zero-low-byte BMP characters, surrogate pairs, NUL termination, and strings exceeding 32 KiB; test four- and eight-byte BigInt pointer preservation and the original release address. A negative-control mutation confirms truncating a 64-bit address fails.

Keep the bilingual Agent Note focused on implementation rationale and required memory ownership. Preserve master archive seals during rebase.

Co-authored-by: zhanglunet <[email protected]>
2026-09-05 23:24:46 +08:00
Tianyi Cui 9ffe85a512 OTel uploads explicit feedback for all users by default 2026-09-05 23:21:23 +08:00
ChinesezjcandTianyi Cui 02a029e679 Feedback is recorded in the session log and delivered through DeepSeek
Co-authored-by: Tianyi Cui <[email protected]>
2026-09-05 23:21:22 +08:00
Tianyi Cui cd872be967 Merge pull request #3613 from deepseek-harness/chore/pi-ai-0.85.1
chore(llm): upgrade pi-ai to 0.85.1
2026-09-05 23:16:54 +08:00
Tianyi Cui 1a93474759 docs(llm): clarify pi-ai replay compatibility evidence 2026-09-05 22:57:00 +08:00
Tianyi Cui 7bab91d247 fix(llm): retain Anthropic resolved model during replay 2026-09-05 22:40:40 +08:00
Tianyi Cui 69a0441c34 chore(llm): upgrade pi-ai to 0.85.1 2026-09-05 22:36:58 +08:00
fz 20ed4aced0 docs(sdk): clarify the default editor selection 2026-09-05 22:28:40 +08:00
fz 965adbb5cf feat(sdk): disable str_replace_editor by default 2026-09-05 22:11:20 +08:00
Yichen Jiang 62120daf94 Merge pull request #3602 from deepseek-harness/worktree/dsh-package-manifest
refactor(manifest): centralize package manifest types
2026-09-05 21:08:27 +08:00
Yichen Jiang eea8a83a23 Merge origin/master into worktree/dsh-package-manifest 2026-09-05 20:52:58 +08:00
Yichen Jiang 37aac1a555 docs(manifest): align invariant omission wording with validation 2026-09-05 20:50:37 +08:00
Tianyi Cui 93d89dd0d5 Merge pull request #3603 from deepseek-harness/fix/ci-runtime-wheel-windows
fix(boot): normalize absolute plugin paths in patches
2026-09-05 20:50:02 +08:00
Yichen Jiang 4d56cbc3d3 refactor(manifest): centralize package manifest types 2026-09-05 20:44:31 +08:00
Tianyi Cui 4826e0c2a3 docs(boot): clarify patch path conversion ownership 2026-09-05 20:32:47 +08:00
Tianyi Cui c70b30a6fb test(cli): exercise patch removal without rapid rewrite 2026-09-05 20:25:20 +08:00
Tianyi Cui 15e444e0d7 fix(boot): normalize absolute plugin paths in patches 2026-09-05 20:14:43 +08:00
mektpoy 06cee18430 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation
# Conflicts:
#	.agents/notes/implemented/bug-fix/2026-09-01-host-goal-pause-aborts-turn.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-19-human-goal-command.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-19-same-session-goal-round-driver.i18n.yaml
2026-09-05 15:34:05 +08:00
Yichen Jiang 4aa3cb7818 Merge pull request #3590 from deepseek-harness/worktree/ui-primitives-consolidation-429264
refactor(client): consolidate shared controls into ui-primitives
2026-09-05 15:33:18 +08:00
Yichen Jiang d46f840e99 Merge origin/master into worktree/ui-primitives-consolidation-429264
Archiving low-future-value Agent Notes (#3548) stripped the inbound
citations to three now-archived notes from the ui-primitives README, and
this branch rewrote the same "Controls and icons" opener so the new
component catalog owns the export enumeration. The resolution keeps this
branch's opener and drops the archived-note citation master removed, in
both languages; the pairing record is re-recorded from the merged pair.
2026-09-05 15:17:44 +08:00
Yichen Jiang c279350e03 fix(client): keep the Switch track capsule under the global corner shape
The track's radius is half its height, so its corners consume the whole
side and the global `superellipse(1.5)` squares the ends off — beside a
thumb that already opts out at `border-radius: 50%`, leaving a round knob
in a squared-off slot. Pair `corner-shape: round` with the radius, the way
every full-round radius in the repository does.

The corner-shape stylesheet spec recognizes 50%, 100%, and radii at or
above 99px, so a radius that is full-round only relative to its own box
passes it; the comment records that gap at the rule it affects.
2026-09-05 15:11:25 +08:00
Tianyi Cui d86c08bc1c Merge pull request #3548 from deepseek-harness/worktree/archive-agent-notes-20260904
docs(notes): archive low-future-value Agent Notes
2026-09-05 15:07:49 +08:00
Yichen Jiang 853de8ad0b docs(client): finish the five-state and Pill/Tag corrections
The `idle` addition left two maintainer-facing statements behind: the
README's limitations entry still listed four supported StateDot states,
and TerminalBlock's run-state JSDoc still counted the union as four while
correctly saying three of them are reachable there.

Pill's header comment still sent every capsule without `onClick` to Tag,
which contradicts both the catalog this pull request corrected and
TerminalBlock's own static read-only Pill two files away. Size separates
the two controls as much as interactivity does, and the comment now says
so. The function JSDoc and the static-mode tests stay as they are: they
describe supported behavior.
2026-09-05 15:04:17 +08:00
Yichen Jiang a6ef8dc97a fix(client): animate the unloading phase dot and correct the catalog
`unloading` marks a teardown the Host is running, which an async disposer
can hold for a while, so the inventory's dot animates it like `loading`
instead of showing the static grey `idle` mark that means no activity.

Correct four documentation facts against the shipped code: StateDot's
render JSDoc still promised four states, the catalog claimed four Tooltip
sides where TooltipSide has three, the Agent Note's geometry audit counted
three matching rules where two match, and the migrated-site and shipped-
appearance counts had drifted.

Record two things the first pass left out: TerminalBlock renders its exit
status as a static Pill, which the Tag/Pill catalog entry now accounts for
by size rather than by interactivity alone, and the disabled inventory tag
changed fill token, which joins the visual-change list.

Pin Tag's eight tones with a stylesheet spec, for the same reason StateDot
has one: CSS Modules resolve to class-name maps in component suites, so a
missing or wrong tone rule passes every render assertion.
2026-09-05 14:54:42 +08:00
Tianyi Cui 051cd4b281 docs(notes): address ds-review-bot feedback on the archive audit
- Stop treating three archived records as current authority: bounded-llm
  citation now points at the llm-retry README, the semantic-composer
  proposal cites the runtime-owned child guard as history it builds on,
  and the code-runtime comment states the deferred rationale locally.
- Fix the stale "dsh family stays restricted" claims left without their
  rationale citation: the check-workspace-constraints comment, the
  release publish comment, and the kept npm-release-sequences note now
  record that the family published publicly on 2026-08-13 (87f8e6a728).
- The rejected client-settings-locale-theme body keeps its pristine
  proposal prose with only the Status line and the two link paths whose
  targets this PR archived; the link remaps are required for
  verify-md-links and pairing, and every prose byte is untouched.
2026-09-05 14:52:33 +08:00
Tianyi Cui a7a5be1703 docs(notes): archive low-future-value Agent Notes
Run the dsh-archive-agent-notes audit over every active Agent Note on
current master, judging each record by whether its rationale still guides
work rather than by size or age.

- Archive 453 implemented bilingual triplets (417,882 English words):
  completed UI chrome, narrow adapters, closed bug fixes, implementation
  walkthroughs whose package READMEs, docs pages, generators, or successor
  notes now carry the useful behavior, and 51 records fully superseded by
  a later active note. Keep 201 implemented notes whose ownership rules,
  negative guarantees, durable or wire semantics, security rules,
  reintroduction conditions, or still-tempting rejected alternatives
  remain useful.
- Reject 7 proposals whose premise is gone or whose work shipped in
  amended form under other records; delete 2 rejected notes that no
  longer prevent a plausible mistake.
- Retarget every remaining inbound link to the archived path, and repair
  active prose that named an archived record as the owner of a live fact:
  parenthetical citations drop, ownership sentences redirect to the
  README, docs page, or active note that states the fact, and history
  citations say so. Chinese files link the English archived path because
  the pairing gate treats the frozen tree as outside the bilingual corpus.
- Seal 1,359 new frozen artifacts; existing seals are unchanged and
  outbound links from archived notes are neither inspected nor repaired.
- Regenerate docs/config-catalog.md after the hook-bridge comment edits
  shifted two source line numbers.
2026-09-05 14:37:32 +08:00
Yichen Jiang 452b2a816a refactor(client): share the capsule tag, switch, and idle state dot
Client feature plugins never import one another's components, so
ui-primitives is their only channel for sharing one. Nothing told an
author to look there first, and the package offered nothing to look
at: its README named six source files against forty-plus exports.

Add Tag (read-only capsule badge, eight tones) and Switch (36x20
toggle with a required accessible name), extend StateDotState with
idle for a tracked subject with no activity, and move ui-agent-preset,
ui-settings-plugins, and ui-settings-plugin-inventory onto them.

The plugin inventory's conditional tag referenced
--dsw-alias-state-warning-primary, which does not exist, so both
themes had been painting its hardcoded #b45309 fallback.

State the reuse rule as the first step of the new-component checklist,
and give the README a component catalog so the rule has something to
check. The rule is guidance, not a gate: a package may still write its
own control, and the Agent Note records the five that stay local.
2026-09-05 14:32:59 +08:00
Tianyi Cui 9f68695f97 docs(notes): normalize Chinese Agent Note header tokens
The Agent Note rules keep the `# Agent Note: ` title prefix and the
`Status:` line in English verbatim on both language sides. 51 Chinese
counterparts carried a full-width colon (`# Agent Note:`), an annotated
prefix (`# Agent Note(agent 决策记录):`), or a translated status token
(`状态:已实现`, `状态:implemented`, `状态:已实施`, `状态:proposed`), which the
archive verifier rejects on entry to the frozen tree. Normalize the tokens
and re-record the bilingual sidecars; no body text changes.
2026-09-05 14:23:52 +08:00
mektpoy b9a4b682c4 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation 2026-09-05 14:16:58 +08:00
Yichen Jiang 4dd2c7b51b Merge pull request #3582 from deepseek-harness/worktree/queue-submission-sending
fix(web): show sending state for queued submissions
2026-09-05 12:39:43 +08:00
Yichen Jiang 0ea65903ce Merge pull request #3580 from deepseek-harness/worktree/fix-client-reconnection
fix(connection): recover stalled handshakes and keep retrying
2026-09-05 12:37:00 +08:00
Yichen Jiang 69161395ce fix(web): wait for queue admission before collapsed snapshots 2026-09-05 12:24:05 +08:00
Yichen Jiang 1e04fcff35 fix(connection): validate retry factors and clarify timeout recovery 2026-09-05 12:21:59 +08:00
Kaige-Gao 8b94ed9c21 test: align hygiene gate expectation 2026-09-05 11:59:46 +08:00
Yichen Jiang a3ccbd4d99 fix(web): show sending state for queued submissions 2026-09-05 11:51:52 +08:00
Yichen Jiang 1bd26370cc fix(connection): recover stalled handshakes and keep retrying 2026-09-05 11:50:27 +08:00
Yif fd1e51b097 test(web): refresh master-added goldens for the reworded placeholder
file-upload-round and the clickable-links gallery were recorded on master with
the pre-rewording composer placeholder.
2026-09-04 20:25:04 +08:00
Yif 78258bf6fd Merge remote-tracking branch 'origin/master' into fix/input-placeholder-stat-ui-polish 2026-09-04 20:24:04 +08:00
Yif eac164392d fix(client): name the context meter's tools row precisely and drop the header approximation
The heuristic tools segment counts tool schemas only, so the row reads 工具定义
/ Tool definitions; the header figures lose the ~ because they are anchored to
provider-reported usage, unlike the heuristic rows that keep it.
2026-09-04 20:22:11 +08:00
Yif a49376a2ca fix(client): reword composer placeholders around the / and @ triggers
The default and hero placeholders drop the ellipsis and name the / commands
and @ references as comma-separated actions; goldens and e2e assertions
refresh with the copy.
2026-09-04 20:21:46 +08:00
Yif a3208573a6 fix(client): polish composer and hero spacing
Tighten the composer card's top pad and draft-text pads, pull the attachment
rail closer to the draft, settle the toolbar gaps on 12, give the hero
workspace row its right clearance, and let the wrapped hero badge center under
the title with more air between the wrapped fish and the title line.
2026-09-04 20:21:16 +08:00
Yif 5813c14dee fix(client): portal composer menus over the sidebar and float toasts near the top
ModelSelect renders its dropdown through a body portal with viewport-clamped
fixed placement, so the panel keeps its full width instead of being cut by the
sidebar edge. The preset seat passes Menu an anchor class with an icon-only
min-width floor and moves its label ellipsis onto a dedicated span, keeping the
chip's overflow degradation breakpoint-free. Toasts move to the viewport top
and shrink to fit their text.
2026-09-04 20:19:42 +08:00
07akioni 9e5745de3b fix(desktop): align app versions with release 2026-09-04 20:01:24 +08:00
07akioni d43addeb5c Merge remote-tracking branch 'origin/master' into feat/electron 2026-09-04 19:59:39 +08:00
Dudu-0223 5659d19c30 Merge pull request #3484 from deepseek-harness/fix/fork-resume-system-prompt
fix(web): avoid repeated system prompt on resume
2026-09-04 18:38:07 +08:00
Dudu-0223 d8f630f4b7 Merge remote-tracking branch 'origin/master' into fix/fork-resume-system-prompt 2026-09-04 18:13:46 +08:00
07akioni 42c7317bac chore(cli): remove obsolete desktop host exclusion 2026-09-04 18:03:19 +08:00
Kaige-Gao a19065017f chore(ci): deduplicate client static gates 2026-09-04 17:30:46 +08:00
Yichen Jiang d347e70390 Merge pull request #3554 from deepseek-harness/release/dsh-0.1.3-alpha.1
release: [email protected]
2026-09-04 17:16:23 +08:00
Chinesezjc a33b9081b6 Merge remote-tracking branch 'origin/master' into fix/ci-node-compile-cache-data-disk 2026-09-04 17:13:09 +08:00
Kaige-Gao 5d9603b763 feat(web): localize slash command descriptions 2026-09-04 17:11:39 +08:00
07akioni 64ca04e8fb test(compaction): allow complete live summaries 2026-09-04 17:11:22 +08:00
Dudu-0223 d733bb24e5 Merge remote-tracking branch 'origin/master' into fix/fork-resume-system-prompt 2026-09-04 16:58:21 +08:00
Yichen Jiang 5aff05a92f Merge branch 'master' into release/dsh-0.1.3-alpha.1 2026-09-04 16:58:08 +08:00
Yichen Jiang 2f77acb9ab Merge pull request #3558 from deepseek-harness/fix/web-clickable-links-gallery-golden
test(web): refresh the clickable-links gallery golden for the attachment button
2026-09-04 16:58:00 +08:00
07akioni 81c6f740e0 test(web): stabilize snapshot replay 2026-09-04 16:51:31 +08:00
Chinesezjc 4dfd3b5948 fix(note): restore blank line before Alternatives heading after merge conflict resolution 2026-09-04 16:50:44 +08:00
mektpoy 588be2d3c5 test(web): refresh clickable links after upload merge 2026-09-04 16:45:11 +08:00
Dudu-0223 eb60b74f47 test(web): wait for seeded agent attachment 2026-09-04 16:43:09 +08:00
07akioni 737a965e92 Merge remote-tracking branch 'origin/master' into feat/electron 2026-09-04 16:41:04 +08:00
Dudu-0223 493072641d Merge remote-tracking branch 'origin/master' into fix/fork-resume-system-prompt
# Conflicts:
#	packages/client/ui-chat/src/client/conversation-nodes/chat-snapshot-builder.ts
2026-09-04 16:39:08 +08:00
Yichen Jiang c42ab9e14e test(web): refresh the clickable-links gallery golden for the attachment button 2026-09-04 16:38:22 +08:00
mektpoy b55a8e4777 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation 2026-09-04 16:34:50 +08:00
Dudu-0223 f0ab6a6054 fix(ui-chat): retain skill names on message upserts 2026-09-04 16:31:34 +08:00
07akioni e09407e655 fix(desktop): adapt host fetch handlers 2026-09-04 16:29:01 +08:00
Yichen Jiang 6a82a3b3e2 Merge branch 'master' into release/dsh-0.1.3-alpha.1 2026-09-04 16:24:04 +08:00
07akioni 75c7bbb88d Merge remote-tracking branch 'origin/master' into feat/electron
# Conflicts:
#	packages/client/connection/README.i18n.yaml
#	packages/client/connection/README.md
#	packages/client/connection/README.zh.md
2026-09-04 16:23:37 +08:00
ihsiang 0180c5cdea Merge pull request #3547 from deepseek-harness/ihsiangzhang/tool-call-clickable-styles
feat(client): 统一回答中可点击链接样式——链接别名、hover 点状虚线、分类图标
2026-09-04 16:23:14 +08:00
Chinesezjc cff9a004a6 Merge remote-tracking branch 'origin/master' into fix/ci-node-compile-cache-data-disk 2026-09-04 16:22:44 +08:00
07akioni fe0b7f2814 fix(desktop): move host out of CLI package 2026-09-04 16:21:45 +08:00
Yichen Jiang e94f938c05 release(dsh): align file-upload version 2026-09-04 16:21:09 +08:00
Chinesezjc f7f4bab746 Merge origin/master into fix/ci-node-compile-cache-data-disk 2026-09-04 16:17:32 +08:00
Yichen Jiang 14befe7ff7 Merge branch 'master' into release/dsh-0.1.3-alpha.1 2026-09-04 16:16:15 +08:00
Yichen Jiang 9c13703708 Merge pull request #3556 from deepseek-harness/fix/web-skill-chip-rebuilt-message
fix(web): keep skill chips on rebuilt message nodes
2026-09-04 16:16:08 +08:00
Dudu-0223 f9359b5863 Merge branch 'master' into fix/fork-resume-system-prompt 2026-09-04 16:14:09 +08:00
CreatixChu 53f6590f76 Merge pull request #3109 from deepseek-harness/worktree/2984-generic-file-upload
feat(attachment): 支持通用文件上传
2026-09-04 16:06:32 +08:00
Yichen Jiang 75d3402b84 fix(web): keep skill chips on rebuilt message nodes 2026-09-04 15:59:33 +08:00
yx.zhang 8ffdee4fe5 feat(client): unify clickable-link language with link alias and category glyphs
Clickable artifact links across the transcript (markdown anchors, prose
file mentions, web source/fetch links, produced-file chips, workflow
member links) now share one language: a dedicated --dsw-alias-link color
(light deepseek-500, dark deepseek-400) decoupled from
state-business-primary, font-weight 500, no underline at rest, and a
dotted 3px-offset underline on hover/focus. A new ui-primitives LinkIcon
leads each link with a currentColor category glyph (url / folder / code /
image / document / other) derived from the path extension by
classifyLinkPath. Produced-file chips drop the grey pill and 96px cap and
render at natural width, shrinking with ellipsis only on row overflow.
ToolRow's grey dotted file links and the grey show-in-folder action stay
as they were. The inline-code chip tint moves to neutral-50 (dark
neutral-800) with its 0.5px border kept.

Coverage: LinkIcon unit spec, refreshed markdown-dom fixtures, and the
clickable-links-gallery web e2e registered in the host compiler face.

Closes #3546
2026-09-04 15:55:49 +08:00
creatixchu e28b58f8c0 Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload
# Conflicts:
#	packages/client/ui-chat/src/client/chat/MessageItem.tsx
2026-09-04 15:41:57 +08:00
creatixchu 58ec1f0867 refactor(file-upload): keep storage helpers and the HTTP route package-private
Stop re-exporting the verbatim file-store helpers from attachment-local, move
the raw-byte upload route handler into a non-entry module of file-upload, and
drop the redundant hook type re-exports from the Client entry. The route test
moves next to the module it exercises.
2026-09-04 15:41:25 +08:00
Yichen Jiang ed67c22496 release(dsh): 0.1.3-alpha.1 2026-09-04 15:38:55 +08:00
mektpoy 0928bb2c16 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation 2026-09-04 15:37:06 +08:00
Yichen Jiang 267d755bee Merge pull request #3552 from deepseek-harness/worktree/skill-fuzzy-search-53e21d
feat(web): fuzzy skill discovery and fact-based slash reference chips
2026-09-04 15:31:46 +08:00
mektpoy 56d6c25c9d fix(client): keep goal activation coverage in client face 2026-09-04 15:21:37 +08:00
Yichen Jiang 1b470211ad fix(web): address review: index skill-name batches, bound slash tokens at whitespace, chip only the leading goal token 2026-09-04 15:15:51 +08:00
07akioni ff146b84a3 Merge remote-tracking branch 'origin/master' into feat/electron
# Conflicts:
#	pnpm-lock.yaml
2026-09-04 15:11:38 +08:00
Yichen Jiang d976849a6b fix(web): expect the goal command bubble to share the body face 2026-09-04 14:56:46 +08:00
mektpoy 14baecfa86 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation 2026-09-04 14:49:37 +08:00
mektpoy 206e79ee3d fix(client): order goal activation through inject hooks 2026-09-04 14:49:32 +08:00
creatixchu b4517feed5 Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload 2026-09-04 14:46:36 +08:00
Turtle 7acc038beb Merge pull request #3362 from deepseek-harness/refactor/session-persistence-write-lease
feat(session-persistence-jsonl): cross-process write lock (flock / named semaphore)
2026-09-04 14:45:03 +08:00
Yichen Jiang 9d947bd9cf Merge branch 'master' into worktree/skill-fuzzy-search-53e21d 2026-09-04 14:43:20 +08:00
Yichen Jiang d0da8ccf40 fix(web): decorate slash tokens in bubbles from logged skill and command facts 2026-09-04 14:38:30 +08:00
Turtle 2099 645c68daf2 Merge pull request #3530 from deepseek-harness/turtle/pr-3520-review-followup
docs(fs): record normalized unread diagnostics
2026-09-04 14:35:52 +08:00
Yichen Jiang 46d20f8bee feat(web): rank skill candidates with the shared fuzzy name ranker 2026-09-04 14:31:54 +08:00
07akioni 1553862ac1 Merge remote-tracking branch 'origin/master' into feat/electron 2026-09-04 14:26:23 +08:00
Dudu-0223 3b95586626 Merge branch 'master' into fix/fork-resume-system-prompt 2026-09-04 14:21:42 +08:00
Turtle fa40d90023 refactor: simplify issue templates and policy 2026-09-04 14:20:20 +08:00
Turtle c58097a826 feat(session-persistence-jsonl): cross-process write-ownership lease
Write handles now hold a durable lease (session.lock.json beside the
log): a random owner token, diagnostic pid, and an expiry. Acquisition
wins by exclusive create; a second process's create or write open rejects
while the record is unrenewed for less than leaseTtlMs (default 5 min),
and takes over after that — a crashed holder is waited out, never
reclaimed by pid. The holder renews every leaseRenewIntervalMs (default
4 min); a renewal that finds a foreign, vanished, or expired record — or
fails outright — marks the lease lost permanently, so every later
append/flush rejects with SessionOwnershipLostError while reads continue.
Close releases the record; read handles never touch it. Takeover of an
expired record is eventually exclusive: a replaced holder stops within
one renewal interval.

Refs #3245
2026-09-04 14:12:14 +08:00
creatixchu 268cf0101e Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload 2026-09-04 13:08:41 +08:00
creatixchu f0e52c2731 refactor(file-upload): tighten service boundaries 2026-09-04 13:08:25 +08:00
_Kerman 891f07a2d0 Merge remote-tracking branch 'origin/master' into dshw/pr-deepseek-harness-deepseek-harness-2672
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/api/session-controller/README.i18n.yaml
#	packages/api/session-controller/README.md
#	packages/api/session-controller/README.zh.md
#	packages/api/session-controller/tests/session-projections.host.spec.ts
#	packages/bundle/headless/tests/headless.spec.ts
#	packages/core/agent-loop/README.i18n.yaml
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/README.zh.md
#	packages/core/agent/src/runtime-types.ts
#	packages/fs/tool-str-replace-editor/tests/tools.spec.ts
#	packages/llm/llm-retry/tests/retry.spec.ts
#	packages/llm/llm-retry/tests/transport-recovery.spec.ts
#	packages/shell/tool-bash-persistent/tests/loader-composition.spec.ts
#	packages/shell/tool-bash-persistent/tests/tools.spec.ts
#	packages/shell/tool-pwsh-persistent/tests/loader-composition.spec.ts
#	packages/shell/tool-pwsh-persistent/tests/tools.spec.ts
#	packages/terminal/terminal-bash/tests/index.spec.ts
#	packages/test-support/agent-loop-testkit/package.json
2026-09-04 12:18:37 +08:00
Dudu-0223 b6b2ec4a90 Merge pull request #3480 from deepseek-harness/fix/search-result-reveal-session
Fix session search result navigation
2026-09-04 12:18:21 +08:00
Chinesezjc bee0c13f28 Merge pull request #3513 from deepseek-harness/fix/test-tmp-teardown-self-clean
test: remove dsh-* temp dirs created by unit tests at teardown
2026-09-04 12:11:53 +08:00
Dudu-0223 01a4cba942 docs(web): describe client-only resume handling 2026-09-04 12:09:45 +08:00
Dudu-0223 8ea0cc0445 Merge remote-tracking branch 'origin/master' into fix/fork-resume-system-prompt
# Conflicts:
#	apps/web/tests/message-actions.e2e.ts
2026-09-04 12:08:54 +08:00
Dudu-0223 f1e7dbce55 fix(web): keep resume prompt dedupe client-side 2026-09-04 12:08:16 +08:00
Chinesezjc 1f0a87eb06 Merge remote-tracking branch 'origin/master' into fix/test-tmp-teardown-self-clean
# Conflicts:
#	packages/subprocess/subprocess-local/tests/spawn.spec.ts
2026-09-04 11:58:16 +08:00
Dudu-0223 470ea85286 Merge origin/master into fix/search-result-reveal-session 2026-09-04 11:57:07 +08:00
Chinesezjc d8a995e00e docs: align the changed-spec count with the merged-base diff (36) 2026-09-04 11:56:31 +08:00
Turtle df07f37827 Merge pull request #3516 from deepseek-harness/turtle/issue-2390-windows-hide-subprocess
fix(subprocess): hide Windows child windows
2026-09-04 11:52:34 +08:00
Chinesezjc 3f07443702 Merge branch 'master' into fix/test-tmp-teardown-self-clean 2026-09-04 11:15:31 +08:00
Turtle 9656a1742b Merge pull request #3521 from deepseek-harness/turtle/issue-2349-windows-root-workspace
fix(workspace): preserve Windows drive roots
2026-09-04 11:10:27 +08:00
creatixchu 705cd220d4 test(web): migrate file upload snapshot to v2 2026-09-04 10:29:41 +08:00
creatixchu 48656b4594 test(session-controller): restore Session type import 2026-09-04 10:14:15 +08:00
creatixchu fb743759a7 Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload
# Conflicts:
#	apps/web/tests/scaffold.ts
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	packages/api/session-controller/README.i18n.yaml
#	packages/api/session-controller/README.md
#	packages/api/session-controller/README.zh.md
#	packages/extensions/tool-cordis/src/api-catalog.ts
#	packages/llm/token-meter/src/index.ts
#	packages/session-query/session-log-export/README.i18n.yaml
#	packages/session-query/session-log-export/README.md
#	packages/session-query/session-log-export/README.zh.md
#	packages/session-query/session-log-export/src/archive.ts
#	scripts/package-dependency-policy.ts
2026-09-04 10:12:19 +08:00
pku-xht e82e5ffd7a fix(subprocess): normalize PTY scope launcher environment 2026-09-04 02:58:09 +08:00
pku-xht c7dc4d3833 test(subprocess): restore Cordis API projection 2026-09-04 01:30:10 +08:00
pku-xht cffb09b02c Merge commit '0d361e6eede9e8a739e776949aa7d5e3de4472da' into codex/subprocess-native-containment
# Conflicts:
#	snapshots/session/cordis-inspect-jsdoc/session.v2.jsonl
2026-09-04 00:56:00 +08:00
pku-xht d82fd86c5c fix(subprocess): isolate native runner bootstrap 2026-09-04 00:24:52 +08:00
Tianyi Cui b4ea3efcf6 Merge pull request #3400 from deepseek-harness/worktree/session-format-06-v2-snapshot-rollout
test(snapshot): roll corpus forward to format v2
2026-09-03 23:12:28 +08:00
Tianyi Cui 1d35bcfc8a Merge pull request #3533 from deepseek-harness/gate/package-version-drift
gate(constraints): enforce the dsh family version rule across apps and packages
2026-09-03 22:49:35 +08:00
Tianyi Cui a931bcf226 fix(constraints): require the shared dsh version in every workspace manifest
The dsh-family version rule lived only in the packages/ block of
checkWorkspaceManifest, so apps/ members and the root-named CLI carried the
shared version with no static check of their own. The name-based rule now
covers every scanned manifest; regression coverage names the stale-version
merge that shipped packages/util/http-proxy at 0.1.2-alpha.5 behind a
0.1.2-rc.1 family.
2026-09-03 22:41:44 +08:00
Tianyi Cui 8cb1d6a7eb Merge commit '85c23a2df3' into worktree/session-format-06-v2-snapshot-rollout 2026-09-03 22:37:26 +08:00
Tianyi Cui 86241a442d fix(session): keep independent version fields off the format generation
`SESSION_FORMAT_VERSION` is the only value that names the Session format
generation. Two other version fields had moved to 2 alongside it:

- The `dsh_session_log` request extension's outer schema `version` returns
  to 1 and its Session header projection keeps `seedLength`, derived from
  the logical inherited cut, so the external wire is unchanged in this PR;
  `sessionFormatVersion` alone identifies the embedded generation.
- The `sessionStats` projection unit's `stateVersion` returns to 1: the
  projection cache binds every checkpoint to the format generation, so a
  generation change discards old rows without a unit version bump.

Test doubles and the standalone Client fixture that build a current
header now spell `SESSION_FORMAT_VERSION` instead of the literal.
2026-09-03 22:36:51 +08:00
Tianyi Cui 6c7603aacd Merge commit '51f9d5f6c1' into worktree/session-format-06-v2-snapshot-rollout 2026-09-03 22:24:50 +08:00
Tianyi Cui 9fb0678f0b Merge commit '22472e4092' into worktree/session-format-05-v1-v2-chunk-migration 2026-09-03 22:24:36 +08:00
Tianyi Cui 721ff67ca1 Merge commit '1b6fdd0e1b' into worktree/session-format-04-live-assistant-stream 2026-09-03 22:24:22 +08:00
Tianyi Cui 6c419795f6 docs(session): name the frozen v0/v1 vocabulary in the v0-to-v1 README
The README file table listed four of the six source modules and omitted
the two largest, so the package read as an oversized identity conversion.
The summary now states that most of the source is the frozen released
v0/v1 event vocabulary, why the edge refuses a malformed historical log
before the installed current restorer runs, and that later edges reuse
those shapes; the table gains `payload-validation.ts` and
`relationships.ts` rows.
2026-09-03 22:23:53 +08:00
Tianyi Cui 17fb719138 Merge commit 'cf8f75faaf' into worktree/session-format-06-v2-snapshot-rollout 2026-09-03 22:10:02 +08:00
Tianyi Cui d58964a010 Merge commit 'be5db297c7' into worktree/session-format-05-v1-v2-chunk-migration
# Conflicts:
#	.agents/notes/implemented/architecture/2026-08-31-live-assistant-stream-frames.i18n.yaml
#	.agents/notes/implemented/architecture/2026-08-31-live-assistant-stream-frames.md
#	.agents/notes/implemented/architecture/2026-08-31-live-assistant-stream-frames.zh.md
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	packages/api/session-controller/README.i18n.yaml
#	packages/api/session-controller/README.md
#	packages/api/session-controller/README.zh.md
#	packages/api/session-controller/src/assistant-stream.ts
#	packages/api/session-controller/src/client/sessions/assistant-stream.ts
#	packages/api/session-controller/src/types.ts
#	packages/api/session-controller/tests/assistant-stream.client.spec.ts
#	packages/api/session-controller/tests/session-history-journal.host.spec.ts
#	packages/api/session-controller/tests/sessions-service.client.spec.ts
#	packages/api/session-controller/tests/transport.client.spec.ts
#	packages/core/agent/README.i18n.yaml
#	packages/core/agent/README.md
#	packages/core/agent/README.zh.md
#	packages/extensions/tool-cordis/src/api-catalog.ts
#	scripts/package-dependency-policy.ts
2026-09-03 22:09:31 +08:00
Tianyi Cui 8a0c91be7f Merge commit 'c347bfcfa6' into worktree/session-format-04-live-assistant-stream 2026-09-03 21:59:19 +08:00
Tianyi Cui fe9c2d7053 refactor(agent, session-controller): drop the unread startedTime frame field
The `start` frame and the reconnect baseline attempt carried a wall-clock
`startedTime` that no Host or Client consumer read: the Host accumulator
and the Client reconciler copied it into their attempt maps and nothing
looked at it again. Presentation frames now carry only the coordinates
consumers use (attempt, revision, turn, step, chunk index, and v1 seq
provenance); the type-equivalence block, event graph, READMEs, and the
live-stream Agent Note follow the type.
2026-09-03 21:58:34 +08:00
Tianyi Cui c97df989ff refactor(session): share the canonical log basename and JSON snapshots
`session[.vN].jsonl` was assembled independently by the JSONL provider
(twice), the session-log export archive, and the recorded-session fixture
helpers. `dsh-session-format` now owns `sessionFormatLogFilename` and
`parseSessionFormatLogFilename`; the three consumers append only their
compression suffix, and the migration note names the owner.

`snapshotSessionFormatJson` re-implemented the lossless JSON walk that
`dsh-util-values` already publishes as `snapshotJsonValue` + `deepFreeze`,
and the frozen v0 relationship validator carried a third structural JSON
comparison next to `deepEqualJson`. Both now delegate; the format package
reports one `is not lossless JSON` diagnostic per labelled subject instead
of ten member-specific ones, and enumerable accessors whose values survive
a JSON round trip are accepted like `JSON.stringify` accepts them.
2026-09-03 21:48:09 +08:00
pku-xht d79f5c04e8 Merge master into codex/subprocess-native-containment 2026-09-03 21:46:02 +08:00
creatixchu de022388ea test(ci): stabilize attachment fixtures 2026-09-03 21:25:45 +08:00
Dudu-0223 d18770f50a fix(web): address latest session reveal review 2026-09-03 21:19:09 +08:00
pku-xht 423412b7bf fix(runtime): simplify executable entry dispatch 2026-09-03 21:18:27 +08:00
creatixchu 0516edb037 test(file-upload): restore host composition fixtures 2026-09-03 21:12:50 +08:00
fz 8d06ebb5ac Revert "refactor: remove str_replace_editor"
This reverts commit d12b1146baa326e6facd3b10f81ae11db35ffd86.
2026-09-03 21:05:38 +08:00
creatixchu 2a826a93c3 Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload 2026-09-03 20:55:12 +08:00
creatixchu ea669428be refactor(attachment): unify prompt content admission 2026-09-03 20:53:29 +08:00
creatixchu 3eb9736eb6 refactor(file-upload): scope prompt binding rollback 2026-09-03 20:15:18 +08:00
pku-xht e5dbccce8c fix(subprocess): move SEA bootstrap to runtime packaging 2026-09-03 19:59:26 +08:00
Tianyi Cui 71089f8df7 Merge commit '8f7250f904' into worktree/session-format-06-v2-snapshot-rollout
# Conflicts:
#	apps/cli/tests/profiles/headless/tests/expected/subagent-settlement/child.expected.jsonl
2026-09-03 19:41:58 +08:00
Tianyi Cui 874b174fd6 test(web): compare fixture inventories by Session role and pin the v2 upload
`assertFixtureInventory` folds every retained generation of one parent or
child fixture into a single role before comparing, so an older generation kept
beside the current one is not an inventory drift. The generation spec writes
headers that match each filename, since fixture selection validates the chosen
generation, and asserts that an absent parent resolves only for an
override-only replay. The `dsh_session_log` composition expectation follows the
extension's version 2 payload.
2026-09-03 19:41:16 +08:00
Tianyi Cui d5044d5675 Merge commit 'ee4bad5cde' into worktree/session-format-05-v1-v2-chunk-migration 2026-09-03 19:25:29 +08:00
Tianyi Cui bb771b133c Merge commit '09d3a185ab' into worktree/session-format-04-live-assistant-stream 2026-09-03 19:24:54 +08:00
Tianyi Cui d455ad99e3 test(session): record the v2 SDK expectations and cover review-fix branches
The continuable-child headless expectation and the Python `advanced` and
`restart` scenarios pin the current runtime, whose subagent children carry no
`session/end-seed` marker and whose assistant messages embed their streams:
the child fixture drops the marker and renumbers its references, `advanced/`
re-records `result.json`, and both scenarios gain their v2 Session fixtures.
Unit tests cover the `tool-call-delta` id and name validation, embedded
stream members without timing arrays, and the versionless-header refusal.
2026-09-03 19:22:37 +08:00
Chinesezjc dde27f5163 Merge remote-tracking branch 'origin/master' into fix/test-tmp-teardown-self-clean 2026-09-03 19:04:31 +08:00
Turtle 6e7c3f37c1 docs(fs): record normalized unread diagnostics 2026-09-03 19:01:30 +08:00
Turtle a05b5fbe79 fix(subprocess): hide Windows cleanup helpers 2026-09-03 19:01:30 +08:00
Turtle e609fd73a3 fix(workspace): harden qualified path handling 2026-09-03 19:01:30 +08:00
Tianyi Cui 778e0866c3 test(session): cover the migration read faults and the versioned export name
The JSONL backend rethrows storage errno failures and abort signals from the
source read of a pending migration unwrapped; a test now drives both through
the stat seam so the classification stays covered. The navigation-panes Web
e2e derives the exported archive entry from `SESSION_FORMAT_VERSION`, which
`session-log-export` uses for its `session.v<N>.jsonl` name. The module graph
records the `session-log-export` → `session` peer edge.
2026-09-03 19:00:16 +08:00
Tianyi Cui 91904d7c10 Merge commit 'fef079e5c9' into worktree/session-format-06-v2-snapshot-rollout
# Conflicts:
#	snapshots/session/fs-policy-reject/session.jsonl
2026-09-03 18:51:05 +08:00
Tianyi Cui 156429e86d chore(session): satisfy the master gates on the v1-to-v2 branch
`session-format-v1-to-v2` takes the `0.1.2-rc.1` root version that master
requires, and `defineReleasedPayloadDisposition` drops the `@param` tag for a
parameter it no longer has.
2026-09-03 18:43:24 +08:00
Tianyi Cui 28b16c011a Merge commit 'a123cb0055' into worktree/session-format-05-v1-v2-chunk-migration
# Conflicts:
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
2026-09-03 18:39:44 +08:00
Tianyi Cui 13074e4aa2 Merge commit '308c1c69a6' into worktree/session-format-04-live-assistant-stream 2026-09-03 18:36:02 +08:00
Tianyi Cui 3c3ad02b30 chore(session): satisfy the master hygiene gates
`session-log-export` names its archive entry after `SESSION_FORMAT_VERSION`,
a runtime value of the shared `dsh-session` instance, so `dsh-session` becomes
a peer dependency and the export is classified as peer-required in the package
dependency policy. The three Session format packages take the `0.1.2-rc.1`
root version that master now requires.
2026-09-03 18:35:14 +08:00
Tianyi Cui 3aef64797d Merge master into session format migration
# Conflicts:
#	packages/test-support/session-snapshot/src/harness.ts
#	scripts/smoke-python-runtime.py
2026-09-03 18:31:54 +08:00
creatixchu b2c4483c9d refactor(attachment): own prompt admission on service 2026-09-03 18:18:32 +08:00
Chinesezjc cf4cfd9e4a docs: correct the changed-spec count in the Agent Note verification section 2026-09-03 18:17:09 +08:00
Turtle 818c4f344e Merge pull request #3520 from deepseek-harness/turtle/issue-2353-fs-error-copy
fix(fs): normalize unread mutation diagnostics
2026-09-03 18:15:00 +08:00
Tianyi Cui d89427ba6c Merge commit '12dabcc9d2' into worktree/session-format-06-v2-snapshot-rollout 2026-09-03 17:54:10 +08:00
Tianyi Cui 5fa5fea11d Merge commit '1f9d5f72e9' into worktree/session-format-05-v1-v2-chunk-migration
# Conflicts:
#	packages/session/session-format/README.i18n.yaml
#	packages/session/session-format/README.md
#	packages/session/session-format/README.zh.md
#	packages/session/session-format/src/catalog.ts
#	packages/session/session-format/src/types.ts
#	packages/test-support/llm-replay/tests/llm-replay.spec.ts
2026-09-03 17:53:18 +08:00
Tianyi Cui 51adfbf52c chore(session): retire the v1-to-v2 benchmark script
The repository-only benchmark, its unit-suite spec, the root script, and the
README section are removed; the accepted acceptance run's figures stay in the
embedded-assistant-streams note as recorded facts. The note also records why
the migration edge reuses the `dsh-llm` stream helpers instead of frozen
copies and why its target validation re-checks message/stream agreement
itself. A validation test that recomputed `RELEASED_V2_EVENT_TYPES` from the
same expression as its definition is dropped.
2026-09-03 17:50:09 +08:00
Tianyi Cui 7c169a04b3 Merge commit '1a244059c3' into worktree/session-format-04-live-assistant-stream 2026-09-03 17:48:54 +08:00
Tianyi Cui 13dee20db6 refactor(session): drop dead migration plumbing
`ensureJsonlGenerationCurrent` returned a live Zstandard body iterator that
every production caller disposed unread before decoding the same bytes again;
the header read now decodes only the first frame and owns no decoder past its
return. The JSONL backend reuses the generation module's stable-revision read
instead of keeping a second copy, `encodeCurrent` encodes the validated
current artifact it is documented to receive instead of re-running the
migration chain on it, and the test-only `inspectVersion` catalog method and
the `migrateSessionSnapshotFixture` duplicate of
`prepareSessionSnapshotFixtureForComparison` are removed.
2026-09-03 17:39:12 +08:00
Turtle af63a56078 test(workspace): make relative path regression portable 2026-09-03 17:30:14 +08:00
Chinesezjc c8fc38541f test: own the default spill dir in subprocess specs; correct retention wording
Second review round (ds-review-bot v4p/v5/v6): the exit cleanup claim that
collectors unlink their spill files on dispose was wrong — completed spill
files are retained (seal() only closes, discardSpill() is the only unlink),
so the exit removal only ever applies to directories that never spilled.
Reword the JSDoc, README, and Agent Note accordingly, drop the redundant
readdirSync precheck (rmdirSync ENOTEMPTY is caught anyway), and recount the
v8-ignore window. The spawn.spec default-spill test now records the default
per-process directory it created and removes it in afterAll, so a completed
spill file is never left behind by the unit suite.
2026-09-03 17:29:21 +08:00
Dudu-0223 2f396feca8 Merge branch 'master' into fix/fork-resume-system-prompt 2026-09-03 17:18:21 +08:00
Turtle d33fe767c1 fix(workspace): preserve Windows drive roots 2026-09-03 17:14:02 +08:00
Turtle 18635905aa fix(fs): normalize unread mutation diagnostics 2026-09-03 17:13:13 +08:00
Chinesezjc 1bc330ce01 docs: cross-link the spill retention decision from the teardown note
The Agent Note now links the 2026-07-17 local-spill-startup-cleanup note it
builds on, and the privateSpillDir JSDoc documents the empty-dir exit
removal alongside the directory's creation contract.
2026-09-03 17:07:43 +08:00
Chinesezjc 29e6669e3c test: narrow process-exit spill cleanup to empty dirs; drop spill-store deletion
Review (ds-review-bot) found the exit-time deletion of per-process spill
roots conflicts with the documented retention decision: spill artifacts are
model-visible locators that resumed or forked sessions may still reference
(2026-07-17-local-spill-startup-cleanup), and an exception thrown from an
'exit' listener can change the process exit code.

- dsh-spill-local: revert the exit handler entirely; its default root is
  already owned by the package's 30-day startup sweep.
- dsh-subprocess-local/spawn: remove the per-process spill dir at a
  JavaScript-observable exit only while it is EMPTY (collectors unlink
  their spill files on dispose), best-effort with a named swallow so a
  Windows-held handle never changes the exit code; dirs holding spill
  files keep them for external cleanup.
- Document the empty-dir exit removal in the package README and the Agent
  Note, and re-record both bilingual pairs.
2026-09-03 17:06:48 +08:00
Turtle cc8099dc5f fix(subprocess): hide Windows child windows 2026-09-03 17:05:18 +08:00
creatixchu f989df7c8e test(file-upload): cover extensible request identifiers 2026-09-03 17:04:29 +08:00
creatixchu 8a84c1edff test(file-upload): cover isolated service paths 2026-09-03 17:03:14 +08:00
fz 79b3d7a594 refactor: remove str_replace_editor 2026-09-03 17:02:37 +08:00
creatixchu 33b7123e96 test(remotes): declare built smoke schema dependency 2026-09-03 16:49:08 +08:00
creatixchu 3b8245afc3 fix(build): align file upload project faces 2026-09-03 16:41:45 +08:00
creatixchu 7158227650 fix(file-upload): declare host runtime dependencies 2026-09-03 16:35:50 +08:00
Chinesezjc 6d9776a3b0 test: exempt process-exit spill cleanup from the per-file coverage gate
The exit listener runs after the coverage dump, so its body can never be
measured by the unit coverage lane; mark it v8-ignore with the reason, as
with other process-exit-only code paths.
2026-09-03 16:35:45 +08:00
Chinesezjc 1107ff5fe1 test: remove remaining dsh-* spill/temp dirs in shell and fs specs
Full-template residue histogram on the CI host surfaced four more normal-exit
leaks below the earlier cutoff: tool-bash/tool-pwsh tools.spec (module spill
dir / per-test homes), bash-sandbox sandbox.spec (module spill dir and the
read-only denial root), and fs-sandbox fs-sandbox.spec (inline tmp dir). All
four now remove what they create at the same teardown points as their
neighbors.
2026-09-03 16:26:22 +08:00
creatixchu 9fd72003e6 chore(test): remove obsolete lint suppression 2026-09-03 16:20:23 +08:00
creatixchu dd37061c2b test(client): provide file upload fixture service 2026-09-03 16:20:08 +08:00
Chinesezjc 0364343a7e test: remove dsh-* temp dirs created by unit tests at teardown
Spec files that create /tmp/dsh-* directories via mkdtemp now track and
delete them in afterEach/afterAll; module-scope fixture dirs (executor
spill dirs) are removed in afterAll. The file list came from the
observed-residue inventory on the self-hosted CI host: only specs whose
dirs actually accumulated were leak sources (issue #3134), superseding
the kept-but-unmerged CI sweep branch per the #3233 review decision.

Product per-process spill roots (dsh-subprocess-local spawn,
dsh-spill-local store) register a process-exit handler that removes the
memoized dir, so processes that used the spawn/spill path clean up on
normal exit. A SIGKILLed process cannot run in-process teardown; the
machine-side timer remains the backstop for that path.

Agent Note: .agents/notes/implemented/process/2026-08-28-test-temp-dir-self-cleanup.md
2026-09-03 16:19:18 +08:00
Dudu-0223 a22f2105e0 fix(test): stabilize trajectory history pagination 2026-09-03 16:17:43 +08:00
Tianyi Cui 1762d63e6c test(session): cover observed migration shapes 2026-09-03 16:16:09 +08:00
Dudu-0223 477ff9d5e3 fix(agent-loop): preserve resumed series boundaries 2026-09-03 16:13:45 +08:00
creatixchu 97fe39920a Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload 2026-09-03 16:10:40 +08:00
creatixchu 8fc9a11c5e refactor(attachment): isolate file upload service 2026-09-03 16:10:24 +08:00
fz e9f8641e76 Merge remote-tracking branch 'origin/master' into feat/remove-str-replace-editor-from-minimal
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml
#	.agents/notes/implemented/architecture/2026-08-23-python-sdk-dsh-profile-runtime.i18n.yaml
#	.agents/notes/implemented/architecture/2026-08-23-python-sdk-windows-x64-runtime.i18n.yaml
2026-09-03 16:05:56 +08:00
fz 63795eaa5c feat(minimal): remove str_replace_editor from minimal profiles 2026-09-03 16:03:59 +08:00
Dudu-0223 29e20b0a9f Merge branch 'master' into fix/search-result-reveal-session 2026-09-03 16:00:19 +08:00
Chinesezjc 100fcb286f Merge pull request #3432 from deepseek-harness/fix/pwsh-loader-composition-timeout
test(pwsh): restore product-default deadline in loader composition
2026-09-03 15:59:41 +08:00
mektpoy 1d6633ae04 test(snapshot): sync web goal prompt fixtures 2026-09-03 15:54:30 +08:00
Tianyi Cui e4f46f8e4d Merge commit '4ec9519539' into worktree/session-format-06-v2-snapshot-rollout 2026-09-03 15:46:19 +08:00
Tianyi Cui cf97e3e455 Merge commit 'ad1b192078' into worktree/session-format-05-v1-v2-chunk-migration 2026-09-03 15:45:27 +08:00
mektpoy 3f848e1aa0 docs(client): align goal bar activation comments 2026-09-03 15:45:09 +08:00
Tianyi Cui e7a17eb7ac Merge commit '7931edb2eb' into worktree/session-format-04-live-assistant-stream 2026-09-03 15:44:44 +08:00
Tianyi Cui f9870325b2 fix(session): validate compaction spans by surface order 2026-09-03 15:44:04 +08:00
mektpoy c724617593 test(snapshot): migrate packed session fixtures 2026-09-03 15:42:14 +08:00
Tianyi Cui 7442cedc82 Merge commit '13f179cd60' into worktree/session-format-06-v2-snapshot-rollout 2026-09-03 15:28:51 +08:00
Tianyi Cui 463f8e9221 Merge commit '0d8fcd3a0e' into worktree/session-format-05-v1-v2-chunk-migration 2026-09-03 15:27:50 +08:00
Tianyi Cui 9a5611865f Merge commit 'c0c4aebaa9' into worktree/session-format-04-live-assistant-stream 2026-09-03 15:27:11 +08:00
Tianyi Cui b5f1539733 fix(session): validate surface replacement endpoints 2026-09-03 15:26:35 +08:00
mektpoy 34f897d1ca refactor(goal): share goal bar resume branch 2026-09-03 15:14:49 +08:00
Chinesezjc 91f7e08136 Merge branch 'master' into fix/pwsh-loader-composition-timeout 2026-09-03 15:05:54 +08:00
Dudu-0223 f3dab48118 Merge remote-tracking branch 'origin/master' into fix/search-result-reveal-session 2026-09-03 15:03:50 +08:00
Dudu-0223 4f0706a335 fix(web): address session reveal review 2026-09-03 15:03:38 +08:00
Dudu-0223 ed8cdafe3f test(web): update resumed conversation golden 2026-09-03 14:56:40 +08:00
mektpoy e26fc35d4b fix(goal): keep manual pause authoritative and show activation
Expose a live goals/get read plus goal/activation-changed for the Web strip, reject model resume of durable paused goals, refresh snapshot and generated documentation surfaces, and record the follow-up decision.
2026-09-03 14:53:20 +08:00
Dudu-0223 6ad01cbd8d fix(web): avoid repeated system prompt on resume 2026-09-03 14:45:01 +08:00
creatixchu 1967bedd9f Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload 2026-09-03 14:43:25 +08:00
creatixchu ee23db68cf test(client): cover background upload seams 2026-09-03 14:43:07 +08:00
fz 9fe2112a63 Merge pull request #3473 from deepseek-harness/feat/python-sdk-macos-x64
feat(python): support macOS x64 runtime wheels
2026-09-03 14:36:59 +08:00
Yichen Jiang 0c99ae8557 Merge pull request #3474 from deepseek-harness/worktree/lark-docs-optimization-c86275
docs(user):  reasoning levels and model discovery in the provider guide
2026-09-03 14:30:42 +08:00
creatixchu b7e5d0b90e docs(client): refresh generated catalogs 2026-09-03 14:25:05 +08:00
creatixchu 4ed33aa581 chore(client): refresh slot source locations 2026-09-03 14:20:25 +08:00
fz 44855d1054 fix(release): align http proxy package version 2026-09-03 14:15:32 +08:00
Yichen Jiang a51474c436 docs(user): align provider guide wording with the effort menu, config button, and off semantics 2026-09-03 14:15:32 +08:00
fz 23c1052f5a docs(python): refresh runtime target notes 2026-09-03 14:15:12 +08:00
creatixchu caa4bbb474 Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload 2026-09-03 14:12:15 +08:00
creatixchu 7a99e70372 fix(client): satisfy upload package gates 2026-09-03 14:11:41 +08:00
Dudu-0223 987fde9515 Merge remote-tracking branch 'origin/master' into fix/search-result-reveal-session 2026-09-03 14:10:18 +08:00
Yichen Jiang 74c38ba9c7 Merge remote-tracking branch 'origin/master' into worktree/lark-docs-optimization-c86275 2026-09-03 14:07:26 +08:00
07akioni 0c84f773d9 fix(desktop): align package version with release 2026-09-03 14:05:15 +08:00
creatixchu 6acc828f81 test(client): widen upload carrier fixtures 2026-09-03 14:03:53 +08:00
Yichen Jiang 76fda72979 Merge pull request #3481 from deepseek-harness/fix/http-proxy-rc-version
fix(http-proxy): match the workspace version to the 0.1.2-rc.1 release
2026-09-03 14:02:58 +08:00
fz 61e4829ed7 Merge remote-tracking branch 'origin/master' into feat/python-sdk-macos-x64 2026-09-03 14:02:09 +08:00
creatixchu 4647dbf8ff fix(ui-approval): type pending approval discriminator 2026-09-03 14:01:37 +08:00
Dudu-0223 b09d3a2c0d fix(ui-workspace): reveal opened search result 2026-09-03 14:00:21 +08:00
creatixchu 6cf7b1e34f chore(client): refresh generated API catalog 2026-09-03 14:00:14 +08:00
creatixchu b8512fa5e5 Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload 2026-09-03 13:53:47 +08:00
creatixchu bbb2ca7c9b refactor(client): extract background file upload service 2026-09-03 13:53:25 +08:00
Yichen Jiang 136b67cdec fix(http-proxy): match the workspace version to the 0.1.2-rc.1 release 2026-09-03 13:50:13 +08:00
07akioni 3e526474a3 Merge remote-tracking branch 'origin/master' into feat/electron
# Conflicts:
#	pnpm-lock.yaml
#	scripts/gen-cordis-catalog.ts
2026-09-03 13:46:37 +08:00
Yichen Jiang 34b33c2273 docs(user): simplify discovery, protocol, and OAuth wording in the provider guide 2026-09-03 13:31:47 +08:00
Yichen Jiang 7169660d33 Merge pull request #3198 from deepseek-harness/worktree/deepseek-harness-proxy-config-2f5b4a
feat(net): route every outbound request through the configured proxy
2026-09-03 13:19:19 +08:00
Tianyi Cui 7299d5e093 Merge commit '060de4c547f020e1953c88b98b7ab749fd9ef20f' into worktree/session-format-06-v2-snapshot-rollout 2026-09-03 13:18:35 +08:00
Tianyi Cui 4fb03d0bda fix(session): preserve v2 migration compatibility 2026-09-03 13:17:48 +08:00
Tianyi Cui d7e9115df9 Merge commit 'a4a34b2a71f6bdb92c723840dca4d7fbd71c3148' into worktree/session-format-05-v1-v2-chunk-migration 2026-09-03 13:09:15 +08:00
Tianyi Cui 401216477c Merge commit 'e6b9e90886088ffd344110d45bb406880e554a8a' into worktree/session-format-04-live-assistant-stream 2026-09-03 13:08:25 +08:00
Tianyi Cui 618a7a46e8 fix(session): accept released migration data 2026-09-03 13:07:26 +08:00
Chinesezjc ecd75e6dd6 test(pwsh): clarify deadline comment and keep case budget independent
Review feedback: the dsh-terminal-bash product default is 30s, not 300s;
the raised value bounds one send plus the complete startup sequence, so it
must cover the same cold start the tool deadline does. The vitest case
budget stays at its pre-existing 120s: the case-level timeout overrides
the lane --testTimeout, so syncing it to the plugin deadline would make a
stalled partition wait 300s instead of 120s.
2026-09-03 13:05:22 +08:00
Yichen Jiang 13f467b15b docs(user): gather settings.yaml fields under advanced configuration ahead of troubleshooting 2026-09-03 12:36:39 +08:00
Yichen Jiang be1777084d docs(user): call catalog providers built-in providers in the provider guide 2026-09-03 12:33:24 +08:00
Yichen Jiang 254c9b8b7f docs(user): guide model discovery for third-party providers 2026-09-03 11:51:46 +08:00
Yichen Jiang 410e912893 Merge remote-tracking branch 'origin/master' into worktree/lark-docs-optimization-c86275 2026-09-03 11:49:24 +08:00
Yichen Jiang 454d92dc34 docs(user): route reasoning levels and settings.yaml fields through the provider guide 2026-09-03 11:49:22 +08:00
imccyu 48d84990a0 Merge pull request #3471 from deepseek-harness/release/dsh-0.1.2-rc.1-version-to-master
sync: merge 0.1.2-rc.1 to master
2026-09-03 11:21:56 +08:00
fz 7dcdcc2965 feat(python): support macOS x64 runtime wheels 2026-09-03 11:16:34 +08:00
Yichen Jiang 427d210b5e Merge pull request #3451 from deepseek-harness/worktree/fix-model-listing-discovery
fix(llm): expand model listing discovery
2026-09-03 11:12:32 +08:00
Yichen Jiang 777d46cf81 Merge branch 'master' into worktree/fix-model-listing-discovery 2026-09-03 10:59:28 +08:00
imccyu 3225ec2d94 Merge remote-tracking branch 'origin/master' into release/dsh-0.1.2-rc.1-version-to-master 2026-09-03 10:40:28 +08:00
imccyu cea08311a0 Merge pull request #3470 from deepseek-harness/release/dsh-0.1.2-rc.1
release: [email protected]
2026-09-03 10:35:15 +08:00
pku-xht c8393a2798 test(pwsh): cover background outcome status mapping 2026-09-03 09:12:29 +08:00
pku-xht ed25d4e15b docs(subprocess): correct probe and terminal failure contracts 2026-09-03 08:58:31 +08:00
pku-xht 29c68b6da9 docs(subprocess): sync native containment evidence 2026-09-03 07:03:00 +08:00
pku-xht 0652b7b4d7 fix(subprocess): close containment review gaps 2026-09-03 06:18:21 +08:00
Tianyi Cui 06b93748eb fix(snapshot): address v2 rollout review 2026-09-03 05:15:04 +08:00
Tianyi Cui e10f671167 Merge remote-tracking branch 'origin/worktree/session-format-05-v1-v2-chunk-migration' into worktree/session-format-06-v2-snapshot-rollout
# Conflicts:
#	apps/web/tests/scaffold.ts
#	apps/web/tests/subagent-conversation.e2e.ts
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.zh.md
#	packages/test-support/llm-replay/README.i18n.yaml
#	packages/test-support/llm-replay/README.md
#	packages/test-support/llm-replay/README.zh.md
#	packages/test-support/llm-replay/tests/llm-replay.spec.ts
#	snapshots/sdk/subagent-continuable-inheritance/session.1.v2.jsonl
#	snapshots/sdk/subagent-continuable/session.1.v2.jsonl
#	snapshots/sdk/subagent-dsh-sdk-diagnostic/session.v2.jsonl
#	snapshots/sdk/subagent-list-agents/session.1.v2.jsonl
#	snapshots/sdk/subagent-send-message/session.1.v2.jsonl
#	snapshots/session/agent-instructions/session.v2.jsonl
#	snapshots/session/headless.snapshot.ts
#	snapshots/web/schedule-catalog/session.v2.jsonl
2026-09-03 05:09:32 +08:00
Tianyi Cui 67c8a58854 fix(session): address v2 migration review 2026-09-03 04:45:41 +08:00
pku-xht 14c16012fb fix(subprocess): preserve post-commit runner errors 2026-09-03 04:07:57 +08:00
pku-xht ff6a49660f fix(subprocess): tighten native containment settlement 2026-09-03 03:26:42 +08:00
Tianyi Cui a88ef734cc Merge remote-tracking branch 'origin/worktree/session-format-04-live-assistant-stream' into worktree/session-format-05-v1-v2-chunk-migration
# Conflicts:
#	.agents/notes/implemented/architecture/2026-08-31-live-assistant-stream-frames.i18n.yaml
#	.agents/notes/implemented/architecture/2026-08-31-live-assistant-stream-frames.md
#	.agents/notes/implemented/architecture/2026-08-31-live-assistant-stream-frames.zh.md
#	.agents/notes/implemented/simplification/2026-08-06-buffer-free-feedback-telemetry.i18n.yaml
#	.agents/notes/implemented/simplification/2026-08-06-buffer-free-feedback-telemetry.md
#	.agents/notes/implemented/simplification/2026-08-06-buffer-free-feedback-telemetry.zh.md
#	apps/web/tests/scaffold.ts
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	packages/api/session-controller/README.i18n.yaml
#	packages/api/session-controller/README.md
#	packages/api/session-controller/README.zh.md
#	packages/api/session-controller/src/client/sessions/assistant-stream.ts
#	packages/core/agent-loop/src/agent.ts
#	packages/core/agent-loop/src/assistant-stream.ts
#	packages/core/agent-loop/tests/loop.spec.ts
#	packages/core/agent/src/runtime-types.ts
#	packages/session/session-telemetry/tests/telemetry.spec.ts
#	packages/test-support/llm-replay/README.i18n.yaml
#	packages/test-support/llm-replay/README.md
#	packages/test-support/llm-replay/README.zh.md
#	packages/test-support/llm-replay/src/alpha-refusal-fixtures.ts
#	packages/test-support/llm-replay/src/index.ts
#	packages/test-support/llm-replay/tests/llm-replay.spec.ts
#	packages/test-support/session-snapshot/README.i18n.yaml
#	packages/test-support/session-snapshot/README.md
#	packages/test-support/session-snapshot/README.zh.md
#	packages/test-support/session-snapshot/src/suite.ts
#	packages/test-support/session-snapshot/tests/suite.spec.ts
#	snapshots/sdk/sdk.snapshot.ts
#	snapshots/session/headless.snapshot.ts
2026-09-03 03:10:05 +08:00
imccyu a66e470204 release(dsh): 0.1.2-rc.1 2026-09-03 02:27:19 +08:00
Tianyi Cui a65edc4810 fix(agent): terminate live assistant attempts 2026-09-03 02:25:25 +08:00
Tianyi Cui a5c24f204d Merge remote-tracking branch 'origin/worktree/session-format-03-v0-v1-migration' into worktree/session-format-04-live-assistant-stream 2026-09-03 02:02:47 +08:00
Tianyi Cui 731f1268d1 docs(snapshot): correct child replay ordering 2026-09-03 02:00:11 +08:00
Tianyi Cui f044d3fad2 fix(session): address v0 migration review 2026-09-03 01:52:25 +08:00
pku-xht bc681d7a54 fix(subprocess): harden cancellation settlement 2026-09-03 01:18:40 +08:00
pku-xht 05b6789425 fix(subprocess): preserve clean range after start errors 2026-09-03 00:59:07 +08:00
Turtle 0e6a397464 Merge pull request #3444 from deepseek-harness/turtle/migrate-issue-fields-to-project
fix(issue-management): use Project-local Priority
2026-09-03 00:58:00 +08:00
Turtle 692b9b59f7 fix(issue-management): complete policy token guards 2026-09-03 00:50:13 +08:00
pku-xht 35b5d78749 Merge origin/master into subprocess containment 2026-09-02 23:41:30 +08:00
pku-xht fe873955b4 Merge master@313ac567 into subprocess native containment 2026-09-02 23:00:02 +08:00
pku-xht ac1a5891c2 fix(subprocess): close remaining native containment findings 2026-09-02 22:49:46 +08:00
Tianyi Cui a8e33b62e3 Merge pull request #3434 from deepseek-harness/worktree-pkgnode
fix: Stop the packaged Python SDK runtime from hijacking spawned node commands
2026-09-02 22:47:27 +08:00
Tianyi Cui c2fa93f567 Merge remote-tracking branch 'origin/worktree/session-format-05-v1-v2-chunk-migration' into worktree/session-format-06-v2-snapshot-rollout
# Conflicts:
#	apps/web/tests/scaffold.ts
2026-09-02 22:21:50 +08:00
Tianyi Cui ac8b58241d Merge remote-tracking branch 'origin/worktree/session-format-04-live-assistant-stream' into worktree/session-format-05-v1-v2-chunk-migration
# Conflicts:
#	apps/web/tests/scaffold.ts
2026-09-02 22:19:50 +08:00
Tianyi Cui 08ef483c7a Merge remote-tracking branch 'origin/worktree/session-format-03-v0-v1-migration' into worktree/session-format-04-live-assistant-stream 2026-09-02 22:17:47 +08:00
Tianyi Cui 99567996bd test(session): cover body-free listing races 2026-09-02 22:16:06 +08:00
Tianyi Cui c0d05349e9 Merge remote-tracking branch 'origin/worktree/session-format-05-v1-v2-chunk-migration' into worktree/session-format-06-v2-snapshot-rollout 2026-09-02 21:59:19 +08:00
Yichen Jiang 8de7518c89 test(llm): replay Anthropic's documented model-listing example
The List Models reference reply joins the recorded listings so the
anthropic-messages path is pinned to the published response fields.
2026-09-02 21:58:58 +08:00
Yichen Jiang 31065cf1ab test(llm): archive recorded provider model listings
Replies captured on 2026-09-02 from OpenRouter, models.dev, and DeepSeek
replay through the discovery parser, and OpenRouter's nested
top_provider.max_completion_tokens now feeds the output-token cap.
2026-09-02 21:55:06 +08:00
Tianyi Cui 2087fd3f2c Merge remote-tracking branch 'origin/worktree/session-format-04-live-assistant-stream' into worktree/session-format-05-v1-v2-chunk-migration 2026-09-02 21:52:34 +08:00
Tianyi Cui e3e9bd5909 Merge remote-tracking branch 'origin/worktree/session-format-03-v0-v1-migration' into worktree/session-format-04-live-assistant-stream
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	packages/core/agent/src/runtime-types.ts
2026-09-02 21:51:42 +08:00
Tianyi Cui fe06dccea4 Merge remote-tracking branch 'origin/master' into worktree/session-format-03-v0-v1-migration
# Conflicts:
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	docs/persistence-catalog.i18n.yaml
#	docs/persistence-catalog.md
#	packages/api/session-controller/README.i18n.yaml
#	packages/api/session-controller/README.md
#	packages/api/session-controller/README.zh.md
2026-09-02 21:40:29 +08:00
Yichen Jiang 8179d929ab fix(llm): scope Anthropic /v1 handling to model discovery
Model requests hand the configured baseURL to pi-ai unchanged. Only the
discovery listing URL accepts the Anthropic API root with or without a
trailing /v1, because gateway documentation publishes both spellings.
2026-09-02 21:39:53 +08:00
Yichen Jiang b6427a899e Merge remote-tracking branch 'origin/master' into worktree/deepseek-harness-proxy-config-2f5b4a 2026-09-02 21:38:19 +08:00
imccyu 45a4868c88 test(python): pin packaged shell node resolution in the runtime smoke
The new keyless sdk-spawn-node scenario drives the platform shell tool
through a command starting with node and requires the machine's own Node
version in the tool result with no PKG_EXECPATH in the child environment,
so a pkg upgrade that re-records the child-process patch cannot silently
restore the hijack. Runs on every target through --scenario all.
2026-09-02 21:36:23 +08:00
imccyu 7187cddfb3 docs(notes): record the pkg child_process patch in the single-exe note 2026-09-02 21:36:23 +08:00
imccyu c732dedc69 fix(python): stop the packaged runtime from hijacking spawned node commands
@yao-pkg/pkg's SEA bootstrap rewrites child_process commands named node --
including the string after a -c flag, exactly the Bash tool's bash -c form --
to the executable itself and stamps PKG_EXECPATH into every child
environment, so a model-issued 'node --version' silently booted the dsh CLI
instead of the machine's Node. Pin the packager as an exact root
devDependency invoked through pnpm exec and patch out the single
patchChildProcess call from the SEA bootstrap bundle; packaged children now
resolve node through PATH like any other process. The third-party notices
drop the build-time tools section: the packager is now a declared, patched
devDependency, so the manifest and patch tiers disclose it.
2026-09-02 21:36:23 +08:00
Tianyi Cui 17f49f6191 fix(session): keep cold listing body-free 2026-09-02 21:29:43 +08:00
Tianyi Cui 9d3bbd46ee Merge pull request #3459 from deepseek-harness/revert-3452-feat/session-message-edit
Revert "feat(session, agent, web): support same-session message editing"
2026-09-02 21:21:14 +08:00
Tianyi Cui e974a655a0 Revert "feat(session, agent, web): support same-session message editing" 2026-09-02 21:20:07 +08:00
Yichen Jiang 6f7e30ed3b chore(http-proxy): follow the 0.1.2-alpha.5 release
master released 0.1.2-alpha.5 after this package was created, so the
release bump never reached it; the workspace constraints gate requires
every package version to match the root.
2026-09-02 21:19:00 +08:00
Yichen Jiang 5eb499ed35 Merge remote-tracking branch 'origin/master' into worktree/deepseek-harness-proxy-config-2f5b4a 2026-09-02 21:14:16 +08:00
Tianyi Cui d88c258dc7 Merge remote-tracking branch 'origin/worktree/session-format-03-v0-v1-migration' into worktree/session-format-04-live-assistant-stream
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	packages/core/agent/src/runtime-types.ts
2026-09-02 20:58:27 +08:00
07akioni f749b0dfb7 Merge remote-tracking branch 'origin/master' into HEAD
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/config-catalog.i18n.yaml
#	scripts/gen-cordis-catalog.ts
2026-09-02 20:54:40 +08:00
Tianyi Cui 5a9353adda Merge remote-tracking branch 'origin/master' into worktree/session-format-03-v0-v1-migration
# Conflicts:
#	docs/persistence-catalog.i18n.yaml
#	docs/persistence-catalog.md
2026-09-02 20:48:26 +08:00
lsdsjy f98bfbda85 Merge pull request #3452 from deepseek-harness/feat/session-message-edit
feat(session, agent, web): support same-session message editing
2026-09-02 20:41:36 +08:00
Tianyi Cui 06f29df392 Merge remote-tracking branch 'origin/worktree/session-format-05-v1-v2-chunk-migration' into worktree/session-format-06-v2-snapshot-rollout 2026-09-02 20:10:00 +08:00
07akioni b272d985f5 test(shell): bound pwsh readiness fallback 2026-09-02 20:09:22 +08:00
Tianyi Cui 3ed91ab9d8 Merge remote-tracking branch 'origin/worktree/session-format-04-live-assistant-stream' into worktree/session-format-05-v1-v2-chunk-migration 2026-09-02 20:09:13 +08:00
Tianyi Cui cd708659b5 Merge remote-tracking branch 'origin/worktree/session-format-03-v0-v1-migration' into worktree/session-format-04-live-assistant-stream 2026-09-02 20:08:34 +08:00
Tianyi Cui 086b52f986 test(session): cover generation scan failures 2026-09-02 20:07:48 +08:00
07akioni 9f05e5a077 test(shell): assert persistent pwsh result text 2026-09-02 19:55:03 +08:00
Tianyi Cui 4dbd107568 Merge remote-tracking branch 'origin/worktree/session-format-05-v1-v2-chunk-migration' into worktree/session-format-06-v2-snapshot-rollout 2026-09-02 19:41:24 +08:00
Tianyi Cui 58f5e0b278 Merge remote-tracking branch 'origin/worktree/session-format-04-live-assistant-stream' into worktree/session-format-05-v1-v2-chunk-migration 2026-09-02 19:40:50 +08:00
07akioni 29e60f2c30 fix(shell): avoid duplicate pwsh bootstrap 2026-09-02 19:40:28 +08:00
Tianyi Cui fe9d8b552c Merge remote-tracking branch 'origin/worktree/session-format-03-v0-v1-migration' into worktree/session-format-04-live-assistant-stream 2026-09-02 19:40:13 +08:00
Tianyi Cui 17f784c936 test(subagent): scope SIGKILL grace proof to POSIX 2026-09-02 19:34:52 +08:00
Tianyi Cui 68e24ddef9 fix(test): keep v2 fixture parsing content-only 2026-09-02 19:24:32 +08:00
Tianyi Cui 4a80818ddc Merge embedded stream migration into v2 snapshot rollout 2026-09-02 19:23:45 +08:00
Tianyi Cui af68f9e10c fix(test): qualify selected replay fixture 2026-09-02 19:22:57 +08:00
Tianyi Cui bc0e57a480 Merge live assistant stream into embedded stream migration
# Conflicts:
#	apps/web/tests/scaffold.ts
2026-09-02 19:21:52 +08:00
Tianyi Cui de3ee872d6 Merge session format migration into live assistant stream 2026-09-02 19:18:16 +08:00
Tianyi Cui aa97372fe4 fix(test): repair alpha fixture and Windows gates 2026-09-02 19:17:32 +08:00
07akioni 94651815f2 fix(shell): preserve pwsh prompt readiness 2026-09-02 19:15:38 +08:00
07akioni 633b3c0f69 fix(desktop): keep package helpers platform-neutral 2026-09-02 19:15:18 +08:00
Tianyi Cui 9e371c220d Merge embedded stream migration into v2 snapshot rollout 2026-09-02 19:05:54 +08:00
Tianyi Cui 23b9dc9175 Merge live assistant stream into embedded stream migration
# Conflicts:
#	apps/web/tests/scaffold.ts
#	packages/experimental/webworker-runtime/tests/vfs-example-fixture.spec.ts
2026-09-02 19:05:23 +08:00
Tianyi Cui 42542e9a3d Merge session format migration into live assistant stream 2026-09-02 19:02:32 +08:00
Tianyi Cui 0850261706 fix(test): align current session fixture headers 2026-09-02 19:01:41 +08:00
Tianyi Cui b5b4ef74a0 Merge embedded stream migration into v2 snapshot rollout 2026-09-02 18:50:56 +08:00
Tianyi Cui df7d1b6ee2 chore(release): align v2 format package with alpha.5 2026-09-02 18:50:24 +08:00
Tianyi Cui e12258e2b7 Merge live assistant stream into embedded stream migration 2026-09-02 18:49:39 +08:00
Tianyi Cui d8cc3e035e Merge session format migration into live assistant stream 2026-09-02 18:48:50 +08:00
Tianyi Cui e0604df362 chore(release): align session format packages with alpha.5 2026-09-02 18:47:59 +08:00
Tianyi Cui 2ca559dee3 Merge master into session format migration 2026-09-02 18:46:49 +08:00
Tianyi Cui 8de41bbe99 Merge embedded stream migration into v2 snapshot rollout
# Conflicts:
#	docs/testing.i18n.yaml
#	docs/testing.md
#	docs/testing.zh.md
#	packages/test-support/session-snapshot/README.i18n.yaml
#	packages/test-support/session-snapshot/README.md
#	packages/test-support/session-snapshot/README.zh.md
#	snapshots/session/read-image-attachment-path/session.v2.jsonl
#	snapshots/session/read-image-dimension/session.v2.jsonl
#	snapshots/session/read-image-reencode/session.v2.jsonl
#	snapshots/session/read-image/session.v2.jsonl
#	snapshots/web/navigation-panes/session.jsonl
#	snapshots/web/ptc-round/session.v2.jsonl
#	snapshots/web/pwsh-terminal/session.jsonl
#	snapshots/web/seeded-history/session.jsonl
2026-09-02 18:45:14 +08:00
07akioni 44d7ebf12f fix(release): keep desktop version aligned with dsh 2026-09-02 18:40:21 +08:00
07akioni e187001b04 Merge remote-tracking branch 'origin/master' into feat/electron 2026-09-02 18:32:40 +08:00
07akioni eeda3cb562 test: stabilize desktop and pwsh coverage checks 2026-09-02 18:32:27 +08:00
lsdsjy ef88756f13 feat(session, agent, web): support same-session message editing 2026-09-02 18:26:55 +08:00
Tianyi Cui c024c53d34 Merge pull request #3458 from deepseek-harness/xtr/record-browser-gif-gh-attach
docs(record-browser-gif): publish PR GIFs with gh --attach
2026-09-02 18:24:51 +08:00
07akioni 22461aedb0 feat(desktop): update packaging and auto-update paths for target-specific builds 2026-09-02 18:13:40 +08:00
Yichen Jiang ccecf4db04 fix(llm): address model discovery review 2026-09-02 18:00:43 +08:00
_Kerman 46d01068c6 Merge remote-tracking branch 'origin/master' into xtr/explicit-agent-context 2026-09-02 17:58:45 +08:00
Tianyi Cui 2f091ee8e6 docs(record-browser-gif): publish PR GIFs with gh --attach
Prefer gh v2.99.0's repeatable --attach flag for publishing demonstration
GIFs: it uploads the artifact and rewrites the body's local-path
reference in place, keeping media out of git history without an orphan
assets branch. The assets-branch workflow remains the fallback when the
GIF exceeds 10 MB, gh is older than v2.99.0, or the repository is not on
github.com.
2026-09-02 17:58:36 +08:00
_Kerman 0b8956aab9 refactor(agent): move runtime parent into options 2026-09-02 17:56:01 +08:00
Tianyi Cui 042bd8d01a Merge live assistant stream into embedded stream migration
# Conflicts:
#	packages/session/session-projection-cache/src/spec.ts
2026-09-02 17:52:32 +08:00
imccyu 49a606bc5b Merge pull request #3456 from deepseek-harness/release/dsh-0.1.2-alpha.5-version-to-master
sync: merge 0.1.2-alpha.5 to master
2026-09-02 17:47:12 +08:00
Tianyi Cui aa2616c570 Merge session format migration into live assistant stream 2026-09-02 17:45:59 +08:00
Tianyi Cui 3bdc1b37e5 Merge master into session format migration 2026-09-02 17:43:06 +08:00
Tianyi Cui cf9948b147 Merge master into session format migration
# Conflicts:
#	packages/session/session-projection-cache/tests/cache.spec.ts
2026-09-02 17:41:58 +08:00
creatixchu a1956fa3e2 Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload 2026-09-02 17:39:48 +08:00
Dudu-0223 f7cee2c888 Merge pull request #3333 from deepseek-harness/feat/3330-team-send-message-steer
feat(agent-team): unify messages on steer
2026-09-02 17:27:55 +08:00
imccyu cf126d8699 Merge remote-tracking branch 'origin/merge/projcache-v6-compat-into-master' into release/dsh-0.1.2-alpha.5-version-to-master 2026-09-02 17:25:23 +08:00
Tianyi Cui 25098647e8 Merge live assistant stream into embedded stream migration
# Conflicts:
#	.agents/notes/implemented/architecture/2026-06-14-session-persistence.i18n.yaml
#	.agents/notes/implemented/architecture/2026-06-14-session-persistence.md
#	.agents/notes/implemented/architecture/2026-06-14-session-persistence.zh.md
#	.agents/notes/implemented/architecture/2026-08-08-bounded-session-persistence-write-batching.i18n.yaml
#	.agents/notes/implemented/architecture/2026-08-08-bounded-session-persistence-write-batching.md
#	.agents/notes/implemented/architecture/2026-08-08-bounded-session-persistence-write-batching.zh.md
#	.agents/notes/implemented/feature/2026-08-10-web-session-log-export.i18n.yaml
#	.agents/notes/implemented/feature/2026-08-10-web-session-log-export.md
#	.agents/notes/implemented/feature/2026-08-10-web-session-log-export.zh.md
#	apps/cli/tests/profiles/headless/tests/session-format-guard.expected.e2e.ts
#	apps/web/tests/message-actions.e2e.ts
#	apps/web/tests/scaffold-generation.spec.ts
#	apps/web/tests/scaffold.ts
#	apps/web/tests/seeded-history.e2e.ts
#	apps/web/tests/subagent-conversation.e2e.ts
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/persistence-catalog.i18n.yaml
#	docs/persistence-catalog.md
#	docs/persistence-catalog.zh.md
#	docs/subsystems/persistence.i18n.yaml
#	docs/subsystems/persistence.md
#	docs/subsystems/persistence.zh.md
#	docs/subsystems/session.i18n.yaml
#	docs/subsystems/session.md
#	docs/subsystems/session.zh.md
#	packages/api/session-controller/tests/session-projections.host.spec.ts
#	packages/core/agent-loop/tests/resume.spec.ts
#	packages/session-query/session-query-sqlite/tests/sqlite.spec.ts
#	packages/session-query/session-query/tests/tracing.spec.ts
#	packages/session/session-persistence-jsonl/README.i18n.yaml
#	packages/session/session-persistence-jsonl/README.md
#	packages/session/session-persistence-jsonl/README.zh.md
#	packages/session/session-persistence-jsonl/src/index.ts
#	packages/session/session-persistence-jsonl/tests/jsonl.spec.ts
#	packages/session/session-persistence-jsonl/tests/zstd.spec.ts
#	packages/session/session-persistence/tests/contract.ts
#	packages/session/session-persistence/tests/coordinator-contract.ts
#	packages/session/session-persistence/tests/persistence.spec.ts
#	packages/subagent/subagent/src/continuation.ts
#	packages/subagent/subagent/tests/list-children.spec.ts
2026-09-02 17:20:51 +08:00
imccyu 0a1efddd40 Merge pull request #3455 from deepseek-harness/merge/projcache-v6-compat-into-master
sync: merge projection cache fix from 0.1.2-alpha.5 to master
2026-09-02 17:18:44 +08:00
Dudu-0223 eeddd457cd fix(agent-team): preserve mailbox order on cold resume 2026-09-02 17:14:44 +08:00
Dudu-0223 1180707084 Merge remote-tracking branch 'origin/master' into feat/3330-team-send-message-steer
# Conflicts:
#	packages/experimental/agent-team/tests/team.spec.ts
2026-09-02 16:58:09 +08:00
Yichen Jiang bfdebf1d22 test(llm): expect discovery name fallback 2026-09-02 16:56:06 +08:00
imccyu c917fe6d46 Merge remote-tracking branch 'origin/master' into merge/projcache-v6-compat-into-master
# Conflicts:
#	packages/session/session-projection-cache/src/spec.ts
#	packages/storage/storage-json/src/per-record-unit.ts
#	packages/storage/storage-json/tests/json-backend.spec.ts
2026-09-02 16:55:00 +08:00
07akioni 6bc42c47c2 Merge remote-tracking branch 'origin/master' into feat/electron 2026-09-02 16:45:36 +08:00
07akioni d5363c8839 feat(desktop): enhance auto-update configuration and add upload scripts 2026-09-02 16:32:12 +08:00
Yichen Jiang a6ed19b541 fix(llm): expand model listing discovery 2026-09-02 16:25:20 +08:00
Yichen Jiang 51c65c790d Merge remote-tracking branch 'origin/master' into worktree/deepseek-harness-proxy-config-2f5b4a 2026-09-02 16:11:28 +08:00
Turtle 9ea2329084 fix(issue-management): grant policy Project read access 2026-09-02 16:07:02 +08:00
imccyu 5a69ba1cdd Merge pull request #3445 from deepseek-harness/release/dsh-0.1.2-alpha.5
release: [email protected]
2026-09-02 15:57:43 +08:00
imccyu db6bdc3576 release(dsh): 0.1.2-alpha.5 2026-09-02 15:48:33 +08:00
imccyu 1915665e1e Merge pull request #3438 from deepseek-harness/fix/projcache-cross-version-read-compat
fix(session-projection-cache): survive upgrades across projcache domain versions
2026-09-02 15:47:14 +08:00
Turtle 39b151bda3 fix(issue-management): use Project-local Priority 2026-09-02 15:43:30 +08:00
imccyu db2dd2f840 docs(session-projection-cache): land the read-compat note as implemented and state fixture provenance in place
Review follow-ups: the Agent Note triplet moves to implemented/ rewritten as
shipped state (Decision/Consequences/Testing, present tense), cross-linked
both ways with the 2026-07-28 storage recovery proposal whose projcache
reset/destroy path it supersedes (that proposal stays live for authoritative
and whole-medium damage). The fixtures spec header and the note state the
fixture provenance as recorded facts of the released builds instead of
citing local tooling, and the spec JSDoc points at the note's final home.
2026-09-02 15:25:07 +08:00
imccyu bef26396e5 docs(session-projection-cache): cross-version read-compat note and schema-change fixture rule
The proposed Agent Note records the three shipped on-disk generations of
session_projcache, the read-compat and backup-and-skip decisions, the
upgrade matrix, and the rejected alternatives. The package README documents
the upgrade guarantees and requires every future schema or domain-version
change to land with archived fixtures and tests proving its upgrade story.
The storage subsystem page and the generated cordis catalog pick up the new
DomainSpec fields.
2026-09-02 15:25:07 +08:00
imccyu 49df707c86 fix(session-projection-cache): keep upgraded caches readable and boots safe across domain versions
The session_projcache domain declares compatibleVersions: [3, 4] and
invalidRecords: 'backup-and-skip'. The two lineage identity fields become
optional — records admitted from older versions predate them, and the single
reader (identityMatches) interprets absence as the unseeded lineage: exact
for unseeded sessions, while a seeded caller fails the match and refolds
cold, so the lineage binding keeps its protection. Upgraded homes therefore
boot and serve their cached listing titles immediately, including homes
whose new tree already holds current-stamped documents without lineage
fields, and a record failing validation anyway is backed up and skipped
instead of refusing the plugin tree.

tests/fixtures/ archives the real on-disk media of every shipped generation
(v3 whole-unit file, v4 and v5 per-record documents, and the lineage-less
current-stamped shape); fixtures.spec.ts proves each recovers through the
real storage stack, rewrites to the current format on the next live write,
and that a hopeless record is salvaged without costing the boot.
2026-09-02 15:25:07 +08:00
imccyu fcd109d29a feat(storage): version read compatibility and backup-and-skip salvage for per-record units
A DomainSpec may declare compatibleVersions: older domain versions whose
stored records the current record schemas still accept. The json backend's
per-record reads admit documents stamped with a declared version (writes
always stamp the current one), and the legacy whole-unit bootstrap migrates
only a file whose stored version is in the accepted set — previously it
migrated any version and stamped the records current, turning a discardable
stale cache into invalid-record failures that refused the whole domain at
open and permanently poisoned the new tree on first boot.

A DomainSpec may also declare invalidRecords: 'backup-and-skip' for domains
whose records are disposable derived data: a stored record failing its zod
schema is moved aside through the new optional KvUnit.backupRecord
(<key>.json.bak.<YYYYMMDDHHmm> under the json backend), logged with its
cause, and skipped, instead of rejecting the open. The default stays
fail-loud, and so do backends without backupRecord.
2026-09-02 15:25:07 +08:00
creatixchu 80b376f0ff Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload 2026-09-02 15:24:07 +08:00
Turtle 66ca93c3dc Merge pull request #3441 from deepseek-harness/turtle/fix-project-date-fields
fix(issue-management): restore Project date fields
2026-09-02 15:20:46 +08:00
Turtle 070b46e1ef fix(issue-management): restore Project date fields 2026-09-02 15:06:25 +08:00
_Kerman 600dff4ca4 test(tool-subagent): cover missing session registry 2026-09-02 14:34:10 +08:00
creatixchu 8d1289420b Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload
# Conflicts:
#	packages/client/ui-attachment/README.i18n.yaml
#	packages/client/ui-attachment/README.md
#	packages/client/ui-attachment/README.zh.md
2026-09-02 14:05:03 +08:00
_Kerman 8292ea45ba fix(tool-subagent): simplify standing preset cleanup 2026-09-02 13:58:11 +08:00
Tianyi Cui 9007b56360 Merge session format migration lint fix 2026-09-02 13:54:42 +08:00
Tianyi Cui 2372f84206 Merge session format migration into live assistant stream
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
2026-09-02 13:54:23 +08:00
Tianyi Cui 2b529bc2aa test(session-persistence-jsonl): keep migration assertions typed 2026-09-02 13:50:00 +08:00
Tianyi Cui 91e5f8838e Merge master into session format migration 2026-09-02 13:42:50 +08:00
Turtle be70505f9e Merge pull request #3417 from deepseek-harness/turtle/fix-issue-field-start-date
fix(issue-management): write Start date through Issue fields
2026-09-02 13:41:29 +08:00
Tianyi Cui 723980ac78 Merge master into session format migration
# Conflicts:
#	packages/experimental/webworker-runtime/tests/vfs-example-fixture.ts
2026-09-02 13:41:24 +08:00
_Kerman 02b889bff6 Merge remote-tracking branch 'origin/master' into xtr/explicit-agent-context
# Conflicts:
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	docs/subsystems/core.i18n.yaml
#	docs/subsystems/core.md
#	docs/subsystems/core.zh.md
#	packages/api/remotes/package.json
#	packages/core/agent-loop/README.i18n.yaml
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/README.zh.md
#	packages/core/agent-loop/src/index.ts
#	packages/core/agent-loop/tests/resume.spec.ts
#	packages/subagent/subagent/src/continuation.ts
#	packages/subagent/tool-subagent/src/index.ts
#	packages/subagent/tool-subagent/src/model-selection-settings.ts
#	packages/typert/protocol/README.i18n.yaml
#	packages/typert/protocol/README.md
#	packages/typert/protocol/README.zh.md
2026-09-02 13:39:30 +08:00
Yichen Jiang bbae7318f0 Merge pull request #3424 from deepseek-harness/worktree/github-issue-725-verification-7e80bd
fix(llm): keep streamed tool-call identity across empty deltas
2026-09-02 13:35:55 +08:00
Tianyi Cui 7145acfe07 Merge master into session format migration
# Conflicts:
#	.agents/notes/archived/architecture/2026-06-18-shared-persistence-write-coordinator.i18n.yaml
#	.agents/notes/implemented/architecture/2026-06-14-session-persistence.i18n.yaml
#	.agents/notes/implemented/architecture/2026-06-14-session-persistence.md
#	.agents/notes/implemented/architecture/2026-06-14-session-persistence.zh.md
#	.agents/notes/implemented/architecture/2026-07-24-project-session-directories.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-24-project-session-directories.md
#	.agents/notes/implemented/architecture/2026-07-24-project-session-directories.zh.md
#	.agents/notes/implemented/architecture/2026-08-05-session-preparation.i18n.yaml
#	.agents/notes/implemented/architecture/2026-08-05-session-preparation.md
#	.agents/notes/implemented/architecture/2026-08-05-session-preparation.zh.md
#	.agents/notes/implemented/architecture/2026-08-10-message-feedback-sidecar.i18n.yaml
#	.agents/notes/implemented/architecture/2026-08-10-message-feedback-sidecar.md
#	.agents/notes/implemented/architecture/2026-08-10-message-feedback-sidecar.zh.md
#	.agents/notes/implemented/architecture/2026-08-27-handle-based-session-persistence.i18n.yaml
#	.agents/notes/implemented/bug-fix/2026-07-28-load-pre-identity-session-messages.md
#	.agents/notes/implemented/bug-fix/2026-07-28-load-pre-identity-session-messages.zh.md
#	.agents/notes/implemented/bug-fix/2026-08-04-load-pre-react-loop-sessions.md
#	.agents/notes/implemented/bug-fix/2026-08-04-load-pre-react-loop-sessions.zh.md
#	.agents/notes/implemented/bug-fix/2026-09-01-host-goal-pause-aborts-turn.i18n.yaml
#	.agents/notes/implemented/feature/2026-08-10-web-session-log-export.i18n.yaml
#	.agents/notes/implemented/feature/2026-08-10-web-session-log-export.md
#	.agents/notes/implemented/feature/2026-08-10-web-session-log-export.zh.md
#	apps/cli/tests/profiles/headless/tests/session-format-guard.expected.e2e.ts
#	apps/web/tests/cold-blank-session.e2e.ts
#	apps/web/tests/message-actions.e2e.ts
#	apps/web/tests/scaffold.ts
#	apps/web/tests/workspace-management.e2e.ts
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/persistence-catalog.i18n.yaml
#	docs/persistence-catalog.md
#	docs/subsystems/feedback.i18n.yaml
#	docs/subsystems/feedback.md
#	docs/subsystems/feedback.zh.md
#	docs/subsystems/persistence.i18n.yaml
#	docs/subsystems/persistence.md
#	docs/subsystems/persistence.zh.md
#	packages/acp/acp/src/index.ts
#	packages/acp/acp/tests/bridge.spec.ts
#	packages/api/session-controller/src/list.ts
#	packages/api/session-controller/tests/agent.host.spec.ts
#	packages/api/session-controller/tests/session-cold.host.spec.ts
#	packages/api/session-controller/tests/session-projections.host.spec.ts
#	packages/api/session-controller/tests/session-search.host.spec.ts
#	packages/api/session-controller/tests/test-remote.ts
#	packages/api/session-controller/tests/transport.host.spec.ts
#	packages/core/agent-loop/src/index.ts
#	packages/core/agent-loop/tests/config-session-id.spec.ts
#	packages/core/agent-loop/tests/resume.spec.ts
#	packages/extensions/tool-cordis/src/api-catalog.ts
#	packages/feedback/message-feedback/src/index.ts
#	packages/feedback/message-feedback/tests/helpers.ts
#	packages/feedback/message-feedback/tests/message-feedback.spec.ts
#	packages/session-query/session-log-export/src/archive.ts
#	packages/session-query/session-log-export/tests/archive.host.spec.ts
#	packages/session-query/session-log-export/tests/route.host.spec.ts
#	packages/session-query/session-query-sqlite/README.i18n.yaml
#	packages/session-query/session-query-sqlite/README.md
#	packages/session-query/session-query-sqlite/README.zh.md
#	packages/session-query/session-query-sqlite/src/index.ts
#	packages/session-query/session-query-sqlite/tests/sqlite.spec.ts
#	packages/session-query/session-query/README.i18n.yaml
#	packages/session-query/session-query/README.md
#	packages/session-query/session-query/README.zh.md
#	packages/session-query/session-query/src/corpus.ts
#	packages/session-query/session-query/tests/observation.spec.ts
#	packages/session-query/session-query/tests/session-query.spec.ts
#	packages/session-query/session-query/tests/tracing.spec.ts
#	packages/session/session-checkpoint-policy/tests/session-checkpoint-policy.spec.ts
#	packages/session/session-persistence-jsonl/README.i18n.yaml
#	packages/session/session-persistence-jsonl/README.md
#	packages/session/session-persistence-jsonl/README.zh.md
#	packages/session/session-persistence-jsonl/src/index.ts
#	packages/session/session-persistence-jsonl/tests/jsonl.spec.ts
#	packages/session/session-persistence-jsonl/tests/zstd.spec.ts
#	packages/session/session-persistence/README.i18n.yaml
#	packages/session/session-persistence/README.md
#	packages/session/session-persistence/README.zh.md
#	packages/session/session-persistence/src/coordinator.ts
#	packages/session/session-persistence/src/index.ts
#	packages/session/session-persistence/tests/contract.ts
#	packages/session/session-persistence/tests/coordinator-contract.ts
#	packages/session/session-persistence/tests/persistence.spec.ts
#	packages/session/session-telemetry/package.json
#	packages/shell/tool-bash/tests/tools.spec.ts
#	packages/subagent/subagent/src/continuation.ts
#	packages/subagent/subagent/tests/list-children.spec.ts
#	packages/workspace/workspace/src/index.ts
#	packages/workspace/workspace/tests/workspace.spec.ts
#	scripts/gen-cordis-catalog.ts
2026-09-02 13:34:40 +08:00
Chinesezjc a631115597 Merge pull request #2828 from deepseek-harness/feat/toolcard-image-result
feat(ui-tool): render read_image results as the image
2026-09-02 12:45:39 +08:00
Magolor d921d4b357 fix(storage-json): reject cross-version legacy bootstrap (#3431)
* fix(storage-json): reject cross-version legacy bootstrap

* test(webworker): sync projection cache fixture version

* docs(storage): record legacy bootstrap version ownership
2026-09-02 04:37:15 +00:00
Chinesezjc 3648331b11 Merge remote-tracking branch 'origin/master' into feat/toolcard-image-result
# Conflicts:
#	packages/client/ui-chat/src/client/chat/ChatNodeSeat.tsx
#	packages/client/ui-chat/src/client/chat/ChatView.tsx
#	packages/extensions/cordis-client-runner/src/client/slot-catalog.ts
2026-09-02 12:02:25 +08:00
Chinesezjc e4c822544c test(pwsh): restore product-default deadline in loader composition
The first call pays the full pwsh cold-start latency (spawn + .NET +
PSReadLine + Defender) inside the tool deadline. A 60s bound on the fully
loaded self-hosted Windows pool is exceeded often enough to reset the
session mid-test: two master CI runs (2026-09-01, runs 33524764567 and
33534262413) each failed at ~62s with the second call observing a fresh
session (cwd back at root, env empty). 300s matches the product default
so cold start no longer races the budget.
2026-09-02 11:50:18 +08:00
_Kerman c8f76ca399 chore: remove unrelated changes from Inbox PR 2026-09-02 11:36:46 +08:00
Xu Hanxiang d3ab4ce53d Merge pull request #3401 from deepseek-harness/issue-1424-goal-pause-stop-turn
fix(goal): abort the live turn on host-initiated pause
2026-09-02 11:32:12 +08:00
_Kerman 8fa72e3d60 fix(chat): settle scroll sample before resize follow 2026-09-02 11:26:45 +08:00
Turtle d76c974fbb Merge branch 'master' into turtle/fix-issue-field-start-date 2026-09-02 11:13:10 +08:00
creatixchu 2217ba42d7 fix(ui): align attachment cards with theme constraints 2026-09-02 11:01:45 +08:00
Yichen Jiang 6d261ecdee test(app-boot): assert the home .env proxy contract without pinning a casing
Windows folds `https_proxy` and `HTTPS_PROXY` into one variable, so the
exported spelling shadowed the file's lowercase one and the case failed
there. Each spelling now gets its own name: the file supplies a name the
shell did not export, and the shell outranks the file for the one it did.
2026-09-02 10:51:20 +08:00
Yichen Jiang 1fc6016f85 chore(http-proxy): match the workspace version bumped on master
The 0.1.2-alpha.4 release on master touched every manifest that existed
there; this package did not, so the merge left it at alpha.3 and
`check-workspace-constraints` refused the tree.
2026-09-02 10:36:10 +08:00
Yichen Jiang b03261caad fix(llm): narrow the fix to identity acceptance
Refusing a response whose tool call never receives an identity needed a new
failure code, a change to the default retryable set, and a `[DONE]` gate that
overrode the finish reason a provider had already sent — turning a safe
`max-tokens` truncation into up to five retries. The lenient wire it guarded
against is hypothetical: no report describes a stream that omits identity
entirely, and the pre-existing test for it is labelled as such.

Only `acceptIdentity` and the widened wire types remain. They close the
reported erasure and cannot reach a worse outcome than the previous
assignment, because the set of inputs that assign only narrows.
2026-09-02 10:34:09 +08:00
creatixchu 3b9ac476fb Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload
# Conflicts:
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	docs/persistence-catalog.i18n.yaml
#	docs/persistence-catalog.md
#	docs/persistence-catalog.zh.md
#	packages/api/session-controller/src/commands.ts
#	packages/api/session-controller/src/index.ts
#	packages/api/session-controller/tests/client-contract.client.spec.ts
#	packages/api/session-controller/tests/session-pending-submissions.client.spec.ts
#	packages/client/ui-attachment/src/AttachmentRail.module.css
#	packages/client/ui-chat/src/client/chat/MessageItem.tsx
#	packages/client/ui-conversation/src/client/skeleton/InputBar.tsx
#	packages/client/ui-trajectory/README.i18n.yaml
#	packages/client/ui-trajectory/README.md
#	packages/client/ui-trajectory/README.zh.md
#	packages/extensions/cordis-client-runner/src/client/api-catalog.ts
#	packages/llm/token-meter/src/surface-fold.ts
#	packages/session-query/session-log-export/src/archive.ts
#	packages/session-query/session-log-export/tests/archive.host.spec.ts
2026-09-02 10:29:53 +08:00
Yichen Jiang e7170b05a1 Merge remote-tracking branch 'origin/master' into worktree/deepseek-harness-proxy-config-2f5b4a 2026-09-02 10:28:17 +08:00
Yichen Jiang 93bba8ef67 fix(http-proxy): withhold NODE_USE_ENV_PROXY when the child receives a refused proxy value
`proxyEnvironmentForChild()` hands a child the proxy values the user
exported, including one this package refused — a SOCKS URL kept because
`curl` reads it — and sets `NODE_USE_ENV_PROXY=1` so a child Node honors
them. Node parses `HTTP_PROXY` and `HTTPS_PROXY` under that flag before
running the program and exits on any scheme other than `http:` or
`https:`. So a user with a usable `HTTP_PROXY` and `HTTPS_PROXY=socks4://…`
lost every Node child — stdio MCP servers, subagent CLIs, `npm` in the
bash tool — before its first line, while this process had reported only
that the scheme stayed direct. Measured on Node 24.17: `socks4://`,
`ftp://`, and a malformed value all exit 1; `socks5://` is accepted there
and only there.

The flag is now withheld whenever a value under the names Node parses is
one `isSupportedProxyUrl` refuses. Such a child connects directly, which
is what this process already said about that scheme, and `curl` still
reads the value it was kept for. Node does not read `ALL_PROXY`, so a
refused value there alone changes nothing.

The socks5 case in `install.spec.ts` now asserts the flag absent; the
ALL_PROXY fill case asserts it present; a new case spawns a real child
Node under the overlay for each refused shape and asserts it starts.
2026-09-02 10:27:36 +08:00
_Kerman 3c9410904e Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	packages/api/session-controller/tests/session-projections.host.spec.ts
#	packages/core/agent-loop/src/index.ts
#	packages/experimental/agent-team/tests/persistence.spec.ts
#	packages/experimental/agent-team/tests/team.spec.ts
#	packages/session-query/session-query/tests/observation.spec.ts
#	packages/test-support/agent-loop-testkit/package.json
2026-09-02 10:26:43 +08:00
Yichen Jiang 6ecdc93901 fix(http-proxy): give children the user's environment under a layered direct policy
A direct policy installed over a proxied one swapped the global
dispatcher but left `process.env` holding the outer install's published
normalization. `proxyEnvironmentForChild()` returns nothing under a
direct policy, and `scrubbedParentEnv()` copies `process.env` as it is,
so a child spawned in that window inherited values no active policy
stood behind: an `HTTPS_PROXY` derived from `HTTP_PROXY` the user never
set, or the loss of a SOCKS value they set for `curl` and this package
had refused.

The direct branch now writes the user's own values — the record the
outermost install keeps — back into `process.env` for the window, and
re-applies the outer install's published values when it ends. An
install underneath that proxied nothing published nothing, so there is
nothing to put back. Publishing and restoring share one `writeProxyEnv`;
the empty-string special case it replaced was unreachable, since a
resolved bypass list always carries the loopback entries and an
accepted proxy URL is never empty.

The nesting is reachable only from tests since the plugin was removed;
the fix keeps the disposer symmetric for whoever layers installs next.
2026-09-02 10:19:23 +08:00
Yichen Jiang 83931a5f3e fix(llm): correct the refusal's recorded rationale
`LlmRuntime.adapterStream` normalizes a thrown `LlmError` into the same error
`finish` the loop routes to `agent/request-error`, so throwing would reach
retry too. The Note claimed otherwise. Yielding is chosen because it reports
the attempt's billed usage first and matches the neighbouring `EMPTY_RESPONSE`
refusal.

The rejection comment repeats the corrected durability wording, and the
assembler's delta-only fallback carries a TODO for the empty name it still
invents for adapters that never close a tool-call block.
2026-09-02 10:08:42 +08:00
Yichen Jiang c44dcb7b85 fix(app-boot): accept the proxy names from the Harness-home .env alone
The proxy guide told users a proxy could live in a project or
`$DSH_HOME` `.env`. It could not: `loadLayeredEnv` refuses the four
proxy names from any discovered file, as it refuses `PATH` and
`NODE_OPTIONS`, and the launch fails with a pointer to `export`.

That refusal is right for the invoking directory's file — it arrives
with a clone, and a repository must not choose where the harness sends
its traffic — and wrong for the user's own `$DSH_HOME/.env`, which
already holds their API key. `readEnvLayer` now accepts `HTTP_PROXY`,
`HTTPS_PROXY`, `ALL_PROXY`, and `NO_PROXY` from the directory that is
the Harness home, and nowhere else. `DSH_HOME` is itself bootstrap-only,
so no `.env` can relocate the exemption; the CA and TLS names in the
same group stay refused everywhere, since they change what is trusted
rather than where traffic goes. A project `.env` that sets a proxy name
still fails the launch, and its message now names the home file as the
second way out. Launching from inside the home directory reads that one
file as the project layer; the exemption follows the directory.

The seven existing refusal cases all write to the project layer and
pass unchanged. Four new cases cover the home layer accepting both
casings below an exported value, the home layer still refusing
`SSL_CERT_FILE`, the project layer's new message, and the same-directory
launch. The guide, both package READMEs, and the two Agent Notes that
stated the old rule now state this one.
2026-09-02 10:04:59 +08:00
Yichen Jiang e91c28d3fd fix(llm): cover the malformed tool-call path and correct its records
The `MALFORMED_TOOL_CALL` JSDoc claimed nothing durable is written, but the
loop appends an `assistant/chunk` for every yielded chunk; only the assistant
message and tool result are withheld. The bounded-recovery Note still listed
a five-code transient set, and neither Note linked the other.

A keyless `malformed-tool-call-retry` scenario now records the refusal, the
retry, and the absence of a `tool/call` for the failed attempt. A translator
case pins that an already closable block also withholds its `block-end`.
2026-09-02 10:01:56 +08:00
Yichen Jiang 2795940323 docs(http-proxy): state the shipped library, not the retired plugin
Review found the package's prose still describing a plugin that an
earlier revision removed, and three factual slips about behavior.

- policy.ts, install.ts, install.spec.ts, and the Agent Note named a
  `Config` surface, a `cordis.yml` source, a mountable plugin, and a
  `plugin.spec.ts` that no longer exist; each now describes the
  environment-only resolution the launcher actually runs.
- `NO_PROXY=example.com` bypasses `api.example.com` as well — the matcher
  accepts the host and every subdomain under it, and a leading `.` or
  `*.` means the same thing. The guide, README, and JSDoc claimed a bare
  entry matched only the exact host, which would let a reader believe a
  subdomain was proxied when it went direct.
- A rejection diagnostic names the variable and never its value, so no
  username is shown; the guide said the username was shown with the rest
  masked. The README's source map claimed a "redaction" step that does
  not exist.
- The `node:https` worker placeholder was added for a `node:http` agent
  factory this PR later removed; nothing imports `node:https` now, so the
  stub, its VFS mapping, and its test return to their state on master.
2026-09-02 09:43:47 +08:00
Yichen Jiang 96cbd8d9e6 fix(llm): refresh web and packed-fixture expectations for the new retry code
Adding `MALFORMED_TOOL_CALL` to the default retryable set changes two
expected outputs the session snapshot lane does not own: the shipped Web
composition's inline snapshot, and the canonical packed layout of the
refreshed `empty-response-retry` fixture.
2026-09-02 09:36:54 +08:00
07akioni a596a02bbd test(desktop): load pnpm fixture by file URL 2026-09-02 08:26:16 +08:00
Tianyi Cui 9424841d68 test(snapshot): retain failed reasoning projection 2026-09-02 04:46:35 +08:00
Tianyi Cui 343a20fb6f refactor(snapshot): remove dead fixture path plumbing 2026-09-02 04:46:02 +08:00
Tianyi Cui f693946509 test(snapshot): roll corpus forward to format v2 2026-09-02 04:18:52 +08:00
Tianyi Cui eb7c290b22 fix(session): retain reachable v2 stream settlements 2026-09-02 04:17:44 +08:00
Tianyi Cui 0670239db2 chore(deps): classify session stream helpers 2026-09-02 04:00:33 +08:00
Tianyi Cui f30896394c test(web): restore HMR build artifacts 2026-09-02 04:00:33 +08:00
Tianyi Cui 7e5b72ceee fix(session): harden embedded assistant streams 2026-09-02 04:00:33 +08:00
Tianyi Cui f99b06eaed feat(session)!: embed assistant streams in format v2 2026-09-02 04:00:01 +08:00
Tianyi Cui 0bb7bba015 fix(session): close live assistant framing races 2026-09-02 03:49:17 +08:00
Tianyi Cui 30e045dfad feat(agent): emit live assistant stream frames 2026-09-02 03:36:13 +08:00
Tianyi Cui eb56627f36 test(snapshot): retire vanished generation roles 2026-09-02 03:34:52 +08:00
Tianyi Cui 79f27df0dd fix(session): harden migration artifact ownership 2026-09-02 03:34:38 +08:00
Turtle 8b799cd7ac Merge pull request #3266 from deepseek-harness/refactor/session-persistence-handle-seam
refactor(session-persistence)!: handle-based seam with a lifecycle-owned write path
2026-09-02 00:50:53 +08:00
imccyu 4e84901e64 Merge pull request #3427 from deepseek-harness/release/dsh-0.1.2-alpha.4
release: [email protected]
2026-09-01 23:37:26 +08:00
imccyu a9e185f205 release(dsh): 0.1.2-alpha.4 2026-09-01 23:19:57 +08:00
Turtle bec6805d6a refactor(session-persistence)!: handle-based seam with a lifecycle-owned write path
The persistence seam is now create/open/stat/list returning per-session
SessionHandles (read/append/flush/close); every log read and write flows
through the owning handle. The seam package exports only the service and
handle contracts, consumer-visible errors, and pure durable-data
validation helpers; each backend owns its complete storage runtime, and
the shared contract suites pin equivalent observable behavior. The
backend routes published sessions' live events by id into the active
write handle; agent-loop only acquires, seeds, and closes the handle.
Resume appends interruptedTurnClosers through its write handle;
session-query owns the revision-keyed cold cache. Legacy-only surfaces
are removed in the same swap: locate/readRaw/supportsRawArtifacts, the
legacy event-shape read migration, zstd torn-frame salvage,
DSH_SESSION_JSONL, and hook transcript_path population; a torn final
zstd frame is discarded whole; the session-list cold blank probe returns
on stat metadata (eventCount derived from the last physical row,
sizeBytes). The WebUI ZIP export serializes the logical log from a read
handle, so both backends export identically.

Refs #3245
2026-09-01 23:19:02 +08:00
Tianyi Cui 3c5b7097ae Merge pull request #3425 from deepseek-harness/feat/ptc-disable-workflow-plugin
feat(presets): omit workflow from Web PTC mode
2026-09-01 23:18:39 +08:00
imccyu 1f694c88ab Merge pull request #3391 from deepseek-harness/worktree-chatperf
perf(web): reduce conversation rendering and layout overhead
2026-09-01 23:16:50 +08:00
imccyu e32437d18b perf(chat): throttle scroll geometry sampling 2026-09-01 23:06:52 +08:00
imccyu 4e4733c50b test(web): await turn-tail stream publication 2026-09-01 22:55:17 +08:00
fz 0cdcc9c3c5 feat(presets): omit workflow from PTC mode 2026-09-01 22:45:09 +08:00
imccyu e427d5746e fix: ci 2026-09-01 22:41:42 +08:00
Tianyi Cui c3e5bd7dae Merge pull request #3418 from deepseek-harness/fix/ptc-note-cloudflare-link
docs: restore Cloudflare's Code Mode name and blog link in PTC Agent Note
2026-09-01 22:36:56 +08:00
imccyu 9ef0e28000 test(web): await streamed text before snapshot 2026-09-01 22:36:05 +08:00
imccyu 0e90d47d19 perf(chat): skip stable node list mapping 2026-09-01 22:29:46 +08:00
Yichen Jiang a1271a4903 fix(llm): keep streamed tool-call identity across empty deltas
A continuation SSE delta that repeats a tool call's `id` or `name` as an
empty string — or as `null`, which some OpenAI-compatible gateways send —
erased the identity established by the call's first delta. The assembled
block reached the loop with an empty name and failed as `unknown tool ""`,
and the empty `callId` persisted into `tool/result`, which the session
reader refuses on reopen.

`acceptIdentity` accepts only a non-empty string, so a repeated empty or
null field means "no update". A tool call still missing `id` or `name` at
`[DONE]` ends the response with the new retryable `MALFORMED_TOOL_CALL`
code instead of closing an unusable block.
2026-09-01 22:22:51 +08:00
imccyu 577f0cf7d9 refactor(client): bind keyed chat sources in renderer 2026-09-01 22:22:25 +08:00
Tianyi Cui d1521ea783 feat(session)!: add released format migration 2026-09-01 22:12:21 +08:00
imccyu b8a19413e9 fix(client): satisfy strict observable contracts 2026-09-01 22:01:18 +08:00
_Kerman c3447a2c15 test(headless): cover pre-turn inbox events 2026-09-01 22:00:59 +08:00
Yichen Jiang 0d99bd0489 docs: regenerate the module graph without the telemetry proxy edge
Reverting telemetry to its own transport dropped the package's dependency
on the proxy library, and the generated graph still recorded that edge.

The gate that catches this is `verify-module-graph`, which runs in
`check:ci:static` and not in `doc-sync`; the revert was checked with the
latter alone.
2026-09-01 21:59:50 +08:00
Yichen Jiang 13daefe073 revert(session-telemetry-otel): leave telemetry on its own transport
Telemetry was the only call site this PR could not cover without changing
the SDK transport underneath it, and both ways of doing that cost more
than the channel is worth.

Routing an `http.Agent` needs Node's `proxyEnv`, added in 22.21 and 24.5
— inside the engines range, so three supported runtimes stayed direct
anyway, and the proxy package had to keep a `createNodeHttpAgent` export
for a path that only sometimes worked. Replacing the transport with the
SDK's `fetch` delegate covered every runtime but has no compression,
while the shipped `base` bundle enables gzip and a realistic OTLP batch
is 6.4x smaller with it; keeping both meant gzipping at the serializer,
which put transport code inside a telemetry plugin.

Telemetry is the one outbound channel whose loss costs the user nothing:
no tool, model request, or session depends on it, and an export that
cannot connect is already dropped silently. A user behind a mandatory
proxy is left where they were rather than regressed.

`src/index.ts`, `otel.spec.ts`, and `tsconfig.json` return to their state
on master; the package keeps only a dev dependency on the proxy library.
`egress.spec.ts` inverts: it installs a policy and asserts the fake proxy
saw nothing, so an SDK upgrade that moved the exporter onto `fetch` would
surface as a failing test rather than silently routing telemetry.
2026-09-01 21:51:29 +08:00
_Kerman 6f4b38ea2e docs: refresh agent loop testkit graph 2026-09-01 21:50:28 +08:00
_Kerman ec51b7651f Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	packages/api/session-controller/tests/session-projections.host.spec.ts
#	packages/context/agent-instructions/tests/agent-instructions.spec.ts
#	packages/core/agent/src/inbox.ts
#	packages/goal/tool-goal/tests/tool-goal.spec.ts
#	packages/skill/tool-skill/tests/tool-skill.spec.ts
#	packages/terminal/terminal-bash/tests/index.spec.ts
2026-09-01 21:46:31 +08:00
imccyu de07b4c05b chore(ui-chat): document local keyed sources 2026-09-01 21:46:08 +08:00
Yichen Jiang b518286735 fix(session-telemetry-otel): keep gzip on the fetch transport
The previous commit moved the OTLP exporter to the SDK's `fetch` delegate
and refused `exporter.compression` at load, on the belief that nothing
shipped enabled it. `packages/bundle/base/cordis.patch.yml` does, so the
refusal broke every test that boots the shipped bundle — the snapshot,
e2e, and Windows observational jobs all failed on that one load error.

Dropping gzip was the wrong trade anyway: a realistic OTLP batch measures
6.4x smaller with it, so trading it for proxy support would have charged
every deployment to fix one. The `fetch` transport has no compression
hook, but serialization is the seam before the body reaches it — the
plugin now gzips there and declares `Content-Encoding` itself.

`keepAlive` and `httpAgentOptions` have no such seam, since they
configure a connection pool `fetch` does not expose, so those two stay
refused at load rather than accepted and ignored. `compression` is typed
as the two values this package can actually apply rather than the SDK's
wider enum, and a third value fails loud at load.
2026-09-01 21:42:09 +08:00
_Kerman dc160810da test(agent-loop): use production inbox harness 2026-09-01 21:39:10 +08:00
imccyu a718d1f0a1 docs(client): record conversation performance boundaries 2026-09-01 21:31:04 +08:00
Tianyi Cui b74486ab29 docs: restore Cloudflare's Code Mode name and blog link in PTC note
The code-mode → ptc rename rewrote Cloudflare's product name in the
link text and the external URL path, leaving "PTC mode" pointing at
https://blog.cloudflare.com/ptc/ (404). Restore Cloudflare's own name
and the working https://blog.cloudflare.com/code-mode/ link in both
the English and Chinese notes.
2026-09-01 21:27:44 +08:00
Yichen Jiang bdd294dc47 Merge remote-tracking branch 'origin/master' into worktree/deepseek-harness-proxy-config-2f5b4a 2026-09-01 21:21:22 +08:00
imccyu 2e21d210a5 fix(trajectory): reanchor replaced history windows 2026-09-01 21:17:47 +08:00
Yichen Jiang 8470ddef1d refactor(http-proxy): converge the proxy API on four functions
The package exported six functions, four of them shaped by one SDK's
transport each: a dispatcher factory, a `node:http` agent factory, a
proxy-URL lookup, and a policy accessor. Review asked whether the call
sites could converge instead of the package growing an export per SDK.

They could, and each removal took a whole shape with it:

- The OTLP exporter moves to the SDK's `fetch` delegate, retiring
  `createNodeHttpAgent`. Its Node-version floor goes too: `proxyEnv` on
  an `http.Agent` needs 22.21 or 24.5, inside the engines range, so
  telemetry was direct on 22.19, 22.20, and 24.0-24.4. The cost is
  `compression`, a Node-transport option; the plugin now refuses it,
  `keepAlive`, and `httpAgentOptions` at load instead of ignoring them.
- `web-fetch-http` builds its own address-pinning agent under an
  annotated `proxy-exempt:` exemption, retiring `createDispatcher`.
  Pinning is per-request state a process-wide dispatcher cannot hold.
- E2B reads `route.proxy`, retiring `proxyUrlFor`.

What remains is `installProxyFromEnvironment`, `proxyRouteFor`,
`proxyEnvironmentForChild`, and `clearedProxyEnv` — one per way a caller
can need the policy. Installation absorbs resolution and diagnostic
reporting, which no caller needed apart.

`proxyRouteFor` also closes a defect the old accessor made expressible:
`web-fetch-http` read the policy to decide whether to pin, then read it
again to build a transport, so an unmount between the two returned a
direct, unpinned agent for a URL the first read had cleared as proxied.
A route carries the answer and the transport that answer assumed.

Every egress spec now installs through `installProxyFromEnvironment`, so
no test asserts a policy object a real launch could not produce.
2026-09-01 21:15:04 +08:00
imccyu 7db2bab853 test(conversation): brand fixture sequences 2026-09-01 21:14:19 +08:00
imccyu 443efeeba3 chore(client): refresh slot catalog 2026-09-01 21:09:48 +08:00
imccyu 5934201109 perf(conversation): publish streaming updates every three frames 2026-09-01 21:09:48 +08:00
imccyu ebe9f50b44 perf(ui-chat): contain collapsed reasoning layout 2026-09-01 21:09:48 +08:00
imccyu aad1ce0c68 perf(ui-chat): retain the stats resize observer 2026-09-01 21:09:48 +08:00
imccyu f808112ec8 perf(ui-chat): derive user action reveal in CSS 2026-09-01 21:09:48 +08:00
imccyu 56684331c2 test(ui-chat): compare keyed snapshot values 2026-09-01 21:09:48 +08:00
imccyu 56a4d51d2c perf(ui-chat): scope turn process updates 2026-09-01 21:09:47 +08:00
imccyu 5f1eca58ea perf: InputBar use immutable props 2026-09-01 21:09:47 +08:00
imccyu a731536ecc perf: ChatNodeSeat use seperated source 2026-09-01 21:09:47 +08:00
imccyu 6401a64e20 test(web): cover optimized streaming paths 2026-09-01 21:09:47 +08:00
imccyu 2ab37e9558 perf(trajectory): page resident history before rendering 2026-09-01 21:09:47 +08:00
imccyu c809098b06 perf(conversation): publish streaming updates every two frames 2026-09-01 21:09:47 +08:00
imccyu 81431381d6 perf(conversation): reuse unchanged location projections 2026-09-01 21:09:47 +08:00
imccyu 203e2440ac perf(ui-chat): move reasoning tail alignment to CSS 2026-09-01 21:09:47 +08:00
imccyu e5bbee893b perf(ui-deliverables): move overflow sizing to CSS 2026-09-01 21:09:47 +08:00
imccyu c11c3f98ad docs(ui-deliverables): record CSS overflow policy 2026-09-01 21:09:46 +08:00
Yichen Jiang 3efd4b51e0 Merge pull request #3415 from deepseek-harness/worktree/3414-turn-rail-preview-layer
fix(web): keep turn previews above code banners
2026-09-01 21:05:36 +08:00
Turtle 6ce0b6cce8 fix(issue-management): write Start date through Issue fields 2026-09-01 21:01:36 +08:00
Tianyi Cui 876a3e0414 Merge pull request #3346 from deepseek-harness/worktree/session-format-02-seq-brands
refactor(session)!: distinguish event seqs from log offsets
2026-09-01 20:56:20 +08:00
Tianyi Cui 27bf1039db refactor(session)!: distinguish event seqs from log offsets 2026-09-01 20:36:00 +08:00
07akioni 6f9ef57a44 Merge remote-tracking branch 'origin/master' into feat/electron 2026-09-01 20:34:52 +08:00
07akioni f90d57f389 fix(desktop): address lifecycle review findings 2026-09-01 20:22:05 +08:00
Yichen Jiang 515eca7dc7 fix(web): keep turn previews above code banners 2026-09-01 20:21:11 +08:00
_Kerman c91b68409c Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery 2026-09-01 20:19:26 +08:00
_Kerman a96ec3dbd6 test(agent-loop): keep inbox internals private 2026-09-01 20:18:04 +08:00
ihsiang 4bc0b000f5 Merge pull request #3411 from deepseek-harness/feat/3287-smooth-corners
feat(web): superellipse corners and hairline elevation strokes
2026-09-01 20:17:16 +08:00
mektpoy b57cc33421 docs(goal): re-record README bilingual pairing 2026-09-01 20:04:06 +08:00
yx.zhang 8a97e817b5 docs(agents): describe the corner and elevation prior art generically
The two styling notes name the surveyed product; the mechanism facts
(superellipse token, guard, full-round opt-out, stroke-in-shadow
elevation, 0.5px hairline) stand alone, so the notes now state them
without the product reference. Pairing records re-recorded.
2026-09-01 20:01:23 +08:00
mektpoy 33fa98b3c2 fix(goal): fence pause to the dropped attempt ref 2026-09-01 19:58:52 +08:00
yx.zhang 3ce5604a71 feat(web): deepen composer stroke to l2, widen menu radii to 20px
The composer hairline moves one step up from the menus' l1; the seven
menu-fill dropdown cards grow from 16px to 20px corners. Notes and the
token comment record the new layering.
2026-09-01 19:25:59 +08:00
yx.zhang b873b9321e fix(web): per-element elevation tokens and review sync
Re-declare the derived elevation tokens on body * so per-surface
--dsw-elevation-stroke-color rebinds reach the consuming shadow (custom
properties inherit with var() already substituted); pin that mechanism
and add synthetic rejection cases to the stylesheet scans; take the
ring-track basenames through node:path so the exemption matches on
Windows; update the ModelsSection row-card spec to the hairline recipe;
align the elevation note with the shipped l1 menu rebind, refresh the
feedback-popover note's surface recipe, and document the soft tier.
2026-09-01 19:15:56 +08:00
yx.zhang 7020c7e122 feat(web): superellipse corners and hairline elevation strokes
Apply global visual polish across the web client: corner-shape:
superellipse(1.5) with corner-shape: round pairing for full circles,
elevation tokens that draw 0.5px stroke outlines inside box-shadow for
floating surfaces, 0.5px hairline borders and divider lines for
neutral-token strokes, and tuned stroke contrast plus larger radii for
menus, settings panels, and cards. Stylesheet-scan specs in ui-theme
reject unpaired circles, border+shadow mixes, and 1px neutral hairlines
repo-wide.

Closes #3287
2026-09-01 18:25:20 +08:00
07akioni f026514610 fix(desktop): align merged release lifecycle 2026-09-01 17:27:36 +08:00
07akioni 13f079812e Merge remote-tracking branch 'origin/master' into feat/electron 2026-09-01 16:55:25 +08:00
07akioni 6aaba0c334 feat: windows build & sign 2026-09-01 16:19:43 +08:00
creatixchu 590a8e220a docs(attachment): record generic file behavior 2026-09-01 16:11:43 +08:00
creatixchu e9b7ed0aab test: cover generic file submission flows 2026-09-01 16:11:43 +08:00
creatixchu a1144c4950 feat(ui-attachment): unify mixed attachment presentation 2026-09-01 16:11:43 +08:00
creatixchu bafa6ae11d feat(conversation): stream files through submission lifecycle 2026-09-01 16:11:43 +08:00
creatixchu 8a0ff3aff8 feat(session-controller): admit files across command flows 2026-09-01 16:11:43 +08:00
creatixchu 65d2015b09 feat(attachment): store and project generic files 2026-09-01 16:11:43 +08:00
fz dead2b2324 Merge pull request #3382 from deepseek-harness/feat/sdk-default-web-fetch
feat(base): expose web fetch by default
2026-09-01 15:59:35 +08:00
Yichen Jiang 68488c552a Merge pull request #3403 from deepseek-harness/fix/model-discovery-profile-headers
fix(llm): reuse profile headers for model discovery
2026-09-01 15:46:34 +08:00
Yichen Jiang 8fa464890c Merge remote-tracking branch 'origin/master' into fix/model-discovery-profile-headers 2026-09-01 15:26:09 +08:00
Chinesezjc d2954806de fix(snapshots): project read-image-attachment-path fixture into canonical packed layout 2026-09-01 15:19:37 +08:00
fz 0a0f9e59ff feat(base): expose web fetch by default 2026-09-01 15:18:18 +08:00
Yichen Jiang 25e4527f5e fix(llm): validate configured provider headers 2026-09-01 15:09:40 +08:00
Chinesezjc a23c3dd64e Merge branch 'origin/master' into feat/toolcard-image-result 2026-09-01 14:45:24 +08:00
Yichen Jiang 5257c75092 fix(llm): reuse profile headers for model discovery 2026-09-01 14:37:16 +08:00
_Kerman 1eebb7c312 Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery
# Conflicts:
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/bundle/headless/package.json
#	packages/compaction/compaction-basic/tests/manual-compaction.spec.ts
#	packages/shell/tool-bash-persistent/package.json
#	packages/shell/tool-pwsh-persistent/package.json
#	packages/skill/tool-skill/package.json
#	packages/subagent/subagent/tests/continuation-inheritance.spec.ts
#	packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts
#	packages/terminal/terminal-bash/package.json
#	packages/terminal/tool-terminal/package.json
#	packages/test-support/agent-loop-testkit/README.i18n.yaml
#	packages/test-support/agent-loop-testkit/README.md
#	packages/test-support/agent-loop-testkit/README.zh.md
#	packages/test-support/agent-loop-testkit/package.json
#	packages/test-support/agent-loop-testkit/tsconfig.json
#	pnpm-lock.yaml
2026-09-01 14:25:18 +08:00
Dudu-0223 1149d47e9a test(tools): update team catalog expectation 2026-09-01 14:22:50 +08:00
Dudu-0223 040d73871b feat(agent-team): unify messages on steer 2026-09-01 14:22:50 +08:00
fz aefbee95e2 test(acp): refresh adjacent messaging schema 2026-09-01 14:22:49 +08:00
fz ab9dcd5a2a Merge remote-tracking branch 'origin/master' into feat/sdk-default-web-fetch 2026-09-01 14:17:15 +08:00
Dudu-0223 52af48f808 Merge pull request #3250 from deepseek-harness/feat/3220-steer-service
Unify adjacent Agent delivery on Steer
2026-09-01 14:14:38 +08:00
Dudu-0223 11719fd83c test(web): await goal composer settlement 2026-09-01 14:00:07 +08:00
mektpoy 29ce849738 fix(goal): abort the live turn on host-initiated pause 2026-09-01 13:56:36 +08:00
Dudu-0223 d960d90a98 test(snapshot): refresh Python PTC prompt 2026-09-01 13:46:36 +08:00
Dudu-0223 bfdede9d9e test(subagent): adapt session reads after rebase 2026-09-01 13:46:36 +08:00
Dudu-0223 22b08a9b9b test(subagent): update parent id expectation 2026-09-01 13:46:36 +08:00
Dudu-0223 4093ce465b Merge remote-tracking branch 'origin/master' into feat/3220-steer-service 2026-09-01 13:46:35 +08:00
fz 1bd880c587 Merge remote-tracking branch 'origin/master' into feat/sdk-default-web-fetch
# Conflicts:
#	packages/bundle/headless/README.i18n.yaml
#	packages/bundle/headless/README.md
#	packages/bundle/headless/README.zh.md
2026-09-01 13:45:44 +08:00
Yichen Jiang f878545358 Merge remote-tracking branch 'origin/master' into worktree/deepseek-harness-proxy-config-2f5b4a
Master moved 212 commits. Conflicts were eight `package.json` and nine
`tsconfig.json` files, all dependency-and-reference unions: master dropped the
`runtime-diagnostics/invariants` reference across packages while this branch
added `util/http-proxy`. The lockfile, `tsconfig.base.json`, and the module
graph were regenerated rather than merged by hand.

Master also brought `verify-package-invariants`, which rejects an empty
invariant companion. This package's companion was empty by design, so it is
gone with its publication wiring — the export, the `files` entry, the project
reference, the `dsh-invariants` peer, and the test. Master did the same across
`util/`. The README carries the reason sentence that gate requires.

Carried in the same commit, because the review arrived while the merge was open:
`e2bApiUrl` moves out of the `dsh-e2b` entry into `src/api-url.ts`. Code Entropy
flagged it as a public name with no consumer outside its own package; the seam
keeps its URL-precedence test, which is worth having directly — getting that
order wrong hands a proxy the control-plane traffic and its API key.
2026-09-01 13:39:50 +08:00
Turtle 714bec1316 Merge pull request #3367 from deepseek-harness/omit-unneeded-invariants
cleanup: omit unneeded invariant companions
2026-09-01 12:59:03 +08:00
fz 036abf8c6c test(snapshots): refresh remaining headless web headers 2026-09-01 12:02:29 +08:00
07akioni 194bad298a fix: mac build 2026-09-01 11:58:14 +08:00
Turtle d7811225dc Merge remote-tracking branch 'origin/master' into turtle/omit-unneeded-invariants
# Conflicts:
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/code-runtime/code-runtime-python/README.md
#	packages/code-runtime/code-runtime-python/README.zh.md
#	packages/experimental/code-runtime-python/README.i18n.yaml
#	packages/experimental/code-runtime-python/package.json
#	packages/experimental/code-runtime-python/src/invariant.ts
#	packages/experimental/code-runtime-python/tsconfig.json
#	pnpm-lock.yaml
#	tsconfig.base.json
2026-09-01 11:54:10 +08:00
Chinesezjc d13d0a4b86 ci: re-trigger workflow after dropped push event 2026-09-01 11:53:19 +08:00
fz aaf10753a1 test(snapshots): separate ACP web headers 2026-09-01 11:49:55 +08:00
Chinesezjc 9d15938073 Merge pull request #1148 from deepseek-harness/feat/code-runtime-python-backend
feat(code-runtime-python): add the CPython subprocess backend
2026-09-01 11:44:16 +08:00
Chinesezjc 6e5ed52aed fix(ui-tool): address review wording and JSDoc accuracy on the image card 2026-09-01 11:43:26 +08:00
Chinesezjc 666bd48eae fix(ui-tool): scope the image-card path fallback to nested calls; repair merge-broken docs and snapshot fixtures 2026-09-01 11:40:21 +08:00
fz cf7b0bd5a4 feat(headless): expose web fetch by default 2026-09-01 11:40:10 +08:00
Chinesezjc a0c0b55c8a Merge remote-tracking branch 'origin/master' into feat/code-runtime-python-backend
# Conflicts:
#	packages/experimental/code-runtime-python/package.json
2026-09-01 11:29:10 +08:00
_Kerman 3f0b7779e6 test(headless): derive captured session length 2026-09-01 11:23:15 +08:00
Turtle d68ff7e66f Merge remote-tracking branch 'origin/master' into turtle/omit-unneeded-invariants
# Conflicts:
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/session/session-projection/src/invariant.ts
#	tsconfig.base.json
2026-09-01 11:18:11 +08:00
Yichen Jiang b9153cbc19 Merge remote-tracking branch 'origin/master' into worktree/deepseek-harness-proxy-config-2f5b4a
# Conflicts:
#	packages/session/session-telemetry-otel/package.json
2026-09-01 11:15:18 +08:00
fz b5c61b613a Merge remote-tracking branch 'origin/master' into feat/sdk-default-web-fetch 2026-09-01 11:13:00 +08:00
_Kerman 9699772fff Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery
# Conflicts:
#	packages/api/session-controller/README.i18n.yaml
#	packages/api/session-controller/README.md
#	packages/api/session-controller/README.zh.md
#	packages/context/agent-instructions/tests/agent-instructions.spec.ts
#	packages/core/agent-loop/tests/contract-regressions.spec.ts
#	packages/core/agent/src/inbox.ts
#	packages/core/agent/tests/agent.spec.ts
#	packages/test-support/agent-loop-testkit/package.json
2026-09-01 11:02:30 +08:00
Yichen Jiang c62d6f3a44 refactor(net): make the proxy a util library with six functions
Review asked why this is a plugin and why it exports so much. The design note
this branch shipped answered the second question itself — "a pure resolution
function plus an installation function" — and the code drifted to seventeen
exports and a Cordis plugin nobody approved or mounted.

The plugin is gone. Transport policy has one answer per process: nothing to
swap, and no scope narrower than the process to give one. Its `Config` was also
the only supplier of a configuration branch, so resolution now reads the
environment and nothing else — `mode`, the config-sourced fields, and the
`config` policy source were unreachable the moment the plugin left.

Four exports nothing outside the package used are internal again, and
`currentProxyPolicy` answers with the direct policy instead of `undefined`, so
`DIRECT_POLICY` no longer needs a public face. Nine functions remain, one per
way a caller can need the policy; two is not reachable with six consumer seams.

The package moves to `util/`. The note claimed a dependency on `undici`
disqualified it from that group; the charter governs harness dependencies, not
external ones, and the process note that says so predates this branch. The real
blocker was the harness dependency: resolution needed one method of
`LaunchEnvironmentSnapshot`, so it names a structural `EnvLookup` and the
launcher passes its snapshot unchanged. `net/` is dissolved.

Dropping the group's line from the repository layout also returns `AGENTS.md`
to its original ceiling, so the raise the merge needed is reverted.
2026-09-01 11:01:05 +08:00
_Kerman 5dd876025d Merge pull request #2907 from deepseek-harness/xtr/session-log-read-api
perf(session): separate indexed and snapshot log reads
2026-09-01 10:49:54 +08:00
imccyu dd6322d604 Merge pull request #3387 from deepseek-harness/release/dsh-0.1.2-alpha.3
release: [email protected]
2026-08-31 23:53:17 +08:00
imccyu 14bab4422b release(dsh): 0.1.2-alpha.3 2026-08-31 23:39:37 +08:00
imccyu 8b4b815e7e Merge pull request #3384 from deepseek-harness/worktree-connerr
fix(connection): avoid disconnecting during host stalls
2026-08-31 22:43:12 +08:00
imccyu 8372c3e188 Merge pull request #3383 from deepseek-harness/worktree-shikiperf
perf(ui-primitives): defer offscreen syntax highlighting
2026-08-31 22:41:45 +08:00
imccyu ddecdf6b33 test(web): wait for settled background job 2026-08-31 22:30:51 +08:00
imccyu 49bf26a794 fix(connection): tolerate stalled hosts 2026-08-31 22:17:39 +08:00
imccyu 07be260245 test(ui-primitives): cover lazy viewport highlighting 2026-08-31 22:11:39 +08:00
imccyu faa61ada74 perf(ui-primitives): defer offscreen syntax highlighting 2026-08-31 21:58:22 +08:00
Chinesezjc 6ce131c4f4 Merge remote-tracking branch 'origin/master' into feat/code-runtime-python-backend 2026-08-31 21:41:18 +08:00
07akioni cb6685d5b8 Merge remote-tracking branch 'origin/master' into feat/electron 2026-08-31 21:18:11 +08:00
07akioni 5f135ea977 feat: mac code sign & notarize 2026-08-31 21:16:17 +08:00
imccyu 94bbfb95e8 Merge pull request #3379 from deepseek-harness/schedule-catalog-left-alignment
fix(web): align Schedule catalog within viewport
2026-08-31 20:53:40 +08:00
_Kerman ad02fa37b4 Merge remote-tracking branch 'github/master' into xtr/session-log-read-api 2026-08-31 20:50:19 +08:00
imccyu 76557f4899 Merge pull request #3328 from deepseek-harness/worktree/navbar-pagination-interaction-24d006
feat(web): navigate every session turn from the chat rail
2026-08-31 20:45:45 +08:00
imccyu 9ba9a35c72 test(session-projection): cover view transition matrix 2026-08-31 20:30:43 +08:00
fz ca723d9273 feat(sdk): expose web fetch by default 2026-08-31 20:18:50 +08:00
pku-xht 2660635e63 fix(shell): preserve stderr on provider failure 2026-08-31 20:05:37 +08:00
imccyu 6f0daff1dd fix(session-projection): compare observed live views 2026-08-31 19:59:54 +08:00
Yichen Jiang 12bef3b577 perf(session-projection): memoize raw views by state identity
Review follow-up: the per-step gate recomputed view(previous) on every
changed apply — a property read for identity-stable views, but a fresh
throwaway object per change for computing views. The registry now keeps a
WeakMap from state object to raw view: the previous state's view was
cached when that state was current, so each distinct state's view computes
exactly once (gate and snapshot share the memo) and the quiet path
allocates nothing. Unlike the earlier lastView record, an entry is keyed
by the state itself — the view of that exact state by the pure-view
contract — so no stamping discipline exists to get wrong. Primitive
states bypass the WeakMap and compute directly.
2026-08-31 19:46:56 +08:00
Yichen Jiang a2437db180 revert(session-projection): drop the viewKey token, keep the per-step raw-view gate
Review consensus: for the only declaring unit the token function was
literally the view function, so the extra wire member bought nothing —
default raw-view comparison produces the identical Object.is on
state.turns at the identical cost (one property read per side). The
per-step gate stays: it holds the no-stored-baseline property, and its
measured overhead (~ns per changed state) is four orders of magnitude
below the push path it guards.
2026-08-31 19:46:56 +08:00
Yichen Jiang f2e4078d8c docs(session-projection): carry viewKey through the subsystem type fences 2026-08-31 19:46:56 +08:00
Yichen Jiang 9836fdbbd7 docs(session-projection): describe the change feed by its viewKey token 2026-08-31 19:46:56 +08:00
Yichen Jiang acc23f6d9c feat(session-projection): unit-declared viewKey change token
Review follow-up (imccyu): comparing view(previous) recomputes the view on
every quiet change. The wire block now takes an optional viewKey(state)
declaring the cheap comparison token; the drive compares tokens across the
previous and next states and calls view only for an actual push. Default
stays the raw view output. turnOutline declares viewKey: state => state.turns,
making the identity-stable-turns convention an explicit contract; the
registration erasure forwards viewKey (dropping it silently reverted the
gate to the fallback, caught by the new view-call-counting test).
2026-08-31 19:46:55 +08:00
Yichen Jiang 9069a8b6f8 refactor(session-projection): compare per-step views instead of storing a dedup baseline
Review suggestion (imccyu): the drive holds both the previous and next
state, so the identity gate can compute view(previous) and view(next) in
the driving step and compare them directly. The stored lastView cell field
and its stamp-on-every-change rule are deleted; with no dedup memory,
nothing can go stale across listener generations by construction, and a
rebuilt cell no longer pushes an unchanged view on its first live event.
Costs one extra pure view() call per changed state.
2026-08-31 19:46:55 +08:00
Yichen Jiang e71db15d1a chore(release): align session-turn-outline with root 0.1.2-alpha.2, mark mirrored preview clone
The dsh 0.1.2-alpha.2 release bumped every workspace after this branch
forked, so the new package failed the workspace version constraint in the
merge tree. The bounded preview() also grew identical enough to its
deliberate host/client mirror to trip clone detection; the client copy now
carries a jscpd ignore region naming the wire-boundary rationale.
2026-08-31 19:46:55 +08:00
Yichen Jiang b7053eba79 refactor(session-turn-outline): bound oversized preview blocks, degrade malformed previews
preview() now slices a single text block to limit * 2 before joining and
normalizing, so one multi-megabyte block no longer pays a full-string pass;
the host projection and the client turn-navigation helper stay mirrored.
outlineEntry keeps dropping entries with damaged turn/seq (marks cannot
exist or jump without them) but degrades malformed prompt/response
previews to empty strings so the turn stays navigable.
2026-08-31 19:46:55 +08:00
Yichen Jiang 8322f804cb fix(session-projection): advance the view dedup baseline on every change
The change feed stamped lastView only when a listener was subscribed, so a
value change during a listener-free window (HMR swap) froze the baseline
and a later transition back to the old value was silently deduplicated.
The baseline now advances on every changed state, heard or not; broadcast
still only happens with listeners. Docs, catalog, and the feature note
follow the corrected semantics.
2026-08-31 19:46:55 +08:00
Yichen Jiang 39b90961c7 fix(ui-chat): hold jumps while a plain pull owns the pager
A jump clicked while the Load-earlier pull was in flight fell through the
settle effect's nearest-turn fallback and landed on the wrong row. The
effect now keeps the pending jump (busy pulse stays) while loadingOlder is
true and a retry tick re-issues loadThrough when the pull settles.

Also repins the long-interactions e2e rail block to the outline-rail
semantics (fixed mark pitch, load-and-jump labels) and covers the
loadThrough forwarding paths in apply-inject and the client-runtime stub.
2026-08-31 19:46:55 +08:00
Yichen Jiang db5417ff6f fix(session-controller): keep refused jumps from parking a stale target
loadThrough now assigns its low-water target only when it owns the loop
(retargeting stays inside the running-jump branch): a call refused while
a plain load-earlier pull holds the pager no longer leaves jumpTargetSeq
behind to drag a later jump all the way to the head. The loop also
carries the doOpen stale-pass guard so a mid-flight resync stops it
instead of paging the new stream generation toward the old target.
2026-08-31 19:46:55 +08:00
Yichen Jiang 7c58a95ebb test(session-turn-outline): cover fold edges and deflake settle assertion
Edge-branch coverage for the preview reading bound, repeated and empty
drafts, draftless turn ends, orphan-draft clearing, and same-response
recommits (the CI per-file gate exercises them); the jump-settle spec
now asserts only the busy lifecycle after settlement — jsdom's zero
geometry made the rAF active-turn resync timing-dependent under
coverage instrumentation, and the landing position contract lives in
the browser e2e.
2026-08-31 19:46:55 +08:00
Yichen Jiang 0e63841189 feat(session-turn-outline): settled-response previews at card budgets
Outline entries gain the turn's final text-bearing assistant preview:
each assistant message overwrites a state draft and turn/end commits
the survivor, matching the loaded rail's findLast semantic; the bare-
array wire keeps its identity across draft changes, so pushes stay at
three per turn. Preview budgets shrink to the rail card's clamps — one
50-character prompt line, up to three 120-character response lines,
ellipsis on clip — on loaded and unloaded turns alike (stateVersion 2
discards v1 cache rows).
2026-08-31 19:46:55 +08:00
Yichen Jiang ceadd90e71 feat(session-projection): identity-gated change feed
The feed previously fired on every changed state reference of a
client-visible unit; it now also compares the raw view output against
the last delivered one and stays quiet when Object.is-identical, so a
unit can buffer working fields in state behind an identity-stable
projection. Units whose views build fresh objects per call are
unaffected.
2026-08-31 19:46:54 +08:00
Yichen Jiang 62f707bb1d fix(ui-chat): release bottom ownership when a jump starts
Clicking an unloaded rail mark from the pinned tail raced the pinned
scroll snap: the first prepend's compensation fires a non-reader scroll
delivery, the snap called toBottom, and toBottom cancels a pending jump
— so the jump silently stayed at the tail while history loaded. The
click now drops atBottom itself (jumping into history is leaving the
live tail), pinned by a jsdom regression and re-verified live: a
118-turn session lands on turn 1 in ~250ms from click.
2026-08-31 19:46:54 +08:00
Yichen Jiang 422b603874 docs: turn outline rail contracts and agent note
READMEs record the rail's outline merge and the loadThrough paging
verb in both languages; the feature Agent Note owns the decision,
alternatives (sparse windows, minSeq wire bound, outline RPC, height
estimation), and coverage map. Regenerates the client/API catalogs the
widened faces feed.
2026-08-31 19:46:54 +08:00
Yichen Jiang 3a834fe6c9 feat(ui-chat): settle jump landings after paging completes
A mid-paging landing keeps the jump armed with the target row as its
paging anchor, so later chunks and the load-earlier button's unmount
cannot drift the landing; the loader's completion runs one final
correction unless the reader already scrolled off the target. Adds the
browser contract: full outline ladder, keyboard jump on an unloaded
mark, landing geometry, and rail fades.
2026-08-31 19:46:53 +08:00
Yichen Jiang 6af1ee49b1 feat(ui-chat): scrollable fixed-pitch turn rail
Marks keep a fixed 10px pitch instead of compressing into the frame:
overflow scrolls inside a hidden-scrollbar scroller with gradient fades
over each still-scrollable end, the preview compensates the rail scroll,
and the active mark keeps itself centred while the pointer is off the
rail. Pointer-to-mark mapping now works in ladder coordinates.
2026-08-31 19:46:53 +08:00
Yichen Jiang b3064cca77 feat(ui-chat): full-session turn rail with load-and-jump
The rail now merges the turnOutline projection with loaded-window items
(view-layer only; loaded wins, outline fills mid-turn prompt previews),
renders unloaded turns as dimmer marks, and clicking one holds the
reader's place, pages history through the turn's seq, and lands on its
row after the commit — no height estimation. Settlement repages once
per head movement, then falls back to the nearest rendered turn.
2026-08-31 19:46:53 +08:00
Yichen Jiang 218bb7f645 feat(session-controller): loadThrough deep history paging
Session.loadThrough(seq) loops the existing prepend pager (200-message
pages) until the window covers the target seq, with a shared low-water
retarget for repeated calls, a no-progress guard against empty pages
still claiming history, and loadOlder's fail-soft error posture. Busy
state rides the existing loadingOlder snapshot bit.
2026-08-31 19:46:53 +08:00
Yichen Jiang 7e2eacb1fe feat(session-turn-outline): whole-log turn outline projection
New turnOutline projection unit serving every started turn's number,
turn/start seq, and bounded first-prompt preview through the
session-projection seam, mounted in the web-app bundle for the chat
turn rail. Entries stay strictly increasing; previews mirror the rail's
loaded-turn preview budget.
2026-08-31 19:46:53 +08:00
pku-xht fc19a0a3fa fix(subprocess): clarify provider failures and scope polling 2026-08-31 19:26:08 +08:00
pku-xht faa977fb29 fix(web): align Schedule catalog within viewport 2026-08-31 18:59:28 +08:00
Chinesezjc a8d8b8cddd docs(code-runtime-python): sync hostFrameParseCeiling example numbers to the 16x multiple
The hostFrameParseCeiling JSDoc and one load-gate test comment still quoted
the pre-16x derivation (~29 MiB for a ~300 MiB heap, ~14 MiB for a 128 MiB
old space). With HOST_PARSE_WORST_CASE_MULTIPLE = 16 the same hosts derive
~14 MiB and ~7 MiB (floor((176-64)/16)); protocol.spec.ts pins the 304 MiB
case at 15 MiB. Comment-only correction, no behavior change.
2026-08-31 18:57:34 +08:00
imccyu eca3bda903 Merge pull request #3374 from deepseek-harness/hl-perf
fix(web): make streaming code fences incremental
2026-08-31 18:49:03 +08:00
Chinesezjc 56ca8af0ee feat(ui-tool): render the image card for nested read_image calls 2026-08-31 18:14:08 +08:00
07akioni d8e2ac5052 fix(web): retain completed streaming fence lines 2026-08-31 18:11:32 +08:00
Chinesezjc 974fca9f5a fix(code-runtime-python): restore oxlint suppressions lost in the #3289 merge-forward and re-pack the ptc-python fixture
The #3289 merge-forward dropped four typescript/no-unnecessary-condition
suppressions from index.ts (boot-write-failure fake child stdin, the
admit()-closure logsTruncated recheck, and both settled rechecks whose
guards flip mid-wait), turning the lint:contracts-ready gate red. Re-add
them with their reasons. The merge also carried a ptc-python-turn session
fixture that was not in canonical packed layout; migrate-packed-session-fixtures
re-writes it so session-fixture-layout passes.
2026-08-31 17:52:25 +08:00
Turtle 79e388547c Merge remote-tracking branch 'origin/master' into turtle/omit-unneeded-invariants 2026-08-31 17:45:29 +08:00
_Kerman febafc7ee0 fix(test): cover indexed session reads 2026-08-31 17:43:17 +08:00
ZiyaandZiyaZhang 2480bdf27a feat(web): clarify Workspace Write Chinese label (#3345)
Co-authored-by: ZiyaZhang <[email protected]>
2026-08-31 09:42:16 +00:00
_Kerman 03ec1ca57c fix(agent): preserve explicit identity lifecycle behavior 2026-08-31 17:40:47 +08:00
Tianyi Cui 50b6be997d Merge pull request #3289 from deepseek-harness/worktree/pr1148-runtime-contract-fixes
fix(code-runtime): settle Python provider contracts
2026-08-31 17:30:15 +08:00
07akioni 1dd3e60f50 fix(web): make streaming code fences incremental 2026-08-31 17:26:04 +08:00
_Kerman 687ae5c9c0 Merge remote-tracking branch 'github/master' into xtr/session-log-read-api
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.md
#	.agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.zh.md
#	.agents/notes/implemented/feature/2026-08-05-context-form-vocabulary.i18n.yaml
#	.agents/notes/implemented/feature/2026-08-05-context-form-vocabulary.md
#	.agents/notes/implemented/feature/2026-08-05-context-form-vocabulary.zh.md
#	packages/examples/agent-spine-demo/tests/agent-core.spec.ts
#	packages/skill/tool-skill/tests/tool-skill.spec.ts
2026-08-31 17:19:59 +08:00
Turtle c6e6f4f460 fix: retain invariant host lint suppression 2026-08-31 17:16:58 +08:00
Tianyi Cui 01141e619a Merge latest #1148 into #3289 2026-08-31 17:11:37 +08:00
Chinesezjc 5bb2c46453 Merge branch 'master' into feat/toolcard-image-result 2026-08-31 17:11:15 +08:00
Tianyi Cui d87b755e37 Merge origin/master into feat/code-runtime-python-backend 2026-08-31 17:11:11 +08:00
Turtle 01a8882601 fix: complete invariant omission cleanup 2026-08-31 17:10:53 +08:00
Turtle a7f5b6e638 Merge remote-tracking branch 'origin/master' into turtle/omit-unneeded-invariants 2026-08-31 17:01:06 +08:00
Tianyi Cui d15610a66b test(snapshot): refresh Python PTC fixture for latest master 2026-08-31 17:00:18 +08:00
_Kerman 39517fb22b Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery
# Conflicts:
#	packages/core/agent-loop/README.i18n.yaml
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/README.zh.md
2026-08-31 16:53:12 +08:00
Turtle 713ae6c29b Merge pull request #3360 from deepseek-harness/turtle/pr-open-start-date
feat(issue-management): initialize Issue start dates on PR open
2026-08-31 16:48:47 +08:00
Tianyi Cui dc5cc0d575 test(code-runtime-python): align PATH rejection diagnostic 2026-08-31 16:47:26 +08:00
imccyu 60a46b9f5d Merge pull request #3331 from deepseek-harness/worktree-chatctxmemory
perf(web): reduce retained conversation state
2026-08-31 16:41:11 +08:00
_Kerman 8e1c47f82f test(sdk): avoid duplicate projection registry 2026-08-31 16:36:23 +08:00
Tianyi Cui ba0609571f Merge #1148 validation corrections into #3289
# Conflicts:
#	packages/experimental/code-runtime-python/tests/runtime.spec.ts
2026-08-31 16:29:52 +08:00
_Kerman a41c3a300e Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery 2026-08-31 16:29:37 +08:00
Chinesezjc 8fb9bc29e9 Merge branch 'master' into turtle/pr-open-start-date 2026-08-31 16:27:41 +08:00
Tianyi Cui f14189cf8c chore(deps): refresh Python runtime lock importer 2026-08-31 16:27:40 +08:00
Tianyi Cui 04aee12cc2 test(code-runtime-python): align macOS runtime expectations 2026-08-31 16:26:39 +08:00
Chinesezjc c5a94f11df Merge pull request #3354 from deepseek-harness/fix/windows-coverage-flaky-test-budgets
test: stabilize the Windows coverage lane against timing flakes
2026-08-31 16:11:55 +08:00
Chinesezjc 8ace43a8b1 Merge pull request #3364 from deepseek-harness/fix/notices-serial-windows-timeout
fix(ci): serial-windows notices timeout and generator store-scan cost
2026-08-31 16:10:47 +08:00
Tianyi Cui 4e2c568efe Merge corrected #1148 checkpoint into #3289
# Conflicts:
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.zh.md
#	packages/experimental/code-runtime-python/README.i18n.yaml
#	packages/experimental/code-runtime-python/README.md
#	packages/experimental/code-runtime-python/README.zh.md
#	packages/experimental/code-runtime-python/src/index.ts
#	packages/experimental/code-runtime-python/tests/runtime.spec.ts
2026-08-31 16:10:13 +08:00
Tianyi Cui 61b3e06e97 fix(code-runtime-python): preserve post-merge hardening 2026-08-31 16:03:32 +08:00
Chinesezjc 4f877cdab1 Merge branch 'master' into fix/notices-serial-windows-timeout 2026-08-31 15:55:59 +08:00
Tianyi Cui d6bd5eb973 fix(code-runtime): bound interpreter version probe 2026-08-31 15:55:05 +08:00
Tianyi Cui 711ec7ffac test(snapshot): canonicalize Python PTC fixture 2026-08-31 15:50:45 +08:00
Tianyi Cui 7f84a825c9 fix(code-runtime): settle Python provider contracts 2026-08-31 15:50:45 +08:00
imccyu d7abd0a01e fix(web): activate selected view for blank sessions
fix(web): activate selected views before blank gating
2026-08-31 15:45:26 +08:00
Chinesezjc a00c9a062c Merge branch 'master' into fix/windows-coverage-flaky-test-budgets 2026-08-31 15:45:19 +08:00
imccyu 4b21065dbe refactor(client): share conversation context initialization 2026-08-31 15:44:23 +08:00
imccyu 4203317e18 perf(client): materialize conversation targets on demand 2026-08-31 15:44:23 +08:00
imccyu 354bf44923 fix: ci 2026-08-31 15:44:23 +08:00
imccyu b4527bedc7 fix(client): pin inbox claim semantics 2026-08-31 15:44:22 +08:00
imccyu 61da6fbbe5 perf(web): defer tool body formatting until expansion 2026-08-31 15:44:22 +08:00
imccyu 8478de9b0e perf(client): linearize inbox projection state 2026-08-31 15:44:22 +08:00
pku-xht 6d49ac2ef6 fix(subprocess): align runner bindings with current types 2026-08-31 15:37:14 +08:00
Chinesezjc a074e6131f fix(ci): serial-windows notices timeout and generator store-scan cost
render() loaded the workspace manifests once per external dependency
name through workspaceLinkedManifest, an O(names x manifests) file
read on the cold path; on the loaded self-hosted Windows host with
coverage instrumentation the freshness spec crossed Vitest's default
5000ms budget and failed the serial-windows standby gate four times in
a week. Load the manifests once in render() and thread the map through
the collectors instead.

The serial-windows lane also ran the coverage inventory at the strictest
budget of any lane: add DSH_COVERAGE_TEST_TIMEOUT_MS=90000 to match the
pull-request windows-coverage lane, pinned by ci-workflow.spec.ts.
2026-08-31 15:33:16 +08:00
Chinesezjc 8e9d5467b0 fix(code-runtime-python): bound reply and call backlogs, snapshot binding metadata, and compact the reply queue
Review findings on the CPython backend: a child that never reads fd 3 leaves
the reply pipe full forever, so the drain loop waits on 'drain' while every
call frame it keeps sending resolves a binding and queues another reply —
the backlog (and the binding results it pins) would grow until the wall
clock. sendReply now caps the pending backlog at MAX_PENDING_REPLIES and
settles the run as worker-exit past it, mirroring the frame cap; a child
flooding calls against a binding that never settles would otherwise bypass
that cap (pendingReplies grows only after the await), so the dispatcher
counts in-flight binding calls before dispatch and releases the slot in the
async body's finally, capping outstanding closures at the same bound. The
drain also compacts its consumed prefix (replyQueue.splice(0, head)) once
head reaches the bound, so a drain that stays alive without emptying cannot
grow the backing store linearly with cumulative throughput.

The completion-value meter counted lone surrogates with
_SURROGATE.findall(folded), materializing one single-character string per
surrogate: a surrogate-dense value near the budget (millions of surrogates,
each serializing to six bytes) allocated millions of objects before the meter
returned, defeating the meter's counting-without-building contract. The count
is now the length difference between folded and the without string the meter
already computes; a standalone equivalence check confirms it matches findall
across lone-high, lone-low, paired, astral, and mixed cases.

validateBindings read namespace.global/errorClass.name/memberNameProperty
several times and retained the original errorClass object for the boot
frame, whose JSON.stringify re-read it after validation: a stateful getter
could throw or change between the two stages, turning the seam-misuse
rejection into a worker-exit or injecting an unvalidated name. Each field is
now read once into a plain value and the bindings map stores a plain
{ name, memberNameProperty } copy, so validation and the boot frame see
identical values.

Regression tests: a hostile child floods 5000 sequential valid calls without
reading fd 3 and the run settles worker-exit with the reply-queue message
before maxWallMs; a 3,000,000-surrogate completion succeeds at an
18,000,002-byte budget and reports output-limit one byte under; a 5000-call
flood against a never-settling binding settles worker-exit with the
call-backlog message; getter-backed namespace metadata that throws or
changes on a second read boots and runs with each field read exactly once; a
two-wave flood whose replies exceed the writable high-water mark drives the
drain past the compaction bound mid-delivery and verifies all 1524 replies
arrive. README Known Limitations gains the reply-backlog and call-backlog
bounds (en/zh, pairing re-recorded); a new Agent Note registers the findings.
2026-08-31 15:25:26 +08:00
Chinesezjc b75eec0967 docs(doc-graphs): list the experimental Python backend as a codeRuntime implementation
The capability-seams graph derives its implementation lists from
SERVICE_ROLES in scripts/gen-doc-graphs.ts, which still listed only the
worker-thread backend. Add experimental-code-runtime-python so the
generated graph and table match the registered ctx.codeRuntime
implementations; regenerate docs/capability-seams.md, sync the zh pair,
and re-record the i18n pairing.
2026-08-31 15:25:26 +08:00
Chinesezjc 2df28fd249 fix(code-runtime-python): validate explicit pythonBin at load, snapshot bindings, and settle the reply drain
Review findings on the CPython backend: an explicit pythonBin path bypassed
the load-time checks (missing/non-executable/directory paths surfaced only
as a run-time worker-exit); a throwing binding member accessor escaped the
fd-3 data callback and terminated the host; the reply drain waited on
'drain' alone, so a pipe destroyed under the wait hung forever; and two
staging-leak assertions diffed a global tmpdir that parallel workers can
perturb.

resolvePythonBin now applies the same accessSync(X_OK) + isFile check to
explicit paths (resolved against the host CWD), and the load error message
distinguishes 'is not an executable regular file' from 'does not resolve on
PATH'. validateBindings snapshots callables into a plain record during run()'s
synchronous validation, turning an accessor throw into the seam-misuse
rejection and fixing the key set the boot frame and dispatch share. The reply
drain waits on drain/close/error together and short-circuits on
proto.destroyed. The staging-leak assertions check the exact paths this test
file staged (recorded by the mocked mkdtempSync) instead of a tmpdir diff.

docs(code-runtime-python): add the alternatives section to the hardening note

docs(config-catalog): refresh the code-runtime-python Config source line

test(code-runtime-python): cover the async spawn-error worker-exit path
2026-08-31 15:25:26 +08:00
pku-xht fb00331cfa Merge master into subprocess native containment 2026-08-31 15:24:49 +08:00
pku-xht 5e3eaea742 refactor(subprocess): keep runner error bindings one-shot 2026-08-31 15:22:12 +08:00
Chinesezjc 2c8d545524 docs(experimental): list code-runtime-python in the group README; state the portable note as current fact
The review's items: the experimental group README's Packages table and Summary
now list code-runtime-python (CPython subprocess backend, ctx.codeRuntime),
paired; the portable-identifier note's Scope drops the 'has since shipped …
now lists' change narration in favor of the current state, removing the
apparent contradiction with 'the worker is the only shipped backend'.
2026-08-31 15:20:50 +08:00
Chinesezjc c435170a93 docs(code-runtime): drop the remaining shipped claims for the private experimental backend
The review's final wording items: the portable-identifier note's Scope said the
backend 'has since shipped' without noting it is experimental/private; the
RESERVED_WORDS JSDoc said backends 'ship for both languages'. Both now name the
TypeScript backend as released and the CPython backend as experimental and
private. The package README also records that the truncation-marker text and
tempdir prefix keep the pre-rename short names (byte-anchored by tests,
independent of the npm name).
2026-08-31 15:19:22 +08:00
Chinesezjc 12d0bdb274 docs(code-runtime): stop calling the private experimental Python backend published
The review's carry-over: 'each has a published backend' in the CodeRuntime
JSDoc and its projections (tool-cordis api-catalog, subsystems page) plus
'both shipped'/'backends ship' in the code-runtime README all claimed the
Python backend is released; it is private and experimental, excluded from the
release family. The wording now states the TypeScript backend is released and
the Python backend is experimental and private (not published), in the JSDoc
(api-catalog regenerated to match), the READMEs (paired), and the subsystems
page (paired).
2026-08-31 15:17:56 +08:00
Chinesezjc 732a54f85b docs(code-runtime-python): fix note status grammar and paragraph wrap
The fd-3 note's Status line moved off line 3 when the experimental-location
fact was added; it is back as the sole line-3 status. The zh portable-identifier
note's merged Scope paragraph lost its blank-line separator, which the
md-wrap gate read as one hard-wrapped paragraph — the blank line is restored.
2026-08-31 15:16:24 +08:00
Chinesezjc 2504d0a501 fix(code-runtime-python): complete the experimental move across configs and docs
The review's move-follow-ups: the Windows test exclude now points at
packages/experimental/code-runtime-python (the constructor throws by design on
Windows, so the suite must stay excluded); the invariant companion and
@module annotations use the new npm name; the truncation marker text and
tmpdir prefix stay as-is (tests anchor them); the package JSDoc and READMEs no
longer call the private experimental backend 'published'/'shipped'; the
code-runtime README row describes the package as protocol AND runtime; the
fd-3 note records the package's experimental location.
2026-08-31 15:15:08 +08:00
Chinesezjc d7eb7f4418 fix(code-runtime-python): finish the experimental move — invariant name and tsconfig aliases
The move broke two generated/derived surfaces: (1) the package invariant
companion still registered the old name
@deepseek-ai/dsh-code-runtime-python, so the exhaustive-topology test found
the new name unreserved — it now registers
@deepseek-ai/dsh-experimental-code-runtime-python; (2) the tsconfig.base.json
alias for the renamed package sat inside the generated region, so
gen-tsconfig-paths dropped it (a package named after something other than its
directory needs a hand-written alias before the BEGIN marker) — the alias is
moved out and the config is current again.
2026-08-31 15:13:55 +08:00
Chinesezjc 053d17f6a1 refactor(code-runtime-python): move the package into packages/experimental
The CPython code runtime's complete public contract is experimental, so it
moves to packages/experimental per the experimental-packages rules: npm name
@deepseek-ai/dsh-experimental-code-runtime-python, private: true, no
publishConfig. All references updated (code-runtime READMEs, config-catalog
and module-graph regenerated with zh alignment, tsconfig paths, doc-standard
and workspace-constraints scripts, the fd-3 and settlement Agent Notes, and
the package README links); md-links and translation pairing pass, and the
suite still runs green.
2026-08-31 15:13:55 +08:00
Turtle 49f1d1bd9a Merge remote-tracking branch 'origin/master' into turtle/pr-864-master-port 2026-08-31 15:12:15 +08:00
Xu Hanxiang dc3984204d Merge pull request #3288 from deepseek-harness/issue-3135-tab-completion
fix(client): complete highlighted commands with Tab
2026-08-31 15:11:36 +08:00
Chinesezjc 45cfc9cfaf docs(code-runtime-python): sync the Consequences enumeration to eleven no-fail-before fixes
The review's item: the Problem section counts eleven no-fail-before fixes, but
the Consequences section still said 'the ten called out in the Problem section'
(zh: '那十处') and omitted the new unknown-binding preview cap. Both sides now
say eleven and name the cap, paired and re-recorded.
2026-08-31 15:09:28 +08:00
Chinesezjc 200703a20d docs(code-runtime-python): list the unknown-binding preview cap as the eleventh no-fail-before fix
The review's warning: the settlement note's Problem paragraph says ten fixes
have no fail-before test, but the unknown-binding preview cap (a transient
whole-target JSON.stringify peak, unmeasurable through the seam) is the
eleventh. The count and the item are now recorded, paired.
2026-08-31 15:09:28 +08:00
Chinesezjc 391e29ec8a docs(code-runtime-python): register the unknown-binding preview cap in the settlement note
The review's suggestion: the settlement note enumerates each review fix in this
PR, so the unknown-binding preview cap (escaped from a 1 KiB prefix,
capMessage still enforces the reply budget) gets its own short section, paired
and re-recorded.
2026-08-31 15:07:40 +08:00
Chinesezjc a6678610b8 fix(code-runtime-python): cap the unknown-binding preview before JSON.stringify
The reviewer's standing item: the unknown-binding reply ran JSON.stringify on
the WHOLE capped target (global + '.' + name, each up to maxValueBytes code
units), allocating the escaped form — up to ~6x under control-heavy input, a
multi-hundred-MB spike near the maxValueBytes ceiling that no hostile-peer
bound would have admitted. The escaped preview is now built from a 1 KiB
prefix of the target (enough to identify the binding); capMessage still
enforces the reply budget. A forged huge-name case drives the path.
2026-08-31 15:06:50 +08:00
Chinesezjc 6719e287de docs(code-runtime-python): state the layer-5 deferral as current fact, not PR history
The review's wording item: the layer-5 bullet ended with 'not by this PR'
(zh: 'not borne by this PR'), which references PR context in durable prose.
The sentence now ends with the current-state fact ('not by this package's
suite'), paired and re-recorded.
2026-08-31 15:06:50 +08:00
Chinesezjc 80ceb4ec5f docs(code-runtime-python): register the layer-5 assembly snapshot deferral
The review's open suggestion: the Known Limitations now records that the
real-Loader assembly snapshot is deferred to issue #1182 layer 5 (this package
is exercised through ctx.plugin and real-subprocess tests; the full application
composition is covered by a tracked assembly test in that layer), paired.
2026-08-31 15:06:50 +08:00
Chinesezjc 771872a73d test(code-runtime-python): cover the finish-residual sealed side; use a block array for the open seal
The review's two remaining non-blocking items: (1) a case where the run ends
with a SEALED open hold (past MAX_PENDING_CHUNKS) — finish() must commit the
sealed prefix, verified to fail if finish drops openSealed. (2) openSealed is
now a block ARRAY (one joined block per seal) matching the fd-3 reader's
blocks and the stray capture's seal, instead of one repeated string concat
that leaned on V8 ConsString amortization.
2026-08-31 15:06:50 +08:00
Chinesezjc 74e9d97e37 docs(code-runtime-python): register the host-side open seal; note the empty-first-frame billing
The review's follow-ups on the open-seal fix: (1) the settlement note's seal
section now records the HOST-side open hold seal (openParts -> openSealed,
mirroring the child _LogStream and stray-capture seals), paired. (2) the
first-fragment guard comment notes the empty-first-frame case (bills cost + 1 =
3, establishes no hold, bounded over-charge in the safe direction). (3) a
regression case commits a SEALED open hold before the truncation marker —
verified to fail if truncateLogs drops openSealed.
2026-08-31 15:06:50 +08:00
Chinesezjc bca392e6d1 fix(code-runtime-python): seal the open hold past MAX_PENDING_CHUNKS
The review's warning: each held open fragment is a distinct array slot plus
string object header (~30x overhead the byte cap cannot see), and a
budget-sized single-character open flood is honest-child reachable
(print('x', end='', flush=True) in a loop). With maxLogBytes near its ~67 MB
load ceiling that was up to ~2 GB of host auxiliary heap. The hold now seals
into one block past MAX_PENDING_CHUNKS, mirroring the fd-3 reader's blocks and
the stray capture's seal; the merge, truncateLogs, and the finish residual all
read sealed + current fragments, and a within-budget flood regression asserts
the merged entry is byte-identical.
2026-08-31 15:06:05 +08:00
Chinesezjc 953dd2d9b8 docs(code-runtime-python): align three stale comments with the shipped code
The review's wording items: the load-check comment still referenced the
resolvePythonBin JSDoc's old ENOENT promise; the spawn-site comment called the
type assertion a non-null assertion; and two comments claimed the
'logs serialize to maxLogBytes + marker + envelope' bound is recorded in the
README's Known Limitations, which has no such entry — the cross-references are
dropped, the bound stays stated inline.
2026-08-31 15:06:05 +08:00
Chinesezjc fcf4e5463a docs(code-runtime-python): declare detachResidual in the public surface
The review's carry-over: detachResidual (a test seam for the settled run's
resource cleanup) is re-exported from the '.' entry but was not in the README's
declared public surface; the list now names it alongside resolvePythonBin and
readProcessStart, paired.
2026-08-31 15:06:05 +08:00
Chinesezjc ca0e3e573e docs(code-runtime-python): drop the fixed empty-open limitation; declare the test helpers
The empty-open continuation skip (5b61a8fe6) made the Known Limitations entry
stale — the held fragment array no longer grows per empty frame — so the entry
is removed on both sides. The public-surface list now declares
resolvePythonBin and readProcessStart, which the '.' entry re-exports for the
test suite.
2026-08-31 15:06:05 +08:00
Chinesezjc 716060a04a test(code-runtime-python): cover the zero-content open-continuation skip
The skip branch (an empty open continuation is not pushed into the hold) needs
coverage; a case drives an empty continuation between a first fragment and the
closing frame and asserts the merged entry is unchanged.
2026-08-31 15:06:05 +08:00
Chinesezjc d9ed44d62c fix(code-runtime-python): skip zero-content open continuations in the hold; correct the spawn comment
The review's items: a zero-content open continuation bills 0 but still pushed
'' into the held fragment array, so a forged empty-open flood grew host memory
without touching the ledger — the push is now skipped (an empty fragment
contributes nothing to the merged entry). The spawn-site comment said a PATH
change between load and run would fail with ENOENT; it actually makes spawn
throw synchronously, which the surrounding try settles as worker-exit.
2026-08-31 15:06:05 +08:00
Chinesezjc 3151ecb848 docs(code-runtime-python): state the pythonBin load rejection in the README and the load-check comment
The review's warning: the pythonBin load-rejection is a product-visible change
(unresolvable basename now fails at load instead of a run-time worker-exit),
but the READMEs (en + zh) only said the basename is resolved against PATH, and
the load-check comment still described the old fallback. The README pythonBin
entries and the load-check comment now state the rejection; pairing
re-recorded.
2026-08-31 15:06:05 +08:00
Chinesezjc f931c2128a docs(code-runtime-python): register the pythonBin load-rejection change; harden PYABS
The review's follow-ups: (1) the product-visible change (an unresolvable
basename pythonBin now fails at load instead of a run-time ENOENT worker-exit)
is registered in the settlement note, paired. (2) PYABS falls back to the bare
name when python3 is not resolvable, instead of interpolating the literal
'undefined' into the wrappers.
2026-08-31 15:06:05 +08:00
Chinesezjc 80e13b3446 fix(code-runtime-python): align the resolvePythonBin docs and the exception-group guard
The review's follow-ups on the pythonBin change: (1) the JSDoc and the two
call-site comments still described the old fallback-to-bare-name contract;
they now state the load-rejection behavior. (2) the ExceptionGroup case's
version guard raised a skip message on Python < 3.11 but the assertion still
required the truncation marker unconditionally — the assertion now matches
either the truncation marker (3.11+) or the skip message (3.10). (3) the shell
wrappers quote the resolved interpreter path.
2026-08-31 15:05:23 +08:00
Chinesezjc 0b980bdfd1 fix(code-runtime-python): reject an unresolvable pythonBin at load; guard the ExceptionGroup case
The review's two non-blocking items: (1) resolvePythonBin returned the bare
basename when PATH had no hit, and spawn (env:{}) would silently fall to
execvp's platform default PATH and could start a system interpreter the caller
never asked for. It now returns undefined for an unresolvable basename and the
load check rejects it (absolute paths pass through), so the failure is loud at
configuration time instead of silent at spawn; the case that expected a
run-time worker-exit now asserts the load rejection, consistent with the
empty/NUL pythonBin cases. (2) the over-cap exception-group case skipped on
Python < 3.11 (ExceptionGroup is a 3.11+ builtin), matching the TaskGroup
case's version guard.
2026-08-31 15:05:23 +08:00
Chinesezjc 60b8fc00c4 test(code-runtime-python): resolve the interpreter path in the shell wrappers
The review's portability warning: the six shell wrappers exec'd a bare
'python3', which /bin/sh resolves against its compiled-in default PATH while
the runtime spawns with env:{} — in environments where python3 is reachable
only through the caller's PATH (Nix, pyenv) every wrapper run would fail as
worker-exit. The wrappers now bake the resolved absolute interpreter path
(module-level resolvePythonBin, which the product spawn already uses), and
resolvePythonBin is exported for the tests.
2026-08-31 15:05:23 +08:00
Chinesezjc 27b8f97150 fix(code-runtime-python): normalize the inherited SIGXCPU state before any CPU-consuming setup
The reviewer's residual timing item: the inherited-SIGXCPU reset ran AFTER
setrlimit(RLIMIT_CPU) and the boot-namespace construction, so a huge namespace
under an inherited ignore/block could burn past the soft limit inside that
window and be misclassified as worker-exit. The reset now happens at the very
top of _run, before the resource-limit setup and namespace construction.
2026-08-31 15:05:23 +08:00
Chinesezjc c4fe0320fb test(code-runtime-python): drive the inherited SIGXCPU path with a wrapper; fix the zh outer wire sentence
The review's two follow-ups on the inherited-SIGXCPU fix: (1) a discriminating
case — pythonBin points at a wrapper that ignores SIGXCPU before exec'ing
python3, so the child genuinely inherits the ignore; with cpuSeconds: 1 the
busy loop must end as timeout (the bootstrap reset restored SIG_DFL), and
reverting the reset leaves it running to the wall — verified red. (2) The zh
README's OUTER wire section now carries the truncation-exception sentence
(the previous commit had duplicated it in the inner section instead); the
duplicate is removed, and the settlement note registers the inherited-SIGXCPU
reset.
2026-08-31 15:05:23 +08:00
Chinesezjc 7b9db83f86 fix(code-runtime-python): reset the inherited SIGXCPU disposition and mask at startup
The reviewer's standing issue: the child inherits the host's SIGXCPU
disposition and signal mask — if the host ignores or blocks SIGXCPU, the soft
RLIMIT_CPU fires but cannot stop the child, and the hard limit's SIGKILL then
classifies a definite CPU overrun as worker-exit instead of a timeout. The
bootstrap now resets SIGXCPU to SIG_DFL and unblocks it before any model code
runs (the settle-time enforcer already restores SIG_DFL for a program that
traps or masks the signal mid-run; this closes the inherited-state gap). The
zh README's outer wire section also gains the truncation-exception sentence to
match the en side.
2026-08-31 15:04:43 +08:00
Chinesezjc fa0565032f docs(code-runtime-python): register the truncation exception to open merging; clean a case comment
The review's warning: the READMEs (outer and inner wire sections, en + zh) and
the fd-3 protocol note still claimed the next log frame always merges into an
open entry, while truncateLogs commits the already-billed prefix as its own
entry before the marker. The one exception (truncation) is now stated in both
READMEs and the owning note, paired and re-recorded. The prefix-commit case's
parenthetical describing the pre-fix implementation is removed per the
comment-does-not-record-review-history rule.
2026-08-31 15:04:43 +08:00
Chinesezjc 6bdbe71092 fix(code-runtime-python): drop fd-3 frames with illegal UTF-8 instead of mangling them
The reviewer's standing issue: line.toString('utf8') silently replaces illegal
bytes with U+FFFD, so a forged frame could land a corrupted completion value
(the honest child's lossless encoder never emits non-UTF-8, so such a frame is
hostile traffic). The fd-3 frame decode now uses a fatal UTF-8 decoder: an
illegal byte throws and the frame is dropped, same treatment as the
unsafe-integer check. A forged illegal-UTF-8 done frame is verified to be
dropped (the run settles on the program's real return), and reverting to
toString makes the case fail.
2026-08-31 15:04:43 +08:00
Chinesezjc 89fbe54cb1 fix(code-runtime-python): commit a flushed open prefix before the truncation marker
The review's warning: a flushed unterminated line is billed and committed
(README wire contract says so), but every truncation arm — the child truncated
frame, an over-budget open frame, an over-budget closing frame, and admit's two
budget arms — pushed only the marker, dropping the held prefix: the ledger
charged for output that vanished. All arms now funnel through truncateLogs(),
which pushes the (already billed) held prefix before the marker and clears
openParts, so the prefix survives and only the marker stays last; the finish()
guard drops the now-dead !logsTruncated check (a truncated run has an empty
hold). A regression case asserts [prefix, marker]; the forged-flood and
closing-overflow cases now expect the committed prefix plus the marker.
2026-08-31 15:04:43 +08:00
Chinesezjc e7ac747e2d docs(code-runtime-python): register the zero-billed empty open-frame hold as a known limitation
The review's suggestion: an empty open continuation frame bills zero and holds
one host slot, so a forged empty-open flood grows the held fragment array
without touching logBudget. Accepted as a residual (per-frame host cost far
below its ~30-byte fd-3 wire cost, bounded by pipe throughput, model-code trust
level equal to bash) and now registered in the README's Known Limitations on
both sides, paired and re-recorded.
2026-08-31 15:04:43 +08:00
Chinesezjc 909d5c334b docs(code-runtime-python): restate the buffered-chunks pre-check comment as invariant-preserving
The review's revision: the buffered-chunks pre-check's open-aware overhead is
observationally inert — when the +3 form trips and the open-aware form does not
(pending + newline in [remaining - 2, remaining]), _push_bounded_prefix
re-slices the same newline-free line text and _push_locked admits it under the
same open-aware billing, byte for byte. The comment now states that the
open-aware form keeps _push_bounded_prefix's 'certain to reject' precondition
true, contrasting with the scan pre-check whose slice carries the newline and
therefore genuinely truncates.
2026-08-31 15:04:43 +08:00
Chinesezjc fdcfec4977 docs(code-runtime-python): align the en wire-contract section with the open flag; fix the case comment
The review's warning: the en README's inner 'Wire contract' section still
described only the truncated flag while the zh counterpart (and the outer 'The
wire' section) described open. The inner en section now matches. The exact-fit
closing-line case comment described the buffered-chunks pre-check recipe while
the program actually drives the scan pre-check; the comment now states the
actual arithmetic and path (and the buffered variant was dropped — its writes
coalesce into one call in the test environment, so it did not discriminate).
2026-08-31 15:04:43 +08:00
Chinesezjc 9194dfebc8 fix(code-runtime-python): make the write-path pre-checks open-aware; document the open flag in zh
The review's warning: while an open entry accumulates, the newline pre-checks in
the write path still charged a NEW entry's +3 cheap-bound overhead (quotes +
separator), so an exact-fit merged TAIL was truncated (or the pre-check
over-rejected it and flushed a truncated prefix). Both pre-checks now charge
the overhead only when no open entry is in progress, matching _push_locked's
open-aware bound. A regression case (the review's recipe: flush an open
fragment, then write one exact-fit newline-terminated line) is verified to
truncate when the +3 is restored.

The zh README's wire-contract section now describes the open flag like the en
side (the fd-3 Agent Note holds the split-billing arithmetic; a cross-doc link
was omitted to keep the bilingual link sequence aligned).
2026-08-31 15:04:43 +08:00
Chinesezjc 371303822f test(code-runtime-python): give the first-fragment cap a discriminating case; dedupe the note
The review's warning: the one-byte overflow case ran through the CHILD ledger
(print path), so the host's first-fragment cap (logBudget - 1) never executed,
and the sub-2-byte guard test does not discriminate logBudget from
logBudget - 1 (a reverted cap still trips the guard). The frame is now forged
on fd 3, so a reverted cap of logBudget admits it and flushes it at settlement
— verified to turn the test red.

The review's dedupe suggestion: the split-billing arithmetic was stated in both
notes; the settlement note's Decision paragraph now links to the fd-3 protocol
note's wire-contract section (one home per fact), paired and re-recorded.
2026-08-31 15:04:43 +08:00
Chinesezjc c7d2d4b8b5 docs(code-runtime-python): register the open-merge split billing in the settlement note
The review's suggestion: the settlement note's Decision section now states the
shipped split-billing fact (first fragment pays quotes+separator, continuations
and the closing frame pay content only; host caps logBudget-1 / logBudget+2;
child keys off _open_started), paired and re-recorded.
2026-08-31 15:04:03 +08:00
Chinesezjc 1097bd3c3c docs(code-runtime-python): register the open-merge split billing in the fd-3 note
The review's suggestion: the open-merge mechanism (incremental split billing on
both sides, host caps logBudget-1/logBudget+2, the sub-2-byte walk guard, the
child's _open_started-keyed billing) lived only in code comments. The wire
contract section of the note now states it, paired and re-recorded.
2026-08-31 15:03:21 +08:00
Chinesezjc 22e2dc454d test(code-runtime-python): cover the sub-2-byte guard of the exact-cost walk
The new jsonStringCostUpTo guard (returns undefined below a 2-byte cap) was
uncovered: forged open frames drive the host ledger down to one byte, and a new
open entry's first-fragment cap (logBudget - 1 = 0) trips the guard and
truncates to the marker, asserted as the merged entry plus the marker.
2026-08-31 15:03:21 +08:00
Chinesezjc 3001cc23be fix(code-runtime-python): correct the open-merge cap arithmetic on both sides
The review's arithmetic checks: the closing-frame walk used cap
logBudget - openCost, so a compliant merged entry (58-byte wire cost under a
64-byte budget) could see a negative cap and truncate; the first-fragment cap
used logBudget instead of the ledger's logBudget - 1, so an open frame costing
63 was admitted with a bill of 64, pushing the ledger negative and letting a
subsequent empty frame ride in one byte past the configured cap; and the child
billed a closing frame as a fresh entry (quotes+separator again) instead of the
merged tail, truncating an exact-fit 30+30 entry.

Fixes: first-fragment cap logBudget - 1 (matching admit), continuation and
closing-frame cap logBudget + 2 (billed without quotes), jsonStringCostUpTo
returns undefined below 2 bytes, and the child's split billing keys off
_open_started alone (a closing frame pays content only) with the cheaper bound
len(text) while a merge is open. Regression cases cover all three arithmetic
paths.
2026-08-31 15:03:21 +08:00
Chinesezjc 4fd0068fb7 fix(code-runtime-python): bill a merged open entry incrementally on both sides
The review's critical: the open-merge branch re-joined and re-walked the whole
held text per frame, so k tiny open frames cost O(k * budget) (thousands of
1-byte frames against a near-64 MiB budget would re-traverse hundreds of GB and
block the host event loop). The host now holds a fragment ARRAY with an
incrementally billed cost — each fragment's jsonStringCostUpTo walks only its
own text — and the closing frame bills only its own content, so the merged
entry's wire cost is charged exactly once, split across the fragments. The
child bills symmetrically: the first open fragment pays quotes+separator, each
continuation pays only its content, matching the host ledger (the review's
warning: per-fragment full billing truncated a 16-char merged entry under
maxLogBytes: 64 that costs only 19 bytes as one entry).

Regression cases: 16 single-character flushes merge to one whole entry; a
closing frame that overflows the remaining budget truncates to the marker; a
closing frame after an open flood already truncated the ledger is a no-op; and
a forged open-frame flood stays bounded by the ledger. The closing-frame
post-truncation guard is an invariant-false branch (an open frame that would
trip the ledger resets openParts, so a non-empty hold implies no truncation)
and carries a v8 ignore with that reason.
2026-08-31 15:03:20 +08:00
Chinesezjc ea1d28a068 fix(code-runtime-python): bound the open-merge hold by the ledger budget
The review's critical: the open-merge branch accumulated the held fragment
before any ledger check, so a forged open flood could grow host memory without
touching logBudget. The held fragment is now bounded by the exact-cost walk
(jsonStringCostUpTo against the remaining budget; the closing frame's admit()
still bills the merged entry once), and the open field is registered in the
README wire-contract section and the fd-3 protocol note (en + zh). A forged
open-flood case asserts truncation to the marker under a 64-byte budget.
2026-08-31 15:03:20 +08:00
Chinesezjc 72691455e9 fix(code-runtime-python): merge a flushed unterminated line into the next log entry
The review's remaining warning: an explicit flush of an unterminated line
(print(..., end='', flush=True)) pushed a full log frame, so the following
print() landed in a second entry and logs.join('\n') rendered 'a\nb' for what
the program printed as one line — a model-visible output defect. The flush
frame now carries an  flag (LogMessage gains the optional field on both
sides and in the mirror test), the host holds it and appends the next log frame
to the same entry, and finish() admits the residual if the run ends with it
still open. The settlement note registers the decimal-context fix from the
previous commit.
2026-08-31 15:03:20 +08:00
Chinesezjc 35de0682c7 fix(code-runtime-python): make the float encoder context-independent; correct the binding-reply README entry
The review's critical: Decimal(repr(value)).normalize() read the process-global
decimal context, so a legitimate program setting getcontext().prec = 2 silently
rounded the completion value's digits and traps[Inexact] = True made the encode
raise, misclassifying a successful run as an exception. A fixed module-level
Context(prec=28) makes the spelling decision context-independent; a regression
case mutates both context knobs and asserts the float round-trips exactly.

The binding-reply README entry now states the fact (no seam-level cap;
maxValueBytes meters only the done frame; a wide reply is rebuilt and encoded
whole, bounded by process memory), matching the earlier reviewer wording.
2026-08-31 15:02:38 +08:00
Chinesezjc 666ff2855e docs(code-runtime-python): drop the placebo dispose test and finish the remaining doc drift
The review showed the added dispose case was a placebo (dispose in the same
tick as run means SIGTERM hits the group before the program body runs; the
group-emptied arm is already deterministically covered by the same-group
survivor case, which this removes the v8 ignore for). The test is deleted; the
stale silently-discards comment in the boundary test now says rejects; the
README Known Limitations gains the late-log-frame-drop and host-side
binding-value-memory entries. Pairing re-recorded.
2026-08-31 15:02:38 +08:00
Chinesezjc bc08f405cc test(code-runtime-python): pin the reap-poll group-emptied arm with a dispose-timing case
The review's premise that the group-emptied arm could not be pinned was
incorrect; the same-group reap case already exercises it. This adds the missing
seam-observable case: dispose() while a setsid orphan holds the pipes and the
run is unresolved — settle kills the child, the group empties (the orphan is in
its own session), and the poll finalizes promptly instead of waiting out the
60 s grace. The v8 ignore on that arm is removed.
2026-08-31 15:02:38 +08:00
Chinesezjc 9b7b5489be fix(code-runtime-python): cover the poll-group arm and align the last frame-cap comments
The review's remaining coverage gap: the group-emptied arm of pollGroup depends
on the close-driven settle winning the race against the grace SIGKILL, a timing
interleaving no seam-observable test pins deterministically (the same-group
cases assert the settle and the reap, not this exact interleaving) — the arm
now carries a v8 ignore with that reason. The load-check comment and the
FRAME_ENVELOPE_BYTES JSDoc say rejects-as-worker-exit instead of drops.
2026-08-31 15:02:38 +08:00
Chinesezjc d98965fbcc docs(code-runtime-python): remove the ack-gate v8 ignore and align the remaining doc drift
The forged-second-boot-ack regression makes the re-entry guard covered, so its
v8 ignore is removed. Doc drift: the python README and run() JSDoc state the
resolve-with-value/resolve-with-error contract without inversion; the README
Known Limitations gains the setsid-escaped-orphan entry (the settlement note
referenced it); the settlement note drops the stale drops/discard phrasing and
the two 256 MiB references; the fd-3 protocol zh note no longer claims the
codec is undelivered; the code-runtime seam README (en + zh) says both
backends ship. Pairings re-recorded.
2026-08-31 15:02:38 +08:00
Chinesezjc 3e0055edaf test(code-runtime-python): cover the boot-ack gate's re-entry guard and run-write failure
The review rejected the v8-ignore defense for the ack gate: a forged second
boot-ack is deterministically constructible (one os.write on fd 3) and the
run-write failure is deterministically constructible with the boot-write-failure
mock pattern. A program that forges an extra boot-ack asserts the run still
completes once (the gate does not re-send the run frame); a mocked child whose
fd-3 pipe accepts the boot frame but rejects the run write resolves a
worker-exit.
2026-08-31 15:00:33 +08:00
Chinesezjc cb26dd3804 test(code-runtime-python): pin the directory-skip in pythonBin resolution; cover the ack gate defenses
The resolvePythonBin directory branch now has a regression: a PATH whose first
entry is an executable DIRECTORY named python3 is skipped for a later real
interpreter (fail-before: without the isFile guard the directory would be
chosen and spawn would fail). The boot-ack gate's forged-second-ack re-entry
guard and its write-failure branch are covered by v8 ignore comments (the
honest child sends exactly one ack; the write failure needs the child to exit
between ack and write).
2026-08-31 15:00:32 +08:00
Chinesezjc 2b3b7f87dc fix(code-runtime-python): send the run frame after boot-ack; reject directories in pythonBin resolution
The review's two behavior items: the run frame was written back-to-back with
the boot frame (the seam contract puts run after boot-ack, which confirms the
namespaces were accepted); it now goes out from the boot-ack handler, so a
boot failure cannot race the run frame. resolvePythonBin now requires the
candidate to be a regular file — a directory passes X_OK and would otherwise
shadow a later real interpreter. Doc spots: the load-time overflow message
says worker-exit (not stranding to the wall clock), the run JSDoc spells out
the resolve-with-error contract, the PATH-stub test removes the stale v8
ignore, and the README's binding-value bullet names serialization cost.
2026-08-31 14:59:01 +08:00
Chinesezjc 4943524278 chore: commit the master third-party notices (SDK 0.3.241)
The local machine's node_modules still links claude-agent-sdk 0.3.220, so a
local gen-third-party-notices run rewrites the file to that version; CI's
fresh install resolves the lockfile's 0.3.241 and gen expects it. The branch
adds no third-party dependencies (the schemastery workspace link is already
covered), so the notices file adopts master's 0.3.241 content.
2026-08-31 14:59:01 +08:00
Chinesezjc 981ade7611 fix(code-runtime-python): restore the runtime's cross-package dependency declarations
The earlier merge had adopted master's protocol-only package.json (peer/dev
limited to invariants and cordis, no dependencies), but src/index.ts imports
@deepseek-ai/dsh-code-runtime, dsh-session, dsh-timeout, and schemastery at
runtime — a published lib/index.js could not resolve those bare specifiers.
The manifest now mirrors code-runtime-worker-thread (the five peers, the
schemastery dependency, and the matching dev set); the lockfile, module graph,
and third-party notices are regenerated, and the module-graph zh pair is
re-synced.
2026-08-31 14:59:01 +08:00
Chinesezjc aa123becf1 chore: regenerate the module graph after the sdk-runtime manifest change
Dropping the code-runtime-python peer from sdk-runtime changed the dependency
graph; gen-module-graph refreshes docs/module-graph.md.
2026-08-31 14:57:12 +08:00
Chinesezjc 1eacccc6e4 chore(sdk-runtime): adopt master's manifest (drop the code-runtime-python peer)
The branch's sdk-runtime manifest had carried a code-runtime-python workspace
peer that master's lockfile does not record, so a frozen install failed on the
mismatched specifier. The branch changes no sdk-runtime code, so it adopts
master's manifest verbatim.
2026-08-31 14:56:11 +08:00
Chinesezjc 65a4d64786 chore(code-runtime-python): adopt master's package.json peer dependencies
The earlier merge had kept the branch's older package.json while taking
master's lockfile, so a frozen install failed on mismatched specifiers for the
code-runtime-python package (master added dsh-code-runtime, dsh-session, and
dsh-timeout peers). The branch changes no dependencies, so it adopts master's
manifest verbatim.
2026-08-31 14:56:11 +08:00
Chinesezjc 5b90f4e2ac chore: adopt master's lockfile and third-party notices after the merge
The merge conflict on pnpm-lock.yaml had kept the branch's older dependency
resolutions; the coverage gate's notices check then failed because CI's frozen
install resolved the master lockfile's versions while the committed notices
still named the branch's older ones. The branch adds no dependencies, so it
adopts master's lockfile and notices verbatim.
2026-08-31 14:56:11 +08:00
Chinesezjc 6e8cc96351 docs(code-runtime-python): fix the doc-standard registry and README kind
The audited library registry still listed dsh-code-runtime-python as a plain
protocol library, but the shipped package's src/index.ts has a plugin default
export; the entry is removed from PACKAGE_LIBRARIES and both READMEs declare
kind: package-reference. The zh README heading is 概述 per the standard.
2026-08-31 14:56:11 +08:00
Chinesezjc af72ad4409 docs(code-runtime-python): rewrite the README to the repo documentation standard
The merge pulled master's README rewrite (front-matter, Summary, TOC, section
anchors, details-folding); its content described the pre-delivery protocol-only
package, contradicting the shipped backend. The README (en + zh) now follows
that structure with the delivered facts: PythonCodeRuntime, the fd-3 wire, the
load-validated caps, the 64 MiB frame parse cap (worker-exit settlement), and
the known limitations. Pairing re-recorded.
2026-08-31 14:56:11 +08:00
Chinesezjc 7fbf370d87 docs(code-runtime-python): drop the orphan receive-cap JSDoc and correct the frame comments
The review's three stale-comment items in index.ts: the orphan JSDoc above
FRAME_PARSE_CAP_BYTES (left over from the deleted receive ceiling), the
pre-join comment's change narration and its reference to a no-longer-existing
higher ceiling, and the first-frame comment's mention of a per-line cap check
that no longer exists. Test comments for the pythonBin and sealing-threshold
cases are weakened to their observable claims (both orders reject an over-cap
frame; the pythonBin case pins the contract, not a worker-exit distinction).
2026-08-31 14:55:02 +08:00
Chinesezjc ff87d9a00f docs(code-runtime-python): finish aligning the notes with the delivered runtime
The fd-3 protocol note (en + zh) drops the 'future provider/runtime' staging
language (the runtime is delivered and its real-subprocess suite owns the
field-type gap), and the settlement note's Testing paragraph records the
frame-cap, multi-frame, sealing-threshold, and pythonBin resolution cases now
in the suite. Pairings re-recorded.
2026-08-31 14:55:02 +08:00
Chinesezjc 65da4cfb28 Merge pull request #3352 from deepseek-harness/fix/windows-coverage-align-linux
fix(ci): windows coverage runs zero-build like the linux lane
2026-08-31 14:54:27 +08:00
Chinesezjc 4903f7da1f docs(code-runtime-python): align stale frame-ceiling prose with the 64 MiB parse cap; pin pythonBin resolution
The review's doc drift items: the orphan receive-ceiling JSDoc, the frame-ceiling
references in index.ts/bootstrap.py/tests, and the README's 'dropped, stranding
to the wall clock' phrasing (the run now settles as a worker-exit) are all
updated to the 64 MiB FRAME_PARSE_CAP_BYTES semantics; the README notes the
>64 MiB binding-argument residual as a worker-exit trip of the same cap. A
regression case resolves a basename pythonBin against a PATH whose first entry
is relative ('.') and asserts the absolute entry is used.
2026-08-31 14:54:18 +08:00
Chinesezjc d62b63d529 fix(code-runtime-python): skip relative PATH entries in pythonBin resolution; pin the sealing-threshold rejection
The review's remaining code items:
- resolvePythonBin now skips RELATIVE PATH segments (a bare 'bin' or '.'): the
  returned candidate must be absolute, because spawn() resolves a relative
  pythonBin against the host CWD, outside the seam contract.
- A deterministic-ish regression pins the sealing-threshold corner: 64 MiB of
  4 KiB (<= PIPE_BUF, atomic) newline-free writes plus 12289 more A's before
  the first newline make the first frame exceed FRAME_PARSE_CAP_BYTES; the
  newline-bearing chunk reaches the first-frame check (sealing is the ELSE
  half of the newline branch), so the run reports worker-exit with the
  protocol-frame-exceeded message.
2026-08-31 14:53:33 +08:00
Chinesezjc a715bfd111 fix(code-runtime-python): seal only newline-free runs so the first-frame check cannot be skipped
The review's sealing corner: the fragment-count seal ran before the newline
branch and did not exclude a newline-bearing chunk, so the 1024th chunk (the
first to carry a newline) was concatenated into a sealed block, pendingChunks
was emptied, sawNewline stayed false, and the first-frame check was skipped for
a join that then contained the newline. Sealing now runs as the ELSE half of
the newline branch, so a newline-bearing chunk always reaches the join and its
first-frame check, and the invariant 'sealed blocks hold newline-free prefixes
only' is true — which is what makes the removed per-line check genuinely dead.
2026-08-31 14:53:33 +08:00
Chinesezjc 4c3e453080 fix(code-runtime-python): drop the now-dead per-line cap check again
The pre-join counter (single unframed line) and the first-frame check
(newline-bearing chunk) reject any frame past FRAME_PARSE_CAP_BYTES before the
join, so every line reaching this loop is within the cap by construction — the
per-line check was dead code and its continue branch could never fire, failing
the per-file 100% coverage gate.
2026-08-31 14:53:33 +08:00
Chinesezjc 295e020ea4 fix(code-runtime-python): reject only an oversized FIRST frame before the join, not a multi-frame buffer
The pre-join check charged the whole unframed buffer, which legitimately holds
several frames each within FRAME_PARSE_CAP_BYTES: a first frame of exactly the
cap followed by a second frame crossed the counter and was misreported as a
worker-exit. The pre-join rejection now fires only while the held bytes are a
single unframed line (this chunk carries no newline); once a newline arrives,
a FIRST-FRAME check measures the bytes up to the first newline across the held
chunks (including sealed blocks) and rejects only that frame before the join —
keeping the peak at one copy of its wire bytes — while later frames in the
same buffer are handled by the restored per-line check. Regression cases: a
72 MiB newline-free buffer is rejected pre-join (fail-before: joining would
have doubled it); two within-cap frames whose combined buffer crosses the cap
both survive (fail-before: the unconditional counter check turns it red).
2026-08-31 14:53:33 +08:00
Chinesezjc abf81a0905 fix(code-runtime-python): drop the now-dead per-line parse cap check
The unframed-buffer counter guard runs before every join and guarantees each
line is within FRAME_PARSE_CAP_BYTES, so the line-loop cap check was dead code
(its continue branch could never fire, failing the per-file 100% coverage gate
on index.ts). Removed with a comment explaining the invariant.
2026-08-31 14:53:33 +08:00
Chinesezjc 219d216c54 test(code-runtime-python): move the frame-overflow cases to the 64 MiB parse cap
The pendingBytes guard now trips at FRAME_PARSE_CAP_BYTES (64 MiB) instead of
the 256 MiB wire ceiling, so the three tests that flood/pin frames against the
guard assert the 67108864 message and write a 64 MiB-based workload.
2026-08-31 14:53:33 +08:00
Chinesezjc c8139589d2 fix(code-runtime-python): reject an oversized unframed frame before the join; cap the rejection diagnostic
The review's remaining critical: the fd-3 data handler checked the unframed
counter against the 256 MiB wire ceiling, so a single 64-256 MiB frame was
fully Buffer.concat-joined (a second copy) and only then dropped in the line
loop — the peak-memory doubling the pre-join check exists to prevent, for a
frame the parser is guaranteed to discard. The counter is now checked against
FRAME_PARSE_CAP_BYTES before the join; the regression case asserts a worker-exit
with 'protocol frame exceeded' (fail-before: reverting to the ceiling turns it
green, proving the join path). FRAME_CEILING_BYTES is removed.

The rejection-cap fix now has its regression: a completion value whose class
name is 70 MiB of Ns asserts invalid-output, not worker-exit (fail-before:
uncapping the diagnostic turns it red).

The settlement note (en + zh) updates the remaining stale bound text, and the
fd-3 protocol note (en + zh) no longer claims protocol-only exports or a
missing Python codec. Pairings re-recorded.
2026-08-31 14:53:33 +08:00
Chinesezjc 3f8b45f9bb fix(code-runtime-python): cap the done-frame rejection diagnostic and sync stale docs
The review's remaining items:
- _done_with_value's rejection branch now caps the _check_done_value diagnostic
  through _cap_message (a reason embedding a hostile class name could otherwise
  push the done frame past the host's 64 MiB parse cap, misreporting an
  invalid-output run as a worker-exit).
- The settlement note (en + zh) updates three stale facts (load bound is now
  parse-cap minus envelope at 67108800; the sink goes directly through the
  bound primitives); the fd-3 protocol note (en + zh) no longer claims the
  package ships protocol without the runtime; FRAME_ENVELOPE_BYTES' JSDoc and
  _cap_message's docstring follow the new bound.
Pairings re-recorded.
2026-08-31 14:52:57 +08:00
Chinesezjc d90155714b docs(code-runtime-python): correct the sink comment and register the frame parse cap
The review's remaining warning: the _run binding comment claimed the log sink
went 'through the bound send', contradicting the sink's actual direct use of the
bound encode+write primitives. The comment now states that; the settlement note
(en + zh) registers FRAME_PARSE_CAP_BYTES and the 65 MiB-frame regression case.
Pairing re-recorded.
2026-08-31 14:52:01 +08:00
Chinesezjc fca41b78ea fix(code-runtime-python): bound the load-time budget to the frame parser cap
The review found the 64 MiB parse cap contradicted the load-time budget bound:
maxLogBytes/maxValueBytes could be configured up to ceiling - envelope (~256 MiB),
but the receive path silently dropped any frame past the 64 MiB parser cap, so an
honest child's budget-internal done frame under such a config would be discarded
and the run stranded to the wall clock. The load bound is now parse-cap -
envelope, so a configured budget always fits through the parser; the boundary
test moves to 64 MiB - 64. The >64 MiB model-constructed binding-argument drop
is registered as an accepted residual in the README (en + zh).
2026-08-31 14:51:20 +08:00
Chinesezjc ab40136b02 fix(code-runtime-python): cap the raw frame length before JSON.parse and bound the log sink
Addresses the review's remaining two items:
- FRAME_PARSE_CAP_BYTES (64 MiB) drops an fd-3 frame whose raw length exceeds
  it BEFORE toString/JSON.parse: the 256 MiB wire ceiling bounds the bytes, not
  the decoded structure, and a compact wide frame near that ceiling could decode
  to far more host memory. A regression test writes a 65 MiB log frame plus a
  normal one and asserts the oversized frame is dropped while the trailing frame
  still lands in logs (fail-before: without the cap the oversized text is parsed
  and admitted, truncating the ledger so the trailing frame is dropped). The
  forged-oversized lower-bound test's frame is reduced to stay under the cap
  while still exercising the truncation path.
- The log sink writes through the def-time bound encode+write primitives (not
  send_sync, whose body resolves _encode_json_plain and self.write_encoded at
  call time), so a rebind cannot break a log frame.
2026-08-31 14:50:40 +08:00
Chinesezjc 125306324f fix(code-runtime-python): write dispatch frames through def-time bound primitives
The review's remaining functional item: send_sync's body resolves
_encode_json_plain (module global) and self.write_encoded (class attribute) at
call time, so a program rebinding either before the first binding call could
turn a legitimate call into an exception. dispatch now writes the call frame
through def-time bound write_encoded+_encode_json_plain, and the log sink goes
through the bound send; the dispatch rebind test also rebinds those two names
(verified fail-before by reverting to send_sync). The annotation test title
matches its assertion direction, and the note (en + zh) registers the
error-class constructor, dispatch primitives, and dont_inherit mechanisms.
Pairing re-recorded.
2026-08-31 14:50:39 +08:00
Chinesezjc c4c79f094d test(code-runtime-python): pin the error-class constructor and dispatch primitives with rebind cases
The review required regression cases for the two cfb35bef6 fixes:
- Rebinding __main__.Exception/__main__.setattr must not break the minted
  error class: a host rejection still surfaces as ToolCallError with the member
  property readable.
- Rebinding __main__._lossless_json_violation/__main__.asyncio/
  __main__.ProtocolChannel.send_sync must not break dispatch: a legitimate
  binding call still round-trips.
2026-08-31 14:49:54 +08:00
Chinesezjc 44205c4949 fix(code-runtime-python): stop the program's compile from inheriting the module's future annotations
bootstrap.py imports from __future__ import annotations; compile(wrapped) was
inheriting that PEP 563 flag, stringifying the program's type annotations and
changing the semantics of a legal program that reads f.__annotations__ at
runtime. compile(..., dont_inherit=True) stops the leak; a regression test
defines an annotated function and asserts the annotation is the live int class,
verified fail-before by removing dont_inherit (the test turns red).
2026-08-31 14:49:54 +08:00
Chinesezjc 6a659df999 fix(code-runtime-python): capture the error-class constructor and dispatch primitives
The review's remaining items:
- _make_error_class captures Exception and setattr as def-time defaults, so a
  rebind of __main__.Exception/__main__.setattr cannot break the rejection
  constructor.
- dispatch binds _lossless_json_violation, asyncio.get_event_loop, and the
  channel's send method into _run locals before the program runs, so a rebind
  cannot turn a legitimate binding call into an exception or a wall-clock
  timeout.
- The note (en + zh) corrects the stdin coverage phrasing: d3f9f57f5's direct
  EOF-observing case is the in-tree pin, not an approximation.
- Collapse two stray double blank lines in the test file.
Pairing re-recorded.
2026-08-31 14:49:54 +08:00
mektpoy ff21366916 fix(client): complete highlighted commands with Tab 2026-08-31 14:49:35 +08:00
Chinesezjc c4d6c25ffc test(code-runtime-python): pin the pump reader against a class-attribute rebind; correct the staging comment
The review's three remaining items:
- A regression test rebinds __main__.ProtocolChannel.read_frame_async and asserts
  a binding reply still round-trips (the pump's reader is a bound method
  captured by _run before the program runs).
- The settlement note (en + zh) records that send_done's frame-shape check uses
  _run's bound _str/_isinstance.
- The staging-removal comment no longer claims teardown retries tracked state:
  teardown deliberately does not sweep staging, so a removal failure is the one
  case the gone-by-settlement contract degrades on.
Pairing re-recorded.
2026-08-31 14:49:15 +08:00
Chinesezjc 8ed96b1560 docs(code-runtime-python): register the frame-reader capture extensions in the note
The review flagged that the implemented note's capture-family enumeration had
not followed c0ca236b5: read_frame/read_frame_async now also capture len (and
asyncio.get_event_loop on the async reader), _decode_json_plain captures
isinstance/str/list, and the reply pump's frame reader is injected as a bound
method captured by _run before the program runs. Note (en + zh) updated;
pairing re-recorded.
2026-08-31 14:48:36 +08:00
Chinesezjc aa685028a7 test(code-runtime-python): pin the stdin-close behavior with an EOF-observing case
The stdin destroy (child.stdin?.destroy() right after spawn) previously had no
in-tree coverage. A program that reads fd 0 now sees EOF immediately; without
the destroy it blocks and the run would hang to maxWallMs as a timeout —
verified fail-before by disabling the destroy (the test turns red at the wall
ceiling) and restoring it (green). The _str rebind regression was attempted but
is not viable: the success path's done-frame serialization reaches str
transitively through _encode_json_plain, which the README Known Limitations
already records as the accepted success-to-exception residual, so any rebind
test trips that documented residual before send_done's bound _str.
2026-08-31 14:47:57 +08:00
Chinesezjc 302bbb0f8f fix(code-runtime-python): close the remaining call-time lookup gaps in the reply and settlement paths
The review's completeness check found the def-time capture pattern was not yet
applied to every name the reply/settlement paths resolve at call time:
- _decode_json_plain now also captures isinstance/str/list.
- read_frame/read_frame_async capture len; read_frame_async captures
  asyncio.get_event_loop.
- send_done uses _run's bound _str/_isinstance for its frame-shape check.
- The reply pump's frame reader is a bound method captured by _run BEFORE the
  program runs and passed into _pump_replies, so a rebind of the class
  attribute cannot redirect it.
The decode-rebind regression test still pins the _decode_json_plain rebind;
rebinding builtins (len/isinstance/list/str) in a test is not viable because
the Python runtime itself resolves them implicitly.
2026-08-31 14:47:57 +08:00
Chinesezjc aa5e8fc345 fix(code-runtime-python): suppress the unnecessary-optional-chain lint for the stdin destroy
The boot-write-failure fake child carries no stdin at runtime, so the optional
call is the documented guard; the static type (ChildProcessWithoutNullStreams)
says stdin is non-null, which trips the no-unnecessary-condition lint.
2026-08-31 14:47:57 +08:00
Chinesezjc aecdec3f80 fix(code-runtime-python): guard the stdin destroy against a spawn-failure child
The boot-write-failure path's fake child carries no stdin handle, so the
unconditional destroy threw inside the spawn error handler and mislabeled the
worker-exit. Use the optional-call form; the no-stdin branch is exercised by
that same test.
2026-08-31 14:47:57 +08:00
Chinesezjc 40fbf92290 fix(code-runtime-python): close the child stdin handle and def-time capture the frame decode primitives
Addresses the review's two remaining items:
- The host closes the child's stdin write handle immediately after spawn. The
  program is an async body that reads nothing from fd 0; a live pipe would hold
  a host-side handle open past the run, so a setsid-escaped descendant
  inheriting fd 0 could keep the host process from exiting even after the
  closeDeadline forced settlement. The child (and any descendant) reads EOF on
  fd 0 and no host handle survives.
- read_frame/read_frame_async bind their decode primitives (_decode_json_plain,
  os.read, _READ_CHUNK_BYTES, bytes) as def-time default arguments, and
  _decode_json_plain itself captures json.loads, its two regexes, and len the
  same way, so a __main__ rebind cannot kill the reply pump and strand every
  pending Future to the wall clock. _decode_json_plain and its regexes moved
  before the ProtocolChannel class so the defaults resolve at class-definition
  time. A regression test rebinds _decode_json_plain and asserts a binding reply
  still round-trips.
Note (en + zh) registers both mechanisms; pairings re-recorded.
2026-08-31 14:47:57 +08:00
Chinesezjc ac64039843 fix(code-runtime-python): bind str for dispatch's rejection message conversion
The review's remaining non-blocking suggestion: dispatch's call_failure(str(exc))
resolved the builtin str at call time, so a program rebinding __main__.str could
run a hostile callable when the binding-rejection message is formatted. Bind
_str into _run locals and use it in dispatch.
2026-08-31 14:47:18 +08:00
Chinesezjc 937ada4837 fix(code-runtime-python): bind RuntimeError and _BindingRejection for dispatch's rejection path
dispatch's call_failure and its except clause resolved the module globals at
call time, so a program rebinding __main__._BindingRejection = ValueError let
the internal marker type leak into model code. Bind _RuntimeError_cls and
_BindingRejection_cls into _run locals before the program runs (names distinct
from the module globals so the assignment RHS resolves the global, not an
unbound local); dispatch now uses the locals. A regression test rebinds
_BindingRejection and asserts a host rejection still surfaces as RuntimeError.

The sys.__stdout__ flush test now reconfigures the streams back to block
buffering (write_through=False) so the settlement drain path is what the case
pins — verified fail-before: binding the stream objects instead of their flush
methods turns the test red.
2026-08-31 14:47:18 +08:00
Chinesezjc 1efb0094c8 fix(code-runtime-python): bind the original std streams' flush methods, not the stream objects
The settlement drain iterated the bound stream OBJECTS, which are not
callable — every _flush() raised TypeError and was swallowed by the loop's
except, so the drain never ran and only the -u flag carried the behavior.
Bind sys.__stdout__.flush/sys.__stderr__.flush (bound methods, capturing the
stream at binding time, immune to a later sys.__stdout__ rebind; None-guarded).
Verified by removing -u temporarily: the sys.__stdout__ regression test still
passes, so the drain is a genuine backstop, not a documented-but-dead layer.
2026-08-31 14:47:18 +08:00
Chinesezjc 43a0879ad1 fix(code-runtime-python): clear stray buffers on truncation and drain the original std streams
Addresses the review's two carried warnings and the comment suggestion:
- Once the ledger truncates, every arm that marks it (admit()'s two ceilings and
  the child-marker frame arm) now clears both stray pipes' buffered output
  wholesale, so the end-path flushStray sees empty buffers instead of
  concat+decoding doomed data near a 256 MiB maxLogBytes; captureStray's newline
  loop re-checks the flag before re-retaining the residual.
- The child runs with -u (unbuffered), so sys.__stdout__/sys.__stderr__ writes
  are visible to stray capture immediately; the settlement flush still drains
  the original std streams before the done frame as a guard. A regression test
  writes through sys.__stdout__/sys.__stderr__ without an explicit flush and
  asserts both bytes land in logs. C-ext stdio remains an accepted residual,
  recorded in the README Known Limitations (en + zh).
- The ledger-comment arithmetic now states the exact boundary (serializes to
  exactly maxLogBytes; without the reserved byte it would be maxLogBytes + 1)
  in both host and child.
Note (en + zh) registers the stray-clear and -u/settlement-drain mechanisms and
the new test; pairings re-recorded; corpus passes 1029.
2026-08-31 14:47:18 +08:00
Chinesezjc 4c7811812d docs(code-runtime-python): state the macOS killGroup behavior directly and complete the residual sentence
The review flagged the change-narrative wording 'degrades to the pre-existing
behavior' (prohibited by docs/AGENTS.md) in four spots — README en/zh, the
readProcessStart JSDoc, and the test comment — and the incomplete :77 residual
sentence ('can still' with no verb complement). Reword the four to a direct
statement of current behavior (killGroup signals the pgid without the identity
re-check on macOS), complete the residual sentence with the actual consequence,
and re-record both pairings. Corpus-wide verify-translation-pairing passes 1029.
2026-08-31 14:46:31 +08:00
Chinesezjc e0d552fa86 docs: regenerate config-catalog with the python backend config and align the zh side
The master merge brought a stale generated config-catalog that omitted the
dsh-code-runtime-python config section and mislisted the package. Regenerate
docs/config-catalog.md (verify-config-catalog passes), translate the python
config section into zh, keep the ts config-catalog code blocks verbatim
(untranslated, per the pairing rule), and drop the stray zh Library-packages
line. Corpus-wide verify-translation-pairing passes 1029.
2026-08-31 14:45:57 +08:00
Turtle 4df85c85ff feat(issue-management): initialize Issue start dates on PR open 2026-08-31 14:44:20 +08:00
Chinesezjc 203110a90c chore: re-trigger pull_request synchronize for CI 2026-08-31 14:44:19 +08:00
Chinesezjc 9af1e5e9f0 fix(code-runtime-python): correct the log-budget floor to 64 and record the marker envelope bound
The review found the 62 floor off by two (the marker's fixed prefix is 51
characters counting both square brackets, so marker(62) serializes to 63) and
the constructor error over-claiming a bound the marker-as-envelope design does
not deliver. Fixes:
- MIN_LOG_BYTES is 64 (marker-only serialization fits with one byte of room);
  the JSDoc arithmetic counts the brackets; the rejection test pins 63; the
  forged-frame test uses 11 NULs (69 escaped) at 64.
- The constructor error now states the marker-only guarantee, and the README
  Known Limitations (en + zh) records the real bound: a truncated run with
  admitted entries serializes its logs to maxLogBytes + marker + envelope.
- The SIGXCPU-mask tests burn with time.process_time() instead of wall-clock
  perf_counter, so a contended CI runner cannot under-burn the budget.
- The settlement note (en + zh) records the 64 floor and the marker envelope
  bound, including the zh pre-encode section that the earlier pass missed.
- The README constructor-rejection list names the maxLogBytes floor.
Pairings re-recorded; corpus-wide verify-translation-pairing passes 1004.
2026-08-31 14:44:19 +08:00
Chinesezjc 51d57cca03 docs(code-runtime-python): register the log-envelope reservation, SIGXCPU unblock, budget floor, and syntax label
The review flagged four mechanism changes shipped without note registration:
- Log ledgers start one byte below the budget (outer-array envelope reservation)
  and the constructor floors maxLogBytes at 62 (the smallest budget that can
  serialize its own truncation marker plus the envelope).
- die_if_cpu_exhausted restores SIG_DFL before unblocking a program-masked
  SIGXCPU, so a trap+mask program cannot run a re-masking handler at the unblock.
- ast.parse passes filename="<model>" so parse-time syntax diagnostics share the
  compile/runtime source label.
Decision and Testing (en + zh) now record all four with their fail-before cases
(exact-limit, budget rejection, syntax label, SIGXCPU-mask, trap+mask); pairing
re-recorded and consistent.
2026-08-31 14:42:28 +08:00
Chinesezjc 4a8c49f78c fix(code-runtime-python): restore SIGXCPU disposition before unblocking and floor the budgets
Addresses the review's two code warnings and one suggestion:
- die_if_cpu_exhausted now restores SIG_DFL BEFORE unblocking SIGXCPU: a program
  that installed a custom handler AND masked the signal would otherwise have
  that pending handler run at the unblock (in model code, re-masking or raising)
  and escape the re-raise; with SIG_DFL first the pending signal kills inside
  the kernel with no bytecode window. A trap+mask combined regression test pins
  it (the mask-only case was already covered).
- The constructor rejects budgets too small to honor: maxLogBytes must fit the
  truncation marker plus the serialized outer-array envelope (floor 64), and
  maxValueBytes must at least represent the smallest JSON completion (floor 4,
  matching the worker backend). The exact-limit test moves to the 64 floor and
  a rejection test pins the floors.
- The pthread_sigmask None-guard comment cites the real rationale (defensive
  against stripped CPython builds; win32 is refused at construction), not the
  unreachable Windows path.
2026-08-31 14:41:49 +08:00
Chinesezjc a2eda792e3 docs(code-runtime-python): align the accepted-residual dep list across README and note
The residual bullets listed the encoder's transitive deps as an exhaustive set
but disagreed with each other and omitted io. Mark the list as a non-exhaustive
example (e.g. _dump_scalar/_dump_string/json/io) in the README (en + zh) and the
settlement note (en + zh); pairings re-recorded and consistent.
2026-08-31 14:41:49 +08:00
Chinesezjc 4e0d77c1d6 fix(code-runtime-python): reserve the log array envelope byte, unblock SIGXCPU before re-raise
Addresses the review's two remaining code warnings and the three suggestions:
- Log ledgers (host and child) start one byte below the budget, reserving the
  serialized outer-array envelope (two brackets and n-1 commas over n entries'
  separators); the exact-zero test moves to maxLogBytes 104 and a new exact-limit
  case pins that maxLogBytes 5 admits ['a'] (5 bytes) while 4 truncates to the
  marker alone.
- die_if_cpu_exhausted unblocks SIGXCPU (pthread_sigmask SIG_UNBLOCK, captured at
  import, None-guarded for Windows) before re-delivering it, so a program that
  masks SIGXCPU, burns past the soft limit, and returns is still classified as a
  timeout; a regression test pins the masked path.
- ast.parse passes filename="<model>" so parse-time syntax diagnostics carry the
  same source label as compile and runtime tracebacks; the syntax-error test
  asserts the label.
- The NUL-escape test comments use the true six-byte JSON escape \u0000 instead
  of the caret notation; the README Known Limitations (en + zh) records that
  PID-reuse protection is inert on macOS; a combined-rebind regression test pins
  BaseException plus the traceback reporter rebinding together.
2026-08-31 14:41:08 +08:00
Chinesezjc 96597c5ed8 fix(code-runtime-python): bind the _done_with_value entry name and correct the residual documentation
Addresses the review's registration-text accuracy findings:
- _run binds _done_with_value into a local (done_with_value_bound) before the
  program runs, closing the __main__._done_with_value = boom success-rewrite
  vector; a regression test rebinds it and returns a legitimate value, asserting
  the success survives.
- README (en + zh): the CPU-recheck bullet now states the recheck runs
  unconditionally after the program returns (a pre-return overrun dies there as
  a timeout) and the false-success window is only a trap-SIGXCPU program that
  passes the recheck and overruns during the settlement flush/encode; the
  encoder-deps residual rationale is replaced with the actual one (bash-equivalent
  trust, verdict still delivered via the send_done fallback frame) and names the
  now-bound entry; the t.join() deadlock bullet fixes the subject/object (the
  main coroutine joins the worker, blocking the pump's main event loop).
- The portable-identifier-seam architecture note no longer claims the Python
  backend does not exist.
- Settlement note (en + zh) registers the entry-name binding and the new test.
- All pairings re-recorded; corpus-wide verify-translation-pairing passes 1004.
2026-08-31 14:40:35 +08:00
Chinesezjc 8c540fd9fd Merge origin/master (revert of PR 2573)
Master reverted PR 2573, deleting the case-insensitive-path-round-trips
note that carried the dead link, so take the deletion and drop the note
repair from this branch; the jsonl.spec.ts change merges cleanly.
2026-08-31 14:39:37 +08:00
Turtle 0e7c769540 Merge remote-tracking branch 'origin/master' into turtle/pr-864-master-port 2026-08-31 14:39:13 +08:00
Chinesezjc e6b23e829b docs(code-runtime-python): split the deadlock into its own bullet and qualify the done_value claim
Addresses the review's two registration-text accuracy findings:
- The cross-thread t.join() deadlock is a process-isolation-backend property (the
  pump runs on the child's main event loop), so it is split out of the wide-binding
  REPLY bullet into its own Known Limitations entry with the correct attribution
  (fix belongs in this backend, not packages/core/session); the zh half-width
  space is removed.
- The settlement note's _done_with_value def-time default-arg sentence is
  qualified: it guards a rebind of _check_done_value/_encode_json_plain, while a
  transitive encoder dep (_dump_scalar/io) rebind can still downgrade, which is
  registered as an accepted residual in the package README.
Pairing re-recorded; corpus-wide verify-translation-pairing passes 1004.
2026-08-31 14:39:07 +08:00
Turtle b8e3b32fcf Merge master into codex/omit-unneeded-invariants 2026-08-31 14:38:55 +08:00
Chinesezjc c8bc96007b docs(code-runtime-python): register the CPU-recheck and encoder-deps accepted residuals
Document the two remaining keep-current residuals in the python package README
Known Limitations (en + zh), per the review's accepted-resolution path:
- A trap-SIGXCPU program can exceed the soft CPU limit during settlement encoding
  and still report success (containment holds via hard +1s and wall clock; only
  the classification is degraded, because the recheck cannot meter mid-encode).
- The encoder's direct deps (_dump_scalar/_dump_string/json) resolve at call
  time, so a __main__ rebind after a legit return can downgrade success to
  exception; the value path's top-level deps are def-time bound, the transitive
  ones are an accepted residual.
Pairing re-recorded and consistent.
2026-08-31 14:37:52 +08:00
Chinesezjc f79e53e74c docs(code-runtime-python): align the note consequences, register the deadlock and default-arg mechanisms
Addresses the bot's keep-current findings:
- The settlement note distinguishes the BaseException (lost done frame) and
  RuntimeError (pump killed -> replies stranded to the wall clock) consequences;
  registers the _done_with_value def-time default-arg capture and the new
  RuntimeError-rebind closed-loop test; zh:95 half-width space fixed.
- The python package README Known Limitations records the cross-thread binding +
  sync t.join() deadlock (en + zh).
- The code-runtime Service Definition README no longer claims only the
  worker-thread backend ships: the Python (process) backend is acknowledged,
  with 'container' as future work (en + zh).
- All pairings re-recorded; corpus-wide verify-translation-pairing passes 1002.
2026-08-31 14:36:31 +08:00
pku-xht 8bb19f8f7f fix(subprocess): close containment review findings 2026-08-31 14:36:13 +08:00
Chinesezjc 923fb56128 fix(code-runtime-python): bind the reply-pump exception names as def-time default arguments
A body-local X = X binding in _pump_replies is too late: _run reaches the
model's top-level statements (which run first, since there is no suspension
point between create_task and await __dsh_main__) before the pump's first step,
so a __main__.RuntimeError rebind there would be captured by the body local and
a closed-loop failure would escape the except, killing the pump. Bind
_RuntimeError, _BindingRejection, str, and bool as DEF-TIME default arguments of
_pump_replies (evaluated at import, before any model code runs). Add a regression
test that rebinds __main__.RuntimeError as the first program statement and drives
the closed-loop worker pattern, asserting the pump survives and delivers the
later binding. Update the settlement note (en + zh) to describe the default-arg
capture; pairing re-recorded and consistent.
2026-08-31 14:34:09 +08:00
Chinesezjc b018abf405 fix(code-runtime-python): bind the pump RuntimeError after its docstring and _done_with_value deps as defaults
- The reply pump's _RuntimeError binding is placed after the function docstring
  (so the docstring remains the __doc__) and the dead _run-side binding is
  removed. _done_with_value binds _check_done_value/_encode_json_plain as
  default arguments so a __main__ rebind after model execution cannot rewrite a
  success into an exception.

The _str/_bool/_BindingRejection pump bindings were attempted but break the
closed-loop pump test (the self-referential _BindingRejection local interferes
with the closure), so they are left unbound; rebinding those names (builtins and
one internal class) is outside the practical threat model.
2026-08-31 14:34:09 +08:00
Chinesezjc 2d82b658ba fix(code-runtime-python): bind RuntimeError inside the module-level _pump_replies
The previous commit bound _RuntimeError in _run, but _pump_replies is a separate
module-level function, so its except _RuntimeError referenced an out-of-scope
local and raised NameError instead of catching the closed-loop failure — killing
the pump and timing out the run. Bind _RuntimeError at the top of _pump_replies
too. The closed-loop pump test now passes.
2026-08-31 14:34:09 +08:00
Chinesezjc bcc11f1235 fix(code-runtime-python): bind RuntimeError for the reply pump catch and note the exception-class locals
The reply pump's except RuntimeError resolved the module global at runtime, so a
__main__.RuntimeError rebind could make a closed-loop scheduling failure escape
the catch, killing the pump and stranding every later reply. Bind RuntimeError
into a _run local alongside BaseException and catch the local. The settlement
note Decision now records that the exception classes the settlement-path except
clauses catch are bound into locals / a closure cell before model code runs
(en + zh); pairing re-recorded and consistent.
2026-08-31 14:34:09 +08:00
Chinesezjc 69dc17c906 fix(code-runtime-python): bind BaseException into every settlement-path except clause
The rebindable-BaseException vector the bot flagged existed in every except
clause of the settlement path, not just the _run outer catch: safe_model_traceback
(three guards) and the post-done flush swallow resolved the module-global
BaseException at runtime, so a __main__.BaseException rebind plus a throwing
__str__ could let a render-time exception escape and lose the done frame. Bind
BaseException into a _run local (at the top) and a closure cell in
_make_failure_reporter, and change every such except clause to catch the local
— immune to a one-line rebind.
2026-08-31 14:34:09 +08:00
Chinesezjc d5945546c7 docs(code-runtime-python): complete the zh no-fail-before enumeration and unify the seal naming
The zh Consequences section counted ten but enumerated only nine; add the
log-fragment seal as the 10th no-fail-before item. Also unify the term to
'封存' (matching the Decision/Testing sections) instead of '封口'. Pairing
re-recorded and consistent.
2026-08-31 14:34:09 +08:00
Chinesezjc 0102cd95bf fix(code-runtime-python): catch the model exception with a pre-program local exception class
The _run outer try/except used the module-global BaseException, which the
program (running as __main__) can rebind: __main__.BaseException = RuntimeError
made the except resolve to RuntimeError, so a subsequent ValueError escaped _run
with no done frame and misreported the run as worker-exit. Bind BaseException
into a _run local before the program runs so the catch is immune; a regression
test rebinds BaseException and raises, asserting an exception, not a worker-exit.

Also correct the NUL-escape comment text: the JSON escape-result side is \^@ (6
bytes, the valid JSON NUL escape), not \x00, so the 6x-budget arithmetic in the
comments is self-consistent. Register the BaseException-rebind case in the
settlement note Testing (en + zh) and re-record the pairing.
2026-08-31 14:34:09 +08:00
Chinesezjc 202c428137 docs(code-runtime-python): correct the fallback-mechanism wording and the no-fail-before count
Addresses the bot's keep-current review findings:
- The module-level fallback comment now states the mechanism truthfully: the
  module globals are RAW primitives bound into _run LOCALS before the program
  runs (the immunity lives in the frame-local binding, not the module global);
  and the fallback literal <unrenderable> is distinguished from the failure
  reporter's _UNRENDERABLE_DIAGNOSTIC text.
- The settlement note's fallback mechanism wording, the transitive-name rebind
  case (now listing the three fallback primitives), and the no-fail-before count
  are aligned en/zh; the zh Problem paste damage is fixed and the Consequences
  count is ten with the 10th item.
- Pairing re-recorded and consistent.
2026-08-31 14:34:09 +08:00
Chinesezjc d3e34d5612 test(code-runtime-python): replace literal NUL bytes in comments with the escape text
The comments describing NUL serialization contained literal NUL bytes, which
interfere with source tooling. Use the \x00 escape text instead.
2026-08-31 14:34:09 +08:00
Chinesezjc fe3ba24057 docs(code-runtime-python): update the no-fail-before count to ten and document the hard==1 CPU blind spot
Addresses the keep-current review findings:
- The settlement note's Problem/Consequences count is nine -> ten, adding the
  log-fragment seal to the no-fail-before enumeration (its 25 M-scale OOM is not
  deterministically constructible in CI); the new Decision section title now
  names all four mechanisms and the double blank line is removed.
- README Known Limitations (en + zh) documents the 1-second dual-limit
  ulimit -t 1 CPU overrun being reported as worker-exit (the hard >= 2 guard
  cannot lower a 1-second soft to 0); pairings re-recorded and consistent.
2026-08-31 14:34:09 +08:00
Chinesezjc 4ff050de71 fix(code-runtime-python): bind the send_done fallback primitives into locals and use a bare except
The done-frame fallback read _os_write/_memoryview/_FALLBACK_DONE_FRAME as module
globals at call time, so a single-line rebind of any of them reopened the
rebind hole the fallback exists to close. Bind them into _run locals before the
program runs, and use a bare except (which catches everything without naming
BaseException, so a rebind of that name cannot defeat the handler). The
transitive-name rebind test now also rebinds _os_write/_memoryview/
_FALLBACK_DONE_FRAME to pin the fallback's immunity.
2026-08-31 14:33:31 +08:00
Chinesezjc 31c3b425bf docs(code-runtime-python): register the fragment-seal, CPU soft-lowering, and done-send fallback fixes
Keep the settlement note current with the latest code-review fixes:
- New Decision section for the _LogStream fragment seal, the _clamped
  RLIMIT_CPU soft-lowering (and its hard==1 blind spot), the send_done
  fallback frame, and the reply-queue slot release.
- Testing registers the fragment-cap drip (no-fail-before), the dual-limit CPU
  overrun, and the transitive-name rebind cases.
- zh mirrored; settlement-fixes.i18n.yaml re-recorded and consistent.
2026-08-31 14:33:31 +08:00
Chinesezjc 9b29d0226e fix(code-runtime-python): make the log seal incremental, scope the soft-lowering to RLIMIT_CPU, and capture memoryview
Addresses the bot's follow-up review findings on the settlement-path fixes:
- The _LogStream seal joined the WHOLE accumulated buffer past the fragment cap,
  re-copying the growing block O(B^2/cap) times for a large drip. It now seals
  only the current fragments into a _pending_blocks entry (character count
  unchanged), so a 25 M single-character drip stays O(B); the newline/flush/
  _push_bounded_prefix consumers join blocks + fragments once.
- The _clamped soft==hard lowering is scoped to RLIMIT_CPU: for RLIMIT_AS a
  one-byte soft differential would only misalign the child's applied limit with
  the host-side budget gate, with no signal to preserve. The hard == 1 blind
  spot is documented.
- send_done's fallback captures memoryview at import (_memoryview) alongside
  os.write, so a one-line rebind of the name cannot change the fallback write;
  the comment now states the module-level-captured mechanism.
2026-08-31 14:33:31 +08:00
Chinesezjc 72241b9f06 test(code-runtime-python): correct the dual-limit CPU overrun assertion and use a hard limit >= 2
The dual-limit CPU test used ulimit -t 1 (hard == 1), which the _clamped
soft-lowering guard (hard >= 2) intentionally does not lower, and trapped
SIGXCPU (which defeats the fix). Use ulimit -t 2 (hard == 2, so the soft is
lowered to 1) and leave SIGXCPU unhandled; the run then classifies as a timeout.
The message is the CPU-time-exhausted diagnostic, not the literal 'SIGXCPU'.
2026-08-31 14:33:31 +08:00
Chinesezjc dcbce50ec2 fix(code-runtime-python): close the log-fragment OOM, CPU classification, and done-send transitive-dependency findings
Addresses the bot's v16 review on the settlement-path code:
- critical: _LogStream._pending now seals the fragment list past a chunk cap
  (like the host captureStray seal), so a newline-free single-character drip no
  longer accumulates one list slot per write and OOMs on its own accounting.
- _clamped lowers a soft==hard result by one unit (when hard >= 2) so a
  dual-limit ulimit -t leaves SIGXCPU a window to fire and a definite CPU
  overrun is reported as a timeout, not a worker-exit.
- send_done wraps its encode+write in a try and, on any throw from a rebound
  transitive name (_dump_scalar/os), writes a fixed pre-encoded done frame via
  the import-time captured os.write, so a settled exception verdict is never
  downgraded to worker-exit.
- drainReplies clears the consumed replyQueue slot so a wide written payload is
  released immediately, bounding host memory to the current backlog under
  sustained fd-3 backpressure.
Tests added for each (fragment cap drip, dual-limit CPU overrun, transitive-name
rebind done frame).
2026-08-31 14:33:31 +08:00
Chinesezjc add4a2fb6f docs(code-runtime-python): clarify that the binding-all-names case is the fixture that rebinds the send names
The Testing sentence's subject attached the three rebinds to 'the fix' rather than
to the fixture that performs them; reword to 'pinned by a case that rebinds' and
mirror zh ('由一个…用例钉住'), re-recording the pairing.
2026-08-31 14:33:31 +08:00
Chinesezjc 7198234a82 test(code-runtime-python): pin send_done against rebinding write_encoded and _encode_json_plain
The rebinds-every-name fixture previously only rebound ProtocolChannel.send_sync,
which a bound method object ignores and the shipped send_done no longer calls —
so it did not actually guard the call-time-lookup shape. Rebind write_encoded
and _encode_json_plain too (the names send_done would resolve late if it looked
them up at call time) and state that in the settlement note's Testing section
(en + zh), re-recording the pairing.
2026-08-31 14:33:31 +08:00
Chinesezjc 093a6217ff docs(code-runtime-python): register the pre-encode, stray-flush, and late-rejection fixes in the settlement note
Keep the agent note current with the recently landed code-review fixes:
- six -> nine no-fail-before cases, adding the done-value TOCTOU pre-encoding,
  the stray-UTF-8 budget-flush retention, and the late-rejection settled guard,
  each with its reason for not carrying a fail-before test.
- New Decision sections for the pre-encode + send_done binding and the stray
  flush retention; Testing lists the binding-all-names case as a tested fix.
- zh mirrored; settlement-fixes.i18n.yaml re-recorded and consistent.
2026-08-31 14:33:31 +08:00
Chinesezjc da38c16912 fix(code-runtime-python): drain the reply queue by head cursor, not shift()
Each shift() re-slices the remaining array, so draining a large gather of
wide bindings awaiting fd 3's drain was O(n^2). Reading by a head index into
the array keeps the drain linear; the finally still discards everything.
2026-08-31 14:33:31 +08:00
Chinesezjc e0e1aa307d fix(code-runtime-python): bind encode/write for send_done and correct stray-flush retention
Addresses the follow-up review findings on the settlement-path fixes:
- send_done now routes both the pre-encoded VALUE frame and the dict ERROR
  frame through a bound _encode_json_plain + bound write_encoded, never through
  channel.send_sync (whose body re-resolves self.write_encoded and the module
  _encode_json_plain at call time) — a program rebinding ProtocolChannel.
  write_encoded or __main__._encode_json_plain no longer skips the done frame.
- flushStray retention re-accrues the withheld multibyte tail from a FRESH
  utf8 state (previously metering the carried lead against the post-flush
  expected>0 state charged it as an illegal continuation), and skips admitting
  when the whole residual drained into the retained tail so no bogus empty
  entry is pushed.
2026-08-31 14:33:31 +08:00
Chinesezjc be0551f52f fix(code-runtime-python): suppress no-unnecessary-condition on the late-rejection settled guard 2026-08-31 14:33:31 +08:00
Chinesezjc 9e6f279040 fix(code-runtime-python): drop the sealed-blocks ternary in the stray flush to hold 100% branch coverage 2026-08-31 14:33:31 +08:00
Chinesezjc 6634d4800c fix(code-runtime-python): bind done-send callables and cover the stray-flush retention
Corrections to the settlement-path review fixes:
- send_done was invoking channel.send_sync / channel.write_encoded via a late
  method look-up, which a program running as __main__ could rebind through
  __main__.ProtocolChannel.send_sync before the failure path ran — a rebound
  send that raises then skipped the done frame and downgraded a settled
  exception to worker-exit. Bind both channel methods into locals before the
  program runs, mirroring the pre-existing binding of flush_out/flush_err/
  safe_model_traceback.
- Restructure flushStray so the mid-sequence budget-flush retention arm is a
  self-contained v8-ignored branch and the covered default path decodes the
  full residual (not schedulable-through-the-seam boundary).
2026-08-31 14:33:31 +08:00
Chinesezjc f71914ceea fix(code-runtime-python): close four settlement-path review findings
Pace-free completion framing, stray UTF-8 flush, and late-rejection guards:
- Pre-encode the completion value at its validation point so send_done never
  re-walks a live value a mutating daemon thread could change (TOCTOU); a
  mutation-induced encode throw is then classified as 'exception', not a
  host-side worker-exit.
- Budget-triggered stray flush retains an incomplete multibyte UTF-8 tail
  (<=3 bytes) as residual instead of decoding a legal, split character to
  U+FFFD in an admitted entry; the end/closeDeadline paths still full-decode.
- Check 'settled' before formatting a late binding rejection's message, so a
  hostile message getter cannot stall or exhaust a run that already settled.
- Document _check_done_value's first-to-trip ruling in its docstring.
- Rewrite ProtocolChannel.send_sync around a shared write_encoded that the
  done frame's pre-encoded string path uses.
2026-08-31 14:33:31 +08:00
Chinesezjc 06e47b299e docs(code-runtime-python): drop the dangling list-conjunction in the six-item note enumeration 2026-08-31 14:33:31 +08:00
Chinesezjc 117ca8cb67 docs(code-runtime-python): register paced-replies and late-drop in the settlement note 2026-08-31 14:33:31 +08:00
Chinesezjc 441ebd0433 test(code-runtime-python): exempt the mid-drain settle branch from coverage
The drain loop's `if (settled) break` needs the run to settle in the window
between two queued frames. A file probe on the concurrent-replies case shows the
queue does reach depth 11, but the wall clock never lands inside that window, so
the branch is not schedulable from a test; a case written to force it passed
without ever executing the line, so it is removed rather than left as coverage it
does not provide. The branch carries a v8 ignore naming what is unreachable.
2026-08-31 14:33:31 +08:00
Chinesezjc 6f58f9c336 fix(code-runtime-python): pace concurrent binding replies against fd 3
`sendReply` ignored `proto.write`'s `false` return, so a program resolving
several large values in one `asyncio.gather` round encoded every reply in the
same turn and queued all of them in fd 3's writable buffer. Binding resolution
carries no seam-level byte cap to bound that, and the failure kills the host
process rather than failing the run: measured on a 64 KiB-highWaterMark pipe,
eight 4 MiB replies buffered 32.0 MiB at once against 0.0 MiB once paced.

Replies now go through a queue that encodes and writes one frame at a time,
awaiting `drain` when the pipe is full. The encode happens inside the loop, so a
queued reply the run no longer needs is dropped by the `settled` check without
ever being serialized.

This was previously deferred on the grounds that serializing would narrow the
seam's concurrency contract. That reasoning was wrong: the child matches each
reply to its `call` by id from a pump that reads fd 3 continuously, so arrival
order was never observable, and the bindings still run concurrently. Only the
host's peak memory and the flush timing change. The README entry recording the
deferral is removed and the Agent Note records the mechanism instead.
2026-08-31 14:33:31 +08:00
Tianyi Cui cf2d0986cf Merge pull request #3361 from deepseek-harness/revert-2573-fix/windows-path-case-test-fragility
Revert "test(session): resolve one relative root on both sides of the jsonl round-trip"
2026-08-31 14:33:01 +08:00
Tianyi Cui 1f3101982b Revert "test(session): resolve one relative root on both sides of the jsonl round-trip" 2026-08-31 14:32:48 +08:00
Chinesezjc 2a9a917853 fix(code-runtime-python): drop a late binding resolution before snapshotting it
`sendReply` already refuses to write after the run settled, but only after
`snapshotJsonValue` walked and copied the resolution. Binding resolution carries
no seam-level byte cap, so a binding resolving a wide value after `maxWallMs`,
an abort, or dispose settled the run spent host heap building a frame that was
then discarded. The check moves ahead of the snapshot.

Also in this change:

- `readProcessStart` moved after `messageOf`. Inserting it between `messageOf`'s
  JSDoc and its body left that function undocumented and the orphaned block
  reading as a second doc for the reader; `verify-export-jsdoc` does not catch it
  because `messageOf` is not exported.
- The README pair adds the disposed-runtime rejection to `run()`'s public
  contract, which `src/index.ts` has enforced all along.
- Known Limitations records three deferred constraints that until now existed
  only in review discussion: the combined log-and-value peak the load gate does
  not model, the host-side per-member expansion of a wide binding reply (owned by
  `packages/core/session`, and shared with the worker-thread backend), and the
  absence of fd-3 backpressure for concurrent replies.
- The Agent Note's same-group section records the teardown identity guard and its
  two rulings, including why an ABSENT start-time reading proceeds rather than
  withholding the signal, and that reading it as a mismatch is what turned the
  three same-group heartbeat cases red on Linux.
2026-08-31 14:31:48 +08:00
Chinesezjc 0a46bb3414 style(code-runtime-python): keep the teardown v8-ignore under the line limit
The directive carried its whole justification inline at 203 characters, past the
140 the @stylistic/max-len rule allows (imports and template-literal messages
are exempt; a line comment is not). The reasoning moves to the lines above and
the directive keeps a short pointer, since a v8 ignore must stay on one line.
2026-08-31 14:30:02 +08:00
Chinesezjc 68f61b2e2f test(code-runtime-python): exempt the two single-platform teardown arms from coverage
The PID-reuse guard has two arms no single OS can execute: the non-Linux early
return in readProcessStart (the Linux coverage lane always takes the read path)
and the refusal arm, which needs a real pid recycled into a new group leader
between spawn and teardown -- no test can schedule that. The coverage lane
reported 99.53% statements / 99.14% branches on src/index.ts for exactly these
two.

Both carry a v8 ignore naming what cannot be reached and why, the convention
this file and subprocess-local already use for platform defenses. The reader
itself stays covered by the process-identity test rather than being exempted
wholesale.
2026-08-31 14:30:02 +08:00
Chinesezjc 2ad93da755 fix(code-runtime-python): treat an absent start-time reading as reaped, not recycled
The PID-reuse guard refused to signal whenever the current reading differed
from the one taken at spawn, including when it was ABSENT. On Linux a reaped
leader has no /proc/<pid>/stat, so every teardown after the leader exited
skipped SIGTERM/SIGKILL while the group it led still held survivors -- the
exact case the process-group teardown exists to reap. Three same-group survivor
tests went red on the coverage lane; they pass on Darwin because the reader
always returns undefined there, leaving the guard inert.

Only a present-and-different reading now blocks the signal. Verified on the
self-hosted Linux box: a reaped leader with live survivors allows the signal, a
pid whose start time differs still blocks it, and a live matching process is
signalled.
2026-08-31 14:30:02 +08:00
Chinesezjc 33318a5767 docs(code-runtime-python): state the real load-time rejections and finish the zh README
The README pair described `run()` as rejecting "a malformed binding namespace or
non-positive config", which understated and misplaced the configuration
failures: a non-Unix platform, a non-integer budget, a timer value setTimeout
would clamp, a budget larger than one fd-3 frame, and an incompatible
addressSpaceMb/output-budget pair all throw from the CONSTRUCTOR, so they fail
when the plugin loads rather than on a later run. Both sides now separate the
load-time platform/configuration errors from the run-result contract.

The Chinese README's Model Experience and KV Cache effect sections were still
untranslated English; the pairing record only tracks hashes, so it could not
show that. Both are now translated.
2026-08-31 14:30:02 +08:00
Chinesezjc 2e3cf144d5 docs(code-runtime-python): correct the claims the new backend invalidated
Adding a published Python backend and reordering `flush_line` left several
owning documents stating things that are no longer true.

`src/invariant.ts` justified its empty installer with "ships only the fd-3
wire-protocol codec", which the subprocess execution path contradicts. The
reason now states the actual one: every relation this backend maintains lives
in the CPython child or on the fd-3 wire, so no same-process event sequence is
observable from a listener -- the same shape the sibling worker-thread backend
uses.

The seam's `PORTABLE_RESERVED_WORDS` and `language` JSDoc, the code-runtime
README pair, and docs/subsystems/code-runtime both said only TypeScript has a
published backend. Corrected in all four, with the generated cordis catalog
regenerated for the `language` change.

The note attributed the 12x multiple to the settlement flush holding three
copies. That stopped being true when `flush_line` was reordered to drop the
pending chunks before its push: the binding worst case is the newline path's
single near-budget write. Corrected in the note (both sides) and in the test
comment that repeated it.

The note's Testing section now registers the cases this stack added, and the
Chinese side receives the O(depth) entry it never got plus the new ones -- it
had drifted from the English.

`INTERPRETER_BASELINE_BYTES` argued 64 MiB from a RESIDENT set while RLIMIT_AS
bounds address space. It now cites the bootstrap's own measurement (30.23 MiB
of mappings for `python3 -I`), making 64 MiB roughly twice the measured
baseline.

Also: a hardcoded `(:232-235)` comment reference becomes a reference by name,
a "which now walks in O(depth) too" change narrative becomes a current-state
statement, and a stray double blank line is removed.
2026-08-31 14:28:26 +08:00
Chinesezjc e6b547bef4 fix(code-runtime-python): guard teardown, log prefix, and settlement flush
Four independent corrections in the run lifecycle.

`killGroup` signalled `-child.pid` with a raw `process.kill`. Node keeps the
numeric `child.pid` after the leader is reaped and only clears its internal
handle, so `child.kill()` refuses while the raw call does not; `close` can
trail `exit` by seconds when a pipe-holding descendant keeps the streams open.
A recycled pgid could therefore receive this run's SIGTERM and armed SIGKILL.
`groupEmpty()` does not cover it: it reports whether the group has members, not
whether they are ours, and it first runs after the signal. The leader's start
time is now read at spawn and re-checked before each signal, matching the
position packages/subprocess/subprocess-local already states
("ProcessIdentity ... preventing teardown escalation after PID reuse"). Kept
local rather than depending on that package, which would add an architectural
edge. Linux reads /proc; Darwin has no /proc, so the reader reports undefined
and the guard degrades to the previous behavior instead of forking `ps` on a
teardown path.

`_push_bounded_prefix` built `(*self._pending, extra)`, copying every pending
reference into a same-size tuple before the bounded loop. For a
single-character drip that is a second pointer array as large as the list:
measured +80 MiB of tuple over a 40 MiB list for 5.2M chunks, the allocation
the bounded prefix exists to avoid. It now iterates the list in place and
handles `extra` in the loop's `else`; 4000 randomized inputs produce byte-identical
prefixes.

The settlement `flush_out()`/`flush_err()` ran outside any guard while `done`
was already decided, so a flush raising under memory pressure skipped
`send_done` and downgraded a child-classified `exception` into a host-side
`worker-exit`. Both are now wrapped, swallowing only the log tail.

The boot re-check's `if effective_soft != RLIM_INFINITY` was dead: `_clamped`
is asked for a finite `addr_bytes` on both sides and each branch returns that
value or a `min` with an inherited bound, so RLIM_INFINITY is unreachable. The
guard could only ever have skipped the re-check it claimed to protect.
2026-08-31 14:26:23 +08:00
Chinesezjc 8f7d9121d1 fix(code-runtime-python): bound three child-side walks by depth, not width
Three separate paths in the CPython child allocated state proportional to a
value's width or a string's length, so a legitimate input the byte budgets
admit could die as the program's own MemoryError.

`_lossless_json_violation` enqueued one traversal tuple per member while
running, in `dispatch`, over MODEL-CONSTRUCTED binding arguments that no
child-side byte budget bounds first. It now uses the same (kind, container,
iterator) cursor the other two walks already had, checking dict keys as the
cursor pulls each entry. Measured over `[0] * 6_000_000` (~17 MB of JSON):
459.1 MiB of traversal tuples before, 0.0 MiB after.

`_decode_json_plain` matched JSON strings with a `(?:[^"\\]|\\.)*` repetition,
which makes CPython's engine retain backtracking state proportional to the
string's width: 146 MiB for a 1 MiB string, 557.8 MiB for 4 MiB. A legitimate
multi-megabyte binding reply raised MemoryError inside `_pump_replies`, and
because that pump is the only settler of the call's future, the run stranded
until the wall clock reported `timeout`. Strings now scan chunk-to-chunk over a
character class, which the engine matches without backtracking state; the same
4 MiB decode peaks at the 4.0 MiB result.

`_check_done_value` charged strings and dict keys what
`_dump_string(...).encode()` returned, building the escaped copy plus its
encode to MEASURE it -- ~6x the original each for control-heavy text, so
metering a value the budget then rejects could itself breach RLIMIT_AS and
report `exception` where the seam promises `output-limit`. The new
`_json_str_cost` counts instead, reusing `_json_string_cost`'s C-level passes
and reproducing `_dump_string`'s exact surrogate rules (fold spelled-out pairs,
charge six ASCII bytes per lone surrogate). Identical values, 228.9 MiB -> 19.1
MiB of peak on a 20M-NUL string.

Each fix ships a regression test. The two RLIMIT_AS repros are Linux-only:
Darwin does not apply the limit, so the peaks above are measured directly and
recorded in the test comments.
2026-08-31 14:24:59 +08:00
Chinesezjc 86674ed21e test(code-runtime-python): budget the wide-value walk for an instrumented lane
The O(depth) wide-value regression test ran under `maxWallMs: 20_000`, but the
cursor pulls 6M elements one at a time through Python-level frames: ~11s on an
idle machine, and more under the coverage lane's V8 instrumentation with several
workers sharing a runner. CI reported `timeout` instead of the round-trip.

Raise the run's ceiling to 60s inside a 90s vitest timeout, so the runtime's own
wall clock still fires first on a genuine hang. The assertion is unchanged and
still discriminates: restoring the O(width) `stack.extend` enqueue fails the test
with a child-side MemoryError in ~2.6s.
2026-08-31 14:24:59 +08:00
Chinesezjc bca73068f6 fix(code-runtime-python): walk the completion value in O(depth), not O(width)
`_check_done_value` and `_encode_json_plain` pushed one stack entry per child
(plus a separator marker, and `dict.items()` materialized as a list), so the
bookkeeping scaled with the value's WIDTH rather than its depth. A value the
byte meter admits could then die on the walk's own frames: a flat
`[0] * 2_000_000` serializes to 4.0 MB, but measured peaks were 145.2 MB in the
meter and 114.7 MB in the encoder — 28.7x the serialized size, far past the 12x
the load-time address-space gate reserves.

Each container now pushes ONE cursor frame that pulls its children one at a
time and writes into a shared `io.StringIO`, so the output string is the only
width-proportional allocation and the caller already metered its size. Measured
on the same value: 0.0 MB in the meter and 9.0 MB in the encoder (2.3x), with
identical verdicts.
2026-08-31 14:24:59 +08:00
Chinesezjc 9a8663cc4c fix(code-runtime-python): flush logs before framing the completion value
The load gate bounds maxLogBytes and maxValueBytes independently against the
address space, but the child framed the completion value (materializing its
escaped form to meter it, then encoding the frame) while a newline-free log tail
still sat unflushed in _pending. Those two peaks added, so two budgets each
admitted alone could together breach RLIMIT_AS and die as worker-exit instead of
settling. The success path now flushes both log streams before _done_with_value
runs; the trailing flush stays for the exception path and is an idempotent no-op
after a successful settle. A combined-peak regression test (32 MiB each against
512 MiB) asserts the over-budget value reports output-limit rather than OOMing.

Also corrects the worst-case-multiple JSDoc and Agent Note: after 1088d6f03d
made flush_line drop pending before its push, the settlement-flush path holds
two copies, not three, so the newline path is the sole 12x worst case. The
reorder is recorded as a called-out untested fix (the 12x gate already admits
only configs safe under both flush orders).
2026-08-31 14:24:59 +08:00
Chinesezjc aa54467476 Merge origin/master and repair the dead note link from PR 2573
Bring in master through cf6750b10 (including the gate-runner fail-fast
change) and drop the stale fixture reference in the
case-insensitive-path-round-trips note: PR 2573 linked a fixture that PR
3128 had already removed, so every pull request's markdown-links gate
failed on master's own note. The claim stands without naming the deleted
file; verify-md-links now resolves all 2199 files locally.
2026-08-31 14:24:51 +08:00
Chinesezjc faeb4e2218 Merge remote-tracking branch 'origin/master' into fix/windows-coverage-align-linux 2026-08-31 14:23:32 +08:00
Chinesezjc 9d9525549d fix(code-runtime-python): raise the output-budget worst-case multiple to 12 and reject the boundary
The load-time output-budget/addressSpaceMb gate used a worst-case multiple of 8,
assuming two simultaneous ~4x astral copies (the built string and its encode).
Three are live at the peak: on the newline path a single write holds the caller's
text argument, the line slice handed to push, and push's encode copy; the
settlement flush_line path held the pending chunks, their join, and that encode
copy. A budget admitted at 8x (e.g. maxLogBytes 48 MiB against addressSpaceMb 512)
could still OOM the child. The multiple is now 12, the strict `>` is `>=` so a
budget whose peak exactly equals the room left after the interpreter baseline is
rejected (that peak plus the baseline is the whole address space), and flush_line
drops the pending chunks before its push to match the newline path's
join-clear-push order. The child re-check mirror and both note sides move in step;
config-catalog is regenerated from the updated field JSDoc.
2026-08-31 14:22:37 +08:00
Chinesezjc ce91c70f9a test(code-runtime-python): assert the inherited-RLIMIT_AS boot re-check reports exception
The boot re-check raises inside bootstrap's setrlimit-phase handler, which
classifies every resource-limit-application failure as kind 'exception'. The
test asserted 'worker-exit'; align it to the actual class and keep the message
assertion so the case still discriminates a config rejection from a generic
setrlimit error. The Agent Note's two references to the reported kind are
corrected on both language sides and the pair re-recorded.
2026-08-31 14:22:37 +08:00
Chinesezjc 436a97a12d fix(code-runtime-python): reserve the interpreter baseline in the budget gate and re-check against the clamped RLIMIT_AS
The output-budget/address-space gate's 8x multiple had no room for the
interpreter's own footprint, so a budget sized right at addressSpaceMb/8 was
admitted while its worst-case peak plus the interpreter overran RLIMIT_AS
(e.g. 15 MiB maxLogBytes against 128 MiB). Reserve a fixed
INTERPRETER_BASELINE_BYTES (64 MiB) before the multiple claims the rest, so each
budget times 8 must fit the room LEFT after the baseline.

The host gate validates against the CONFIGURED addressSpaceMb, but a launch
environment can inherit a stricter RLIMIT_AS (a ulimit -v wrapper below
addressSpaceMb) that _clamped lowers the effective limit to, leaving the budgets
sized for a ceiling the child never gets. bootstrap.py now re-checks both budgets
against the effective clamped soft limit after applying it, mirroring the host
gate's multiple and baseline, and raises at boot rather than letting a
near-budget output OOM mid-run.

Add regression tests for both (the load gate against a 256 MiB address space
covering both budgets, and a ulimit -v wrapper for the inherited-limit re-check);
register the tail-copy test in the note Testing section; sync the zh pair. Merges
origin/feat/code-runtime-python-protocol to resolve the DIRTY base.
2026-08-31 14:22:37 +08:00
Chinesezjc 86c6d9345e test(code-runtime-python): size the tail-copy repro so the model can build its own string
The tail-copy regression built `"first\n" + "A" * 200 MiB`, whose construction
alone peaks near 400 MiB (the string plus the concat temporary) and OOMs under
the 384 MiB addressSpaceMb before the log path under test runs — a MemoryError in
the model, not the defect. Build the tail in a variable and concatenate only the
newline (peak ~2x150 MiB = 300 MiB, under the address space), so the model's own
allocation fits; the pre-fix code then buffered the whole 150 MiB tail again,
pushing past 384 MiB, while the sliced prefix does not.
2026-08-31 14:22:37 +08:00
Chinesezjc d9307ae2a4 fix(code-runtime-python): size the output-budget/address-space gate by worst-case Unicode and gate both budgets
The load-time addressSpaceMb gate used a 1/8 fraction derived for ASCII, but the
child ledgers trigger on character count against a serialized-byte budget: an
astral character is one character yet ~4 bytes stored and ~4 encoded, live at
once, so the true worst-case peak is ~8x the budget, not ~2x. Replace the
fraction with an explicit OUTPUT_BUDGET_WORST_CASE_ADDRESS_SPACE_MULTIPLE (8)
and a strict `>`, and gate maxValueBytes the same way as maxLogBytes — the value
path builds and encodes a near-budget completion under the same RLIMIT_AS, so
the incompatible pair was previously admitted there too.

Slice the newline branch's unterminated tail to a budget-sized prefix: it
buffered the whole text[pos:] before the flush trigger could bound it, so an
early newline plus a huge tail made a second full copy of the model's string —
an RLIMIT_AS death the config gate cannot cover since the tail can far exceed
maxLogBytes.

Disclose the cross-field constraint in the maxLogBytes/maxValueBytes/addressSpaceMb
JSDoc (regenerating config-catalog); refresh the note's stale
Buffer.byteLength(JSON.stringify) reference; reconcile the arrival-order rebuttal
with the seam's "in order" logs JSDoc (within-stream, cross-stream best-effort).
Extend the load-rejection test to both budgets and add a tail-copy regression;
sync the zh pair.
2026-08-31 14:22:37 +08:00
Chinesezjc 2df88b5bbe fix(code-runtime-python): reject an oversized maxLogBytes at load instead of metering log capture at runtime
The child log ledger encodes an admitted entry to UTF-8 once to charge its
serialized cost, so a maxLogBytes approaching addressSpaceMb lets a legitimate
near-budget log entry breach RLIMIT_AS and die as worker-exit instead of
truncating. Two runtime fixes were tried and both traded one resource bound for
another: an exact serialized-cost check is either a full encode (the allocation
being avoided) or a per-character Python loop that burns the CPU budget (a 10 MB
write hits SIGXCPU under cpuSeconds:1). The breach is a property of the
maxLogBytes/addressSpaceMb pair, not any write, so reject the incompatible pair
at load — maxLogBytes must stay within one eighth of the addressSpaceMb byte
count — and revert _LogStream to its original character-count buffering, which
is memory-safe once the budget fits the address space. The check runs on every
platform since the incompatibility is a config-value property, not a runtime one.

Replace the child-flood regression tests (which asserted the reverted runtime
behavior) with a load-rejection test. The host-side accrueStrayCost UTF-8
per-lead validation and its tests are unaffected. Update the note and zh pair.
2026-08-31 14:22:37 +08:00
Chinesezjc c24e1e991b fix(code-runtime-python): charge structurally-valid-but-illegal UTF-8 and newline-path logs by decoded cost
accrueStrayCost accepted any 0x80-0xBF continuation, so a CESU-8 surrogate
(ED A0 80) or overlong (E0 80 80) — structurally well-formed but illegal, and
as cheap to flood as 0xFF — was charged its structural width 3 while
toString('utf8') renders each byte as its own U+FFFD (cost 9). Validate each
lead's first-continuation range (WHATWG E0/ED/F0/F4 bounds) and charge 3 per
byte of any sequence outside it, folding a broken prefix to one U+FFFD.

The child _LogStream newline path had the same char-vs-serialized gap the
newline-free trigger had: its per-line fit checks (first reconstructed line and
each subsequent line) compared character count against the serialized-byte
budget, so a control-char line passed and _logs.push encoded it whole, breaching
RLIMIT_AS. Route every check through _fragment_cost_upto, which sums per-char
costs from _json_char_cost over a start/end sub-range without slicing or
encoding and stops at the budget.

Decline arrival-order stray flushing: the two pipes' data events interleave
nondeterministically and logs carries no cross-pipe ordering guarantee, so a
fixed drain order is as valid as any and an arrival-tick branch could not be
covered without a flaky test.

Add CESU-8/overlong, newline-path-flood, and all-lead-class reassembly
regression tests; fix the note's now-inaccurate CESU/illegal-byte claims and a
fixture byte-count comment; sync the zh pair.
2026-08-31 14:22:37 +08:00
Chinesezjc 5c43621ed2 fix(code-runtime-python): weigh the child log flush by per-fragment serialized cost, allocation-free
The prior child-flush fix measured each fragment with chunk.encode('utf-8'),
which copies the whole write — under a tight addressSpaceMb a single 340 MiB
write died on that encode (the exact allocation _push_bounded_prefix exists to
avoid), and re-scanning the whole pending list per write was quadratic under a
daemon-thread flood (the concurrent-write test timed out at 28s). Compute each
fragment's serialized cost with _fragment_cost_upto, which walks the str via a
new _json_char_cost (code point to escaped width, no encode) and stops once the
running total passes the budget, and accumulate it into _pending_cost once per
write. The early-flush trigger reads that accumulator: still charges control
chars their full serialized width (a NUL is 6 bytes), but never encodes a whole
write and never re-scans the buffer, so the 340 MiB single-write and
daemon-thread tests pass alongside the NUL-flood one.

Rework the child NUL-flood regression to write in 1 MiB chunks under a 512 MiB
address space so its own argument construction is not the allocation under test.
2026-08-31 14:22:37 +08:00
Chinesezjc d9f2fa1b04 test(code-runtime-python): drive the child NUL-flood test without a single huge argument
The child-log-flood regression built one 30M-char argument string, which under
the 64 MB addressSpaceMb died on RLIMIT_AS during construction (exit 120) before
the flush trigger under test could run, so it failed on Linux CI. Write the
flood in 1 MiB chunks under a 512 MiB address space instead: the argument str is
never itself the allocation under test, the fixed serialized-cost trigger keeps
the pending tail bounded to a few MiB, and the run completes at the marker; the
pre-fix char-count trigger accumulates the whole ~200 MiB and its ~1.2 GiB
settlement encode breaches RLIMIT_AS. Mirrors the addressSpaceMb budget the
existing oversized-completion tests use.
2026-08-31 14:22:37 +08:00
Chinesezjc dbff8ffba3 fix(code-runtime-python): charge illegal UTF-8 by its U+FFFD width on both log paths
The host stray-capture cost function charged illegal UTF-8 bytes (0x80-0xC1,
0xF5-0xFF, and orphaned multibyte leads) the raw 1, but toString('utf8')
renders each as U+FFFD (3 serialized bytes). A b"\xff" flood was undercounted
threefold, so the residual grew to a full budget's worth of raw bytes before
flushing and, near a large maxLogBytes, expanded toward a ~1 GiB peak in the
flush's concat plus toString. Replace serializedBufferCost with accrueStrayCost,
a cross-chunk UTF-8 walker that charges each byte its decoded serialized width;
carry its sequence state on each StrayBuffer.

The child _LogStream had the same-family bug: its early-flush trigger compared
_pending_chars (character count) against remaining (a serialized-byte budget),
so a 30M-NUL newline-free flood stayed under a 50 MB char trigger yet encoded to
~180 MB at settlement, breaching RLIMIT_AS as worker-exit. Track _pending_cost
via the _JSON_BYTE_COST table and trigger on it; keep _pending_chars for the
char-based slice bounds.

Correct the note's surrogate claim (only the string-walking jsonStringCostUpTo
charges a lone surrogate six bytes; the byte walker never sees one). Shrink the
post-truncation fixture below PIPE_BUF for a deterministic single callback. List
the shared stdout/stderr budget as a third honest fail-before exception
(cross-pipe arrival timing is nondeterministic). Add illegal-UTF-8,
broken-multibyte, and child-log-flood regression tests; sync the zh pair.
2026-08-31 14:22:37 +08:00
Chinesezjc 45814baf26 test(code-runtime-python): make the stray-seal copy-volume bound discriminate
The stray-sealing regression test asserted copied < 2 MiB — about 4x the
defended sealed shape, so reverting the seal to a re-merge (or removing it)
left the test green. Measured both shapes as the fd-3 sibling does: the sealed
shape copies ~120 KB, the re-merge shape ~538 KB. Tighten the bound to 256 KiB,
which sits between them, and record the measurements in the comment and the
Agent Note so the fail-before claim holds.
2026-08-31 14:22:37 +08:00
Chinesezjc e76b3baf9e fix(code-runtime-python): meter stdout and stderr stray residual against one shared budget
stdout and stderr each checked their pending serialized cost against the full
logBudget independently, so both could retain nearly a budget's worth of
newline-free residual at once — double the intended peak, up to ~512 MiB near
the ceiling. The flush threshold now reads the COMBINED cost of both pipes and
flushes both when it crosses, since they share one ledger.

Remove the post-truncation admit() v8-ignore: captureStray's per-line loop
makes that branch deterministically reachable within one data callback (a chunk
whose first newline-terminated line exhausts the budget hits it on the second),
so it is measured by a new regression test rather than ignored.

Refresh two stray-output test comments that still named the removed
StringDecoder; the raw-chunk buffer reassembles a split multibyte sequence by
concatenating before it decodes, and the end flush renders a stranded partial
as U+FFFD via toString('utf8').
2026-08-31 14:22:37 +08:00
Chinesezjc f29b4b1cb9 fix(code-runtime-python): seal stray fragments, flush by serialized cost, charge lone surrogates fully
Three follow-ups the review caught in the stray-capture rewrite, plus a cost
undercount shared with the log ledger.

Seal the stray fragment list into blocks past MAX_PENDING_CHUNKS, mirroring the
fd-3 reader: a program pacing single-byte os.write(1, ...) calls otherwise
accumulates one live Buffer per write, and the per-object overhead no byte
count sees exhausts the host heap far below the budget.

Flush the residual by its running SERIALIZED cost (serializedBufferCost, a
per-byte lower bound) rather than raw byte count: a control-char-dense
newline-free flood serializes several-fold, so a raw-byte threshold let it grow
to a full budget's worth of raw bytes — up to ~6x what the ledger admits —
before flushStray concat/decoded the whole ~256 MiB residual at once.

Charge a lone surrogate its full six escaped bytes (\uXXXX under ES2019
well-formed JSON.stringify) in both jsonStringCostUpTo and serializedBufferCost,
not the three bytes Buffer.byteLength reports for U+FFFD: a forged log frame
flooding \ud800 escapes was undercharged by half and admitted ~2x maxLogBytes.

Key the sync-spawn leak assertion off the exact bootstrap path from the mocked
spawn's argv, immune to a sibling worker's concurrent staging. Refresh the
stale load-check comment that named the replaced JSON.stringify mechanism.

Add lone-surrogate, stray-sealing, and companion regression tests (per-file
100% coverage); update the Agent Note and zh pair.
2026-08-31 14:22:37 +08:00
Chinesezjc a9c480bf39 docs(config-catalog): refresh the code-runtime-python Config source line
Removing the now-unused StringDecoder import shifted the Config interface
down by one line; regenerate the embedded source reference.
2026-08-31 14:22:36 +08:00
Chinesezjc 8093d22164 fix(code-runtime-python): bound stray capture by serialized cost, chunk-scan, and flush on destroy
The line-aggregating stray capture from the previous round regressed three
ways the review caught. Rewrite it on the fd-3 reader's raw-Buffer-chunk
shape: accumulate chunks with a byte counter and split on the raw 0x0a byte,
so a large newline-free write no longer re-copies the residual and re-scans
from index 0 per chunk (both O(N^2)). Meter each admitted entry by serialized
cost through a new jsonStringCostUpTo that walks to the cap and stops, so a
near-budget control-char-dense line never allocates the sixfold-inflated
JSON.stringify result the old ledger did (the critical: ~1.6 GiB transient
under a large maxLogBytes). Flush the residual explicitly in the closeDeadline
handler before it destroys the streams, so a setsid escapee's path (which
fires no end) does not drop a leader's final newline-free diagnostic.

Harden the sync-spawn leak assertion to a set difference against a pre-run
snapshot, immune to a parallel worker's concurrent tmpdir create/delete.

Decline the round-2 request to enforce the fd-3 ceiling per-frame: the counter
check must precede Buffer.concat to prevent ~2x memory doubling (two
regression tests assert this), and the batch-edge false reject it would fix is
reachable only at a maxLogBytes/maxValueBytes configured within one pipe read
of the 256 MiB ceiling, far past the defaults. Documented at the check and in
the note Alternatives.

Add flood, NUL-flood, short-escape, and closeDeadline-flush regression tests
(restoring per-file 100% coverage); update the Agent Note and zh pair.
2026-08-31 14:21:57 +08:00
Chinesezjc c8bf75cbe4 test(code-runtime-python): cover the newline-free stray-flood ledger bound
The line-aggregating stray capture added two branches — the post-truncation
early return and the residual-overflow admit — that the aggregation and
split tests did not exercise, so per-file coverage dropped below 100%. A
2 MB newline-free native write under a 4 KiB maxLogBytes drives the residual
across the budget (admit-and-truncate) and then short-circuits later chunks,
asserting the captured output ends at the truncation marker and stays under
budget rather than buffering the whole flood.
2026-08-31 14:21:57 +08:00
Chinesezjc 44203f3fa7 fix(code-runtime-python): resolve worker-exit on sync spawn failure; aggregate stray output by line
Wrap spawn and the fd-3 narrowing so a synchronous throw (ENAMETOOLONG on
an over-PATH_MAX pythonBin, EMFILE) removes the run's staging directory and
resolves the same worker-exit class as the async error event, instead of
rejecting run() and leaking the directory.

Aggregate native stdout/stderr by real newline rather than by Node data
chunk: logs entries are joined with "\n" downstream, so a newline-free
write larger than one pipe read no longer reads back with spurious breaks.
The ledger still bounds a newline-free flood.

Track a running scan offset in both frame readers so a large frame
accumulated across chunks is scanned once, not re-scanned from 0 per chunk.

Reword the deadline hard-bound v8-ignore to state its real environment
dependence (PID-1-doesn't-reap container, zombie survivor) and cross-ref
the note's rejected signal-0 alternative; fix settle comments that quoted
the pre-qualification teardown contract; document the capMessage vs
_cap_message billing split on both sides; guard the dispose-after-resolve
heartbeat assertion against a vacuous 0===0 pass; reuse
_TRUNCATION_MARKER_BYTES; note the abandoned-call pending-entry bound.

Update the Agent Note Decision/Testing/Alternatives/Consequences for the
above and record the confirmed-empty finalize as a second honest
fail-before exception; sync the zh pair.
2026-08-31 14:21:57 +08:00
Chinesezjc 1103e36c22 fix(code-runtime-python): confirm group death at the deadline; chunk the frame read
The reap-poll deadline arm sent SIGKILL then finalized immediately, declaring
quiescence on mere signal delivery while the group was still dying. It now keeps
polling for the group to actually empty (bounded by one more reap margin) after
its self-sent SIGKILL, so `finished` resolves only on a confirmed-empty group.

ProtocolChannel.read_frame read the boot/run handshake frames through
FileIO.readline() on the unbuffered fd — one os.read(1) per byte, so a
multi-megabyte program burned CPU (RLIMIT_CPU already in force for the run frame)
in millions of syscalls before ast.parse. It now reads in chunks into the same
_pending buffer the async reader uses; the wrapping os.fdopen is gone. read_frame
is this PR's own code (e7f22ed3), not the protocol layer. The chunked read is a
syscall-count improvement with no cross-platform-deterministic failure to assert,
noted as such in the Agent Note.
2026-08-31 14:21:57 +08:00
Chinesezjc 28f747d775 test(code-runtime-python): cover the reply-pump closed-loop guard; align setsid docs
The closed-loop reply-pump guard now ships with a deterministic regression test:
a worker thread abandons a binding so its loop closes, the host answers that call
before a later binding, and the pump must survive the closed-loop
call_soon_threadsafe to deliver the later reply (host-gated ordering makes it
deterministic; unguarding the pump hangs the later binding to the wall clock).

Align the quiescence self-description with the shipped setsid limitation:
teardown()'s JSDoc and the Agent Note's Problem line now qualify "no subprocess
outlives the fiber" to subprocesses that stay in the child's process group, with
a setsid()-escape exception pointing at the README. Tighten the setsid-orphan
fixture's self-timeout to 5s and its upper-bound assertion to <4000ms so a failed
deadline backstop is a sharper red. Register the new regression tests in the note.
2026-08-31 14:21:57 +08:00
Chinesezjc bea8708b5d fix(code-runtime-python): reject a non-integer maxLogBytes/maxValueBytes at load
The child reads these byte budgets through int(...), which silently floors a
float, so maxLogBytes: 3.5 would truncate at 3 bytes child-side while the host
meters and marks at 3.5 — the two sides enforcing different public config. Gate
them to integers at load, as the worker backend does; correct the stale comment
that claimed the int()-truncated caps needed no gate. Adds a regression test.
2026-08-31 14:21:57 +08:00
Chinesezjc db5f890c7f test(code-runtime-python): update CPU-timeout assertions to the reworded message
The SIGXCPU timeout message changed from "CPU budget (Ns) exhausted" to name the
configured value as a ceiling; two existing timeout tests asserted the old text.
Assert "CPU time exhausted" to match.
2026-08-31 14:21:57 +08:00
Chinesezjc 63c49c8a90 fix(code-runtime-python): meter the exception diagnostic by serialized cost
Raising maxValueBytes' load bound to ceiling-envelope assumed both budgets are
metered in serialized (JSON-escaped) bytes, which held for completion values and
logs but not the diagnostic: _cap_message capped by raw UTF-8, so a control-heavy
message near maxValueBytes could serialize sixfold and breach the fd-3 frame
ceiling — the silent worker-exit inversion the load check prevents. _cap_message
now accumulates per-byte serialized cost (new _JSON_BYTE_COST table) and cuts the
prefix that fits. Also reword the host SIGXCPU timeout message to name cpuSeconds
as the configured ceiling rather than a budget a stricter inherited RLIMIT_CPU
soft may undercut. Adds a control-heavy-diagnostic regression test.
2026-08-31 14:21:57 +08:00
Chinesezjc e0d5d8d097 fix(code-runtime-python): send SIGKILL at the reap-poll deadline, not cancel it
The group-reap poll folded its deadline arm into the empty-group arm, so a host
event loop blocked past graceMs + CLOSE_REAP_MARGIN_MS would run the overdue
poll before the grace SIGKILL timer: the group is still non-empty, the deadline
has passed, and the shared arm cancelled the never-fired SIGKILL and finalized —
releasing a SIGTERM-ignoring same-group survivor for good. Split the arms: empty
group cancels the moot timer and finalizes; deadline-with-non-empty-group sends
SIGKILL itself (idempotent if the timer already ran) before finalizing. Adds a
regression test that busy-blocks the loop past both timers and asserts the
survivor's heartbeat freezes.
2026-08-31 14:21:57 +08:00
Chinesezjc b1ce014035 fix(code-runtime-python): restore per-file branch coverage on the reap poll
The group-reap poll's deadline arm (Date.now() >= deadline) is a backstop that
SIGKILL emptying the reachable group never reaches, leaving one uncovered branch
under the per-file 100% gate. Mark it v8-ignore with the reason and drop the
always-true graceTimer-defined guard inside pollGroup (it runs only when killing
is set, so kill() has armed the timer).
2026-08-31 14:21:57 +08:00
Chinesezjc ecdb79824b fix(code-runtime-python): keep a completed run in live until its group is reaped
settle() dropped the run from `live` eagerly, before the grace-window SIGKILL
reaped a same-group survivor. A dispose() racing a just-resolved run() then
snapshotted an empty `live` and returned while the descendant was still alive,
so teardown's "no subprocess outlives the fiber" (and its JSDoc) was false for
that window. The run now stays in `live` until the process-group poll confirms
the group empty, at which point it is both dropped from `live` and its finished
promise resolved. Adds a regression test asserting dispose() of a completed run
with a same-group survivor returns only after the survivor stops executing.
2026-08-31 14:21:57 +08:00
Chinesezjc 9f449a79a6 docs(code-runtime-python): correct the ProtocolChannel serialization docstring
The class docstring still credited the GIL plus per-frame PIPE_BUF atomicity for
serializing writes, which _write_lock's full-write loop already superseded. State
the current contract (writers serialized by _write_lock around a full-write loop)
and drop the double blank line under the binding-replies note heading.
2026-08-31 14:21:57 +08:00
Chinesezjc a8e47dae37 docs(code-runtime-python): note the settlement CPU recheck uses the clamped soft
Record that die_if_cpu_exhausted compares against the effective clamped cpu_soft
in the rlimit section, and add the recheck-timeout test to Testing; re-record pair.
2026-08-31 14:21:57 +08:00
Chinesezjc 6141f0062d fix(code-runtime-python): recheck CPU against the effective clamped soft limit
The settlement-time CPU recheck compared spent CPU against the configured
cpuSeconds, but _clamped may have lowered the effective soft limit to a stricter
inherited value. A program that traps SIGXCPU, burns past the inherited soft,
and returns inside the soft-to-hard gap was checked against the configured value
and falsely reported successful, bypassing the inherited limit. The recheck now
uses the clamped cpu_soft. Adds a regression test that inherits a 1s soft CPU
limit and asserts a SIGXCPU-trapping over-burn is a timeout, not a success.
2026-08-31 14:21:57 +08:00
Chinesezjc d432603b81 docs(code-runtime-python): note the closed-loop reply-pump guard
Record the call_soon_threadsafe-onto-a-closed-loop guard in the binding-reply
section of the settlement-fixes Agent Note; re-record the bilingual pair.
2026-08-31 14:21:57 +08:00
Chinesezjc a30b460b37 fix(code-runtime-python): keep the reply pump alive past a closed thread loop
A binding called from a worker thread records that thread's loop for its reply.
If the thread finished and closed its loop before the host reply arrived,
_pump_replies' call_soon_threadsafe onto the closed loop raises RuntimeError;
unguarded, that ends the pump task and strands every later reply. Wrap the
schedule in a try/except that drops the moot reply (nothing awaits it) and keeps
the pump serving.
2026-08-31 14:21:57 +08:00
Chinesezjc 3a560d37a6 docs(code-runtime-python): document the setsid-escape teardown limitation
A descendant that calls setsid()/start_new_session leaves the child's process
group, so kill(-pid) teardown cannot reach it; if it also releases the inherited
pipes the run still settles and the fiber goes quiescent while the orphan runs.
This is the containment boundary (model code has bash-equivalent trust), not a
guarantee; reaching such an orphan needs descendant-pid tracking and is deferred.
2026-08-31 14:21:57 +08:00
Chinesezjc ff604dc876 fix(code-runtime-python): clear stale SIGKILL timer and clamp inherited soft rlimit
Two further review findings on the CPython backend:
- The grace-window SIGKILL timer was left armed after settlement, so on a
  normal completion a kill(-pid) could fire up to graceMs later and strike a
  recycled pgid once the kernel reused the leader's pid. settle() now clears
  the timer the moment the process group is confirmed empty (the normal path
  and when the poll sees the survivor gone), bounding the reuse window to the
  genuine-survivor case where the group cannot be empty to reuse.
- _clamped bounded rlimits by the inherited hard limit only, silently raising
  an inherited soft limit stricter than the request (loosening RLIMIT_AS or
  deferring RLIMIT_CPU SIGXCPU). It now clamps each side against its own
  inherited counterpart and pins soft under hard, keeping the strictest of
  configured and inherited. Adds an inherited-soft-limit regression test.

Agent Note expanded to seven fixes with the two new rejected alternatives;
zh pair re-recorded.
2026-08-31 14:21:19 +08:00
Chinesezjc 6cb70e6e69 fix(code-runtime-python): reap same-group survivors and fix cross-loop bindings
Two review findings on the CPython backend:
- Disposal could return while a same-group descendant that ignores SIGTERM
  but releases the inherited pipes was still alive: the leader's close fired
  and the previous fix relied on an unref'd SIGKILL timer that a short-lived
  host never fires, reparenting the survivor to init. settle() now withholds
  the run's finished promise on a ref'd process-group poll until the SIGKILL
  has emptied the group (bounded by graceMs + margin, zero-cost when already
  empty), so teardown's "await each child's exit" holds.
- A binding called from a model worker thread via asyncio.run created its
  reply Future on that thread's loop, but _pump_replies completed it directly
  from the main loop; asyncio.Future is not thread-safe across loops, so the
  call hung to the wall clock. Replies now complete via the owning loop's
  call_soon_threadsafe, and a lock serializes the id claim/write/advance.

Tests: the same-group reap case now asserts a heartbeat file stops (robust
whether the killed descendant is reaped or a zombie, so it holds where PID 1
does not wait() orphans); a cross-loop case runs a binding from a worker
thread and asserts the reply round-trips instead of timing out. Agent Note
expanded to all six fixes with rejected alternatives; zh pair re-recorded.
2026-08-31 14:21:19 +08:00
Chinesezjc 46db9e2ad4 test(code-runtime-python): update output-cap bound to ceiling-envelope
The frame-ceiling cap test asserted the old (ceiling-envelope)/6 bound and
its 44739232 message. The load bound is now ceiling-envelope because both
budgets are metered in already-escaped bytes; assert 268435392.
2026-08-31 14:21:19 +08:00
Chinesezjc 9a05c0075f fix(code-runtime-python): reap same-group children and correct log-budget bound
Address review findings on the CPython backend:
- CRITICAL: a model program could leave a descendant in the child's own
  process group that ignores SIGTERM but releases the inherited pipes, so
  the leader's `close` fired and settle() cancelled the pending SIGKILL
  before it escalated — run()/dispose() returned while that child lived.
  kill() now unrefs the grace timer and settle() no longer clears it, so
  the SIGKILL reaches the whole group; killGroup swallows ESRCH when the
  group is already gone (the normal case). Adds a real-subprocess
  regression test.
- WARNING: the maxLogBytes/maxValueBytes load bound divided the frame
  ceiling by 6 for escape expansion, but both budgets are metered in
  already-escaped serialized bytes, so a payload occupies at most
  cap+envelope on the wire. Bound is now ceiling-envelope; drop the unused
  escape constant.
- Narrow the runtime.spec.ts header to "no subprocess mocks" (it mocks
  node:fs.copyFileSync for staging-failure cases).
- Use full-width punctuation in the README.zh.md prose per translation
  rules; re-record the pair.
2026-08-31 14:21:19 +08:00
Chinesezjc 538ad4d3dc docs(code-runtime-python): sync README with the shipped backend
The package README (both languages) still described this layer as
protocol-only with the PythonCodeRuntime implementation deferred to a
later PR, contradicting the shipped code. Rewrite the intro to describe
the registered runtime, add a Configuration section for every Config cap,
and drop the "implementation not in this layer" limitation. Also pin the
residual-detach fixture's size invariant: the byteLength assertion only
holds above Node's Buffer pool threshold.
2026-08-31 14:20:00 +08:00
Chinesezjc e576ceb913 docs: regenerate module graph for the code-runtime-python dependency
Adding @deepseek-ai/dsh-code-runtime to the backend manifest introduces a
new edge the generated graph must reflect.
2026-08-31 14:16:47 +08:00
Chinesezjc 27901c547f fix(code-runtime-python): declare the dsh-code-runtime dependency
The manifest omitted @deepseek-ai/dsh-code-runtime although src/index.ts
imports CodeRuntime and the portable-identifier constants from it and the
tsconfig references ../code-runtime. A three-way package.json merge over
the protocol-layer stub dropped the entry; restore it in peer and dev
dependencies so the declaration matches the import.
2026-08-31 14:16:02 +08:00
Chinesezjc 7b4b8df2dd docs(code-runtime-python): fix settlement-fixes note wrap and cross-link
Unwrap the English note to one physical line per paragraph (verify-md-wrap)
and retarget the backend link to the fd-3 protocol architecture note that
this stack actually ships (verify-md-links); re-record the bilingual pair.
2026-08-31 14:14:33 +08:00
Chinesezjc c388169cff feat(code-runtime-python): add the CPython subprocess backend
Land the PythonCodeRuntime implementation on top of the fd-3 protocol
seam: python3 -I per run, binding namespace over fd 3, RLIMIT_CPU/AS,
wall-clock timer, and SIGTERM->grace->SIGKILL process-group teardown,
with the real-subprocess integration suite.

Fixes three defects surfaced on the source PR's review before they ship:
- boot-write failure resolved a worker-exit through finish()/settle()
  that read wallTimer/onAbort/live in their TDZ, rejecting run() instead;
  the boot write now runs after those bindings and the v8-ignore that hid
  the branch is removed.
- log capture serialized against settlement with no lock while model
  daemon threads keep writing; LogBuffer now owns one shared re-entrant
  lock taken by write/flush_line/push.
- the fd-3 line residual was a subarray view pinning the whole joined
  frame; it is copied into a right-sized Buffer via detachResidual so
  pendingBytes measures what is retained.
2026-08-31 14:14:32 +08:00
Chinesezjc 456dcdd8fb Merge pull request #3211 from deepseek-harness/ci/gate-fail-fast
ci: fail fast at the first blocking gate failure
2026-08-31 14:14:22 +08:00
Chinesezjc 43cfe6a26e Merge origin/master into fix/windows-coverage-align-linux
Resolve the 08-08 note conflict (keep the zero-build rewrite, drop the
SQLite busy-journal sentence removed with the SQLite backend) and drop the
now-removed session-persistence-sqlite built-package suite from the
lib-consuming self-skip inventory in the ci.yml comment, the
ci-workflow.spec.ts comment, and the partitioned-coverage note; the
inventory is now image-loadable, transform-corpus, and client-bundle.
2026-08-31 14:13:51 +08:00
Tianyi Cui 2491a9d1d9 Merge pull request #2573 from deepseek-harness/fix/windows-path-case-test-fragility
test(session): resolve one relative root on both sides of the jsonl round-trip
2026-08-31 14:13:23 +08:00
Tianyi Cui 817c67d799 Merge pull request #3339 from deepseek-harness/worktree/session-format-01-jsonl-only
refactor(session)!: remove SQLite persistence backend
2026-08-31 13:58:04 +08:00
_Kerman a2de3af0d2 Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery
# Conflicts:
#	apps/cli/package.json
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/examples/agent-spine-demo/package.json
#	packages/goal/goal/package.json
#	pnpm-lock.yaml
2026-08-31 13:43:45 +08:00
_Kerman 700d5407fb Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery
# Conflicts:
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/api/session-controller/src/control.ts
#	packages/context/agent-instructions/tests/agent-instructions.spec.ts
#	packages/test-support/agent-loop-testkit/package.json
2026-08-31 13:37:55 +08:00
_Kerman 2aeb9920ee test(agent-loop): remove duplicated Inbox fixture 2026-08-31 13:37:23 +08:00
_Kerman 17774f7fb1 Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery 2026-08-31 13:37:22 +08:00
_Kerman d776df1106 test(agent-loop): exclude unreachable teardown paths 2026-08-31 13:37:19 +08:00
_Kerman fcad57b3af Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery 2026-08-31 13:37:19 +08:00
_Kerman c33fe6265e fix(agent-loop): restore inbox projection test wiring 2026-08-31 13:37:15 +08:00
_Kerman fc746f7851 refactor(agent-loop): own inbox projection in loop 2026-08-31 13:37:12 +08:00
_Kerman 35371d0f59 Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery
# Conflicts:
#	packages/api/session-controller/src/control.ts
2026-08-31 13:37:12 +08:00
_Kerman b9b2a37528 Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery
# Conflicts:
#	apps/cli/tests/fixtures/dsh-badge/snapshot.ts
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	docs/persistence-catalog.i18n.yaml
#	docs/persistence-catalog.md
#	docs/persistence-catalog.zh.md
#	packages/api/session-controller/tests/session-projections.host.spec.ts
#	packages/context/agent-instructions/tests/agent-instructions.e2e.ts
#	packages/context/agent-instructions/tests/agent-instructions.spec.ts
#	packages/context/tmux-context/tests/tmux-context.spec.ts
#	packages/core/agent-loop/package.json
#	packages/core/agent-loop/src/agent.ts
#	packages/core/agent-loop/src/index.ts
#	packages/core/agent/src/index.ts
#	packages/core/agent/src/types.ts
#	packages/goal/goal/tests/goal.spec.ts
#	packages/goal/tool-goal/package.json
#	packages/llm/llm-retry/tests/retry.spec.ts
#	packages/session-query/session-query/tests/observation.spec.ts
#	packages/shell/tool-pwsh-persistent/tests/loader-composition.spec.ts
#	packages/test-support/agent-loop-testkit/package.json
#	packages/workflow/workflow-worker-thread/tests/workflow-worker-thread.e2e.ts
#	pnpm-lock.yaml
2026-08-31 13:37:06 +08:00
_Kerman 1101422362 refactor(agent): keep concrete inbox loop-internal 2026-08-31 13:36:49 +08:00
_Kerman ea222a1f72 fix(agent): report missing inbox projection 2026-08-31 13:36:45 +08:00
_Kerman f3858fc2a7 Merge remote-tracking branch 'origin/master' into dshw/pr-deepseek-harness-deepseek-harness-2672
# Conflicts:
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
2026-08-31 13:36:45 +08:00
_Kerman 77d0ee38d2 docs: refresh Claude SDK notices 2026-08-31 13:36:39 +08:00
_Kerman c46c3df2f2 test: cover projection-aware session helpers 2026-08-31 13:36:34 +08:00
_Kerman 882a87c4bc Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery 2026-08-31 13:36:34 +08:00
_Kerman 37c5dc4b35 Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery
# Conflicts:
#	docs/subsystems/session-projection.i18n.yaml
#	docs/subsystems/session-projection.md
#	docs/subsystems/session-projection.zh.md
#	packages/context/agent-instructions/tests/agent-instructions.spec.ts
#	packages/core/agent-loop/README.i18n.yaml
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/README.zh.md
#	packages/core/agent-loop/tests/cancel.spec.ts
#	packages/core/agent/README.i18n.yaml
#	packages/core/agent/README.md
#	packages/core/agent/README.zh.md
#	packages/llm/llm-retry/tests/retry.spec.ts
#	packages/session/session-projection/README.i18n.yaml
#	packages/session/session-projection/README.md
#	packages/session/session-projection/README.zh.md
2026-08-31 13:36:28 +08:00
_Kerman 8b0ea3e461 fix(session-controller): derive queues from projections 2026-08-31 13:35:52 +08:00
_Kerman e5f2fbd9a2 fix(agent): validate durable inbox reconstruction 2026-08-31 13:35:49 +08:00
_Kerman 4b1683c287 Merge remote-tracking branch 'origin/master' into dshw/pr-deepseek-harness-deepseek-harness-2672
# Conflicts:
#	docs/module-graph.i18n.yaml
2026-08-31 13:35:46 +08:00
_Kerman a20c5ad0a3 Merge remote-tracking branch 'origin/master' into dshw/pr-deepseek-harness-deepseek-harness-2672
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
2026-08-31 13:35:39 +08:00
_Kerman 31ba0d6ae3 Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/api/session-controller/tests/session-projections.host.spec.ts
2026-08-31 13:35:33 +08:00
_Kerman 87d041b2c1 Merge remote-tracking branch 'origin/master' into xtr/durable-inbox-recovery 2026-08-31 13:35:25 +08:00
_Kerman f9227e0be6 docs(session-projection): keep registry contract unchanged 2026-08-31 13:35:21 +08:00
_Kerman 6ea9dd565b Merge remote-tracking branch 'origin/master' into dshw/pr-deepseek-harness-deepseek-harness-2672 2026-08-31 13:35:17 +08:00
_Kerman 8eb0c50e74 test(session-projection): scope projection assertions 2026-08-31 13:35:03 +08:00
_Kerman 43bc150338 Merge remote-tracking branch 'origin/master' into dshw/pr-deepseek-harness-deepseek-harness-2672 2026-08-31 13:35:03 +08:00
_Kerman 9ff0212fbd Merge origin/master into xtr/durable-inbox-recovery 2026-08-31 13:34:56 +08:00
_Kerman 90b7ac94e2 test: trim unrelated inbox changes 2026-08-31 13:34:25 +08:00
_Kerman bd3b651ea8 refactor(agent): remove inbox service 2026-08-31 13:34:22 +08:00
_Kerman df2bae9639 Merge remote-tracking branch 'origin/master' into dshw/pr-deepseek-harness-deepseek-harness-2672 2026-08-31 13:34:09 +08:00
_Kerman 633daf6624 Merge remote-tracking branch 'origin/master' into dshw/pr-deepseek-harness-deepseek-harness-2672
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/core/agent-loop/tests/cancel.spec.ts
2026-08-31 13:33:36 +08:00
_Kerman aaf50dc39a refactor(agent): back Inbox with a durable projection 2026-08-31 13:32:59 +08:00
Tianyi Cui 4553c9d957 refactor(session)!: remove SQLite persistence backend 2026-08-31 13:23:07 +08:00
Turtle c68676d3c9 Merge pull request #3128 from deepseek-harness/turtle/remove-agent-spine-demo
refactor(bundle): remove the agent spine demo
2026-08-31 13:17:45 +08:00
Yichen Jiang 43afef8576 fix: settle what the master merge broke
`AGENTS.md` sat at exactly its 1950-word ceiling on master, so the one line this
branch adds to the repository layout — a new top-level package group — cannot
fit at any length: even a one-word description overflows. The description is
condensed to five words and the ceiling raised by ten, the smallest change that
keeps every package group listed. Omitting only `net/` from a list that names
every other group was the alternative.

One new test drove an IPv4-mapped literal through a full fetch. An IPv6 literal
sends `resolvePublicAddresses` looking for a NAT64 prefix before it refuses
anything, and that is a real DNS query — 5s under load, 6ms here, which is why
it passed alone and timed out in the full suite. The three IPv4 cases already
prove the branch end to end without touching the network, so the mapped form is
asserted on the predicate instead.
2026-08-31 13:07:21 +08:00
Yichen Jiang 44a9687bbe Merge remote-tracking branch 'origin/master' into worktree/deepseek-harness-proxy-config-2f5b4a
# Conflicts:
#	apps/cli/package.json
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/e2b/e2b/package.json
#	packages/llm/llm-deepseek/package.json
#	packages/llm/llm-pi-ai/package.json
#	packages/test-support/session-snapshot/package.json
#	packages/workflow/workflow-worker-thread/package.json
#	pnpm-lock.yaml
2026-08-31 12:58:59 +08:00
Chinesezjc 0868e5d128 test: make windows coverage timing assertions deterministic
cache.spec.ts polled fire-and-forget fail-soft writes with a fixed 40ms
settle(); contended runners drain the write after the window, so the
warn/row assertions flaked. Poll the observable outcome with vi.waitFor
(5s) instead, matching the file's existing cold-read write-back pattern.

The sdk-client and subagent-dsh-sdk dispose-ladder tests passed tight
confirmation budgets (disposeGraceMs 100-300ms) to real children; on a
contended runner the SIGKILL exit edge can arrive after the budget and
close() misreports a slow reap as failure. Use the product-default
budgets (disposeGraceMs 3000ms) for the real-child cases; the fake-child
negative cases in dispose.spec.ts keep the 10ms bound.
2026-08-31 12:42:01 +08:00
Chinesezjc a9bc7b7056 fix(ci): add client-bundle to the zero-build self-skip inventory
client-bundle.client.spec.ts reads packages/client/ui-trajectory/lib/client.js
and skips all three cases when the bundle is absent, so it is a fourth
lib-consuming suite in the instrumented corpus. List it beside built-package
in the ci.yml comment, the ci-workflow.spec.ts comment, and the
partitioned-coverage note (both languages).
2026-08-31 12:13:43 +08:00
Chinesezjc 16853e1f77 fix(webworker-packer): update image-loadable JSDoc for zero-build coverage
Both coverage lanes now run before any build, so the post-build
uninstrumented gate wording applies only to the serial-windows complete
reference; preview builds still exercise the suite against real
artifacts.
2026-08-31 12:03:47 +08:00
Chinesezjc 2dd8b3eac3 fix(ci): harden the zero-build coverage assertion and list all skip suites
Strengthen the ci-workflow.spec.ts guard to match any 'pnpm run build'
spelling (corepack prefix, multi-line run blocks) instead of one exact
string, and complete the lib-consuming self-skip inventory with the
webworker-runtime transform-corpus import sweep alongside the packer
image assertions and the built-package check. Update the ci.yml comment
and the partitioned-coverage note (both languages) to match, and drop the
stale 'post-build' phase wording and the native-Windows build-wait
rationale from the coverage-exempt comment.
2026-08-31 12:00:05 +08:00
Yichen Jiang 6de470e61b fix(net): keep this machine off the proxy, and refuse a literal the checks reject
Review found `127.0.0.2` routed through the proxy. The bypass list carries four
literal loopback entries because that is all a consumer reading an environment
can match, and `proxyForUrl` matched only those — leaving the rest of
`127.0.0.0/8`, `0.0.0.0`, and the IPv4-mapped spellings routed through a proxy
that could then reach them. Loopback is now recognised structurally, which a
list entry cannot express; the published entries stay for the environment
readers.

The same review case exposed a wider one. `web_fetch` skips its address checks
on a proxied hop, because the proxy resolves the origin — but a literal needs no
resolution, so the skip bought nothing and let a proxy on this machine reach
every private range those checks refuse, `169.254.169.254` included. A literal
the checks would refuse now takes the validated path, where the existing
refusal already covers it.

Tests that proved a tunnelled hop used a loopback origin, which no policy can
route through a proxy any more. They name a host only the proxy can answer for
instead — closer to what a proxied request actually looks like.

The user guide promised the proxy carried every outbound request including
telemetry. It carries neither on an older Node, nor anything a model-authored
script sends, so the promise is narrowed and the exceptions listed. A password
in a proxy URL reaching every tool DSH runs is documented there too: it is how
the variable already behaves, and worth knowing before putting one in.
2026-08-31 11:57:40 +08:00
Chinesezjc ec6a98452d Merge branch 'master' into ci/gate-fail-fast 2026-08-31 11:56:44 +08:00
07akioni 903a926897 feat: optimize ipc perf 2026-08-31 11:54:28 +08:00
07akioni 52b84e8564 chore: missing content 2026-08-31 11:54:28 +08:00
07akioni 2ef85b1e17 fix: windows build 2026-08-31 11:54:28 +08:00
07akioni 19444907f0 feat: electron 打包 2026-08-31 11:54:28 +08:00
Chinesezjc e2ef25b06e fix(ci): windows coverage runs zero-build like the linux lane
The windows-coverage job built the workspace before running the same
ci-coverage gates as Linux, but the instrumented corpus resolves
workspace imports to src through the tsconfig paths map and never
consumes lib/; the two lib-consuming suites (webworker-packer
image-loadable, session-persistence-sqlite built-package) self-skip on
unbuilt checkouts, exactly how the Linux lane already runs them. Remove
the build step so both lanes behave identically, and pin the zero-build
invariant in ci-workflow.spec.ts (red before this change, green after).

Agent Notes updated in place: corrected the build-wait rationale and the
wrong attribution of the packer assertions to the instrumented suite.
2026-08-31 11:40:33 +08:00
Turtle 4c69dc3fed test(loader): budget production profile startup 2026-08-31 11:23:46 +08:00
Turtle 16c8cf30ed test(goal): cover projection teardown access 2026-08-31 11:23:46 +08:00
Turtle fddad3a236 test(sdk): mount session projections in loop fixtures 2026-08-31 11:23:46 +08:00
Turtle 8528e4039d chore(cli): trim test-only profile dependencies 2026-08-31 11:23:46 +08:00
Turtle 287651fd89 test(cli): replay the session title separately 2026-08-31 11:23:30 +08:00
Turtle 244de7c18a refactor(bundle): remove the agent spine demo 2026-08-31 11:23:30 +08:00
Dudu-0223 43840d6ece fix(subagent): harden adjacent message guidance 2026-08-31 11:16:00 +08:00
CreatixChu c3672eb1e3 Merge pull request #3277 from deepseek-harness/worktree/fix-3269-read-image
fix(tool-fs): accept extension-less attachment paths in read_image
2026-08-31 11:12:47 +08:00
CreatixChu 65b8e51042 Merge pull request #3208 from deepseek-harness/worktree/steer-followup-images
fix: deliver images reliably with steer and follow-up messages
2026-08-31 10:57:44 +08:00
_Kerman 6c63e708b8 Merge remote-tracking branch 'origin/master' into dshw/pr-deepseek-harness-deepseek-harness-2907
# Conflicts:
#	docs/config-catalog.i18n.yaml
#	docs/persistence-catalog.i18n.yaml
#	docs/subsystems/session.i18n.yaml
#	packages/api/session-controller/tests/transport.host.spec.ts
#	packages/bundle/headless/src/index.ts
#	packages/core/session/README.i18n.yaml
#	packages/schedule/schedule/README.i18n.yaml
#	packages/schedule/schedule/README.md
#	packages/schedule/schedule/README.zh.md
#	packages/session-query/tool-session-query/src/workspace-access.ts
#	packages/session/session-log-deepseek/src/index.ts
2026-08-31 10:56:53 +08:00
creatixchu 6516fbcde8 Merge origin/master into worktree/steer-followup-images 2026-08-31 10:37:39 +08:00
creatixchu 90a8467213 Merge remote-tracking branch 'origin/master' into worktree/fix-3269-read-image 2026-08-31 10:00:53 +08:00
Chinesezjc 4032a0a428 ci(windows): use ReFS block-clone installs on the self-hosted VM (#3342)
pnpm hardlinks node_modules files to the store on the same volume, and
TypeScript's native realpath resolves those links back to store paths
(F:/.pnpm-store/v11/files/...), producing TS6231 during tsc -b and vite
resolution. ReFS block cloning (package-import-method=clone) gives each
file an independent path while sharing physical blocks, avoiding the
leak without the copy cost. Clone mode needs the @reflink/reflink native
module, which the system corepack pnpm carries but pnpm/action-setup's
dest build omits, so installs run through corepack pnpm.

The install steps branch on the workspace filesystem: clone only on
ReFS, plain install on hosted NTFS (which rejects copy-on-write). The
serial-windows store points at F:\.pnpm-store to share the ReFS volume.
Agent Note 2026-08-30-windows-refs-store-block-clone-install records the
rationale; ci-workflow.spec asserts the branch.
2026-08-31 04:13:15 +08:00
Chinesezjc 161c6591be ci: fail fast at the first blocking gate failure 2026-08-31 01:54:14 +08:00
Dudu-0223 ff34b6c28e test(web): pin expanded snapshots to bottom 2026-08-30 16:12:43 +08:00
Dudu-0223 5b91cdbf8b Merge remote-tracking branch 'origin/master' into feat/3220-steer-service 2026-08-30 16:08:31 +08:00
Dudu-0223 3091bdc257 fix(subagent): address steer review findings 2026-08-30 16:08:20 +08:00
Dudu-0223 9f86f31411 test: align catalogs and packed session fixtures 2026-08-30 14:44:12 +08:00
Dudu-0223 b957733bce docs: confirm config catalog pairing 2026-08-30 14:36:02 +08:00
Dudu-0223 487d61bd14 docs: refresh subagent config source link 2026-08-30 14:31:32 +08:00
Dudu-0223 4fce895468 test(subagent): cover unified messaging setup 2026-08-30 14:27:37 +08:00
Dudu-0223 575dc58a07 Merge remote-tracking branch 'origin/master' into feat/3220-steer-service 2026-08-30 14:16:37 +08:00
Dudu-0223 b91e7ce366 Unify adjacent Agent messaging 2026-08-30 14:14:46 +08:00
Chinesezjc 3137b33ba9 ci: redirect Node compile cache to data-volume runner temp 2026-08-29 18:51:06 +08:00
Chinesezjc a4d4404708 feat(ui-tool): render read_image results as the image
A settled top-level `read_image` call printed its raw attachment object as
literal text in the tool card — `{"type":"image","attachment":{…}}` —
instead of the image, because no presentation metadata told a client card
how to present the reference and the tool-card layer had no image concept.

Host: `read_image` declares an `output.presentationMeta` persisting
`{ path }` only. The attachment reference deliberately lives in the
settled result content — the single record a `tools/post-execute`
replacement rewrites — not in `meta`; the id is opaque and
provider-owned, checked for existence only.

Client: `imageCardModel` derives the card from the call head, the meta
path, the result's own image block, and a shape-matched envelope. ToolRow
gains an `image` card slot; the `read_image` toolview declares the
Tool-owned `tool.call.images` slot as its child and dispatches the
gallery through it. ui-chat down-threads the session-authorized loader
(`ChatNodeOwnerProps.loadImage`), so the tool layer supplies only derived
references plus the loader and never imports an attachment
implementation; ui-attachment fills the slot with its message gallery
renderer. The card keeps the envelope text below the gallery for the
no-attachment-plugin deployment. An image-bearing tool registers a keyed
toolview; the generic fallback keeps its flattened text. `read_image`
joins the read variant with its own locale title key; both rows share
`read-family-row.tsx`.

Verification: `read-image.spec.ts` (metadata projection, envelope by
shape, reference narrowing, real-execution round trip, rejection
branches incl. non-digest ids), `image-card.client.spec.tsx` (derivation,
row render site dispatching the slot, keyed registration with the
child-slot declaration, empty-slot fallbacks, media-type enum), keyless
snapshots (`read-image-gif` added; read-image/-dimension/-reencode
updated to the `{path}` meta), five injected-defect negative controls,
and a demo GIF recorded from this PR's head through the official
image-capable model.
2026-08-29 17:41:05 +08:00
pku-xht 976456db8e Merge master to adopt Flash E2E coverage 2026-08-29 17:39:31 +08:00
pku-xht 93c11689e7 fix(subprocess): address containment review findings 2026-08-29 15:44:13 +08:00
Yichen Jiang b239db6aeb test(net): assert the proxy-name contract on a platform that folds case
The Windows coverage lane failed on four cases that assume `http_proxy` and
`HTTP_PROXY` are separate variables. They are one variable there: `process.env`
is case-insensitive, and the launch snapshot folds names for the same reason. A
scenario built on "the user set only the lowercase name" cannot exist.

Two of them assert a contract rather than a spelling, so they now hold either
way: what reaches a child for a scheme the user named is the user's own value
and never the derived one, and a nested install carries the active policy's
value rather than the outer install's published one. Both read over the pair of
names instead of one.

The other two are about the case distinction itself. Neither can hold on a
folded environment, so each asserts what that platform does instead of skipping:
the later entry wins where a preference cannot be expressed, and a diagnostic
names the spelling resolution asked for. Both were verified against the folding
arm rather than reasoned about.
2026-08-29 13:37:29 +08:00
Yichen Jiang 03d2c54db1 test: start every suite from an environment with no proxy
A developer's Clash and a CI runner's squid both export HTTP_PROXY and its
siblings. Now that the harness honors them, an ambient value decides test
outcomes: this PR has already recorded a proxy's 502 page as a snapshot's
expected output, and let a runner's own export stand in for "what the user
exported" in an assertion about inherited names.

A Vitest setup file clears the proxy names before any suite runs, wired into
every configuration that declares a setup. Real-API e2e is cleared too: before
proxy support existed every request connected directly and that suite passed, so
direct is the environment it is known to work in.

`NODE_USE_ENV_PROXY` cannot be cleared this way — Node samples the proxy
environment at process start — and the module says so. A proxy application never
exports it, and the eight names one does export are fully handled: with all of
them set, the affected suites pass.

The wiring is what regresses, so that is what the test pins. Configurations are
discovered rather than listed, because the web suites carry no setup today and a
hand-written list would let one of them gain a setup without gaining this one.

`plugin.spec.ts` kept its own copy of the eight names to guard against the
machine; it never sets a proxy variable itself, so the setup replaces that
entirely. `install.spec.ts` had one assertion waiting on a DNS miss with no
deadline, which timed out once under load.
2026-08-29 13:17:12 +08:00
Yichen Jiang 2a73128d78 docs(net): describe the worker seam as it is, not as a mechanism that exists
`installGlobalProxy` claimed each worker thread calls it with a policy its host
passed through `workerData`. Nothing does: the two workers this repository ships
evaluate model-authored scripts and are deliberately left without a proxy URL
that may carry credentials.
2026-08-29 13:17:12 +08:00
Yichen Jiang 4623c68e70 perf(scripts): parse only the files the dispatcher gate can find a violation in
`agentBindings` now walks the whole tree to reach a dynamic `import('undici')`,
which pushed the repository-wide scan past the 5s default under the coverage
lane's instrumentation.

Both violations name one of two words in source: an agent construction needs a
binding from the undici module, and the option is a property called
`dispatcher`. Skipping a file that mentions neither leaves 21 of 1597 files to
parse, so the scan runs in ~60ms instead of ~500ms — well clear of the timeout
even instrumented.
2026-08-29 13:17:12 +08:00
Yichen Jiang cfc9b3bdef fix(net): route by the policy, and give a child the routing its parent has
Second review pass on the outbound proxy work.

The installed dispatcher was undici's EnvHttpProxyAgent, which reuses the HTTP
proxy for `https:` whenever no HTTPS proxy is present. That is exactly the state
this package resolves after refusing a SOCKS or malformed URL the user named for
`https:`, so the scheme the diagnostic reported as direct was tunnelled anyway.
The dispatcher is now an Agent whose per-origin factory calls `proxyForUrl`, so
routing and `proxyForUrl` cannot disagree by parsing the same list twice.

`childProxyEnv` returned only the names the user exported, which left a child
Node direct whenever the proxy came from `ALL_PROXY` or from cordis.yml — Node's
`NODE_USE_ENV_PROXY` reads neither — and stripped the merged loopback bypass so
the child sent its own localhost traffic to the proxy. A scheme the user named
in either casing still reaches the child exactly as written; one they named in
neither now carries the resolved value, and the bypass list is always the merged
one.

A nested install (the plugin mounted over the launcher's policy) recorded the
outer policy's published values as the user's, then cleared the record on
disposal, so every later child inherited the normalization instead. The record
now belongs to the outermost install and is restored, not dropped.

`web_fetch` read the active policy twice — once to skip address pinning, again
inside the transport — so a disposal landing between the two reads produced an
unpinned direct connection to a host nothing validated. One snapshot now decides
both.

Also: the node:http proxy test asserted a route the engines range does not always
have, and the gate could not see undici bound through `await import('undici')`,
the form this repository actually uses.
2026-08-29 13:17:12 +08:00
Yichen Jiang 52e39cd783 test(net): clear the ambient proxy before asserting what a child inherits
The case builds a user environment and asserts a child receives it verbatim,
so a runner that exports its own proxy supplied half the "user" values and
decided the assertion.
2026-08-29 13:17:12 +08:00
Yichen Jiang e6dbf85f6c fix(net): address review — containment, opt-out, and syntax-aware discovery
The workflow worker no longer receives proxy configuration: it executes the
model-authored script body, and a proxy URL may carry credentials. A child
process now inherits the values the user exported rather than this process's
normalization, so a SOCKS proxy set for curl survives and no HTTPS_PROXY is
invented. `mode: 'off'` installs a direct dispatcher instead of recording a
policy the global dispatcher ignores, and the environment snapshot is taken
before any write so Windows restores the user's values.

E2B picks its proxy from the control-plane URL the SDK will really call, the
OTLP agent honors `exporter.keepAlive`, and a scheme whose own value was
refused stays direct instead of borrowing another scheme's proxy.

verify-no-bare-dispatcher parses the TypeScript AST as scripts/AGENTS.md
requires; it immediately found the `{ dispatcher }` shorthand the regex missed.
2026-08-29 13:17:12 +08:00
Yichen Jiang aa0ed35ebc test(snapshot): isolate a replayed dsh from the machine's proxy environment
A replay must not depend on the runner's network policy, the same reason it
pins its home and sessions root. The harness now honors the proxy environment,
so a runner exporting one sent the web-fetch scenario's fixture request to a
proxy that could not resolve the fixture host and recorded that proxy's error
page. Clear the proxy names in both test-support spawners, from the one list
dsh-http-proxy owns.
2026-08-29 13:17:12 +08:00
Yichen Jiang ca20b9af11 test(llm): cover the DeepSeek and pi-ai request paths with egress tests
Both adapters' inference requests were argued from a code read and, for
DeepSeek, from one product smoke. Drive each shipping adapter at an
unresolvable endpoint through a fake proxy instead, and cover pi-ai's provider
stream rather than only its model discovery.
2026-08-29 13:17:11 +08:00
Yichen Jiang 35bc2d1d45 fix(webworker): register a node:https placeholder for the proxy agent factory
The VFS packer sweeps module requests statically, so dsh-http-proxy's agent
factory made the preview image unpackable: it names node:https for the SDKs
that post through Node's core HTTP modules, a path the worker never takes.
Mock it the way node:net is mocked rather than hiding the request.
2026-08-29 13:17:11 +08:00
Yichen Jiang ec82e3e3ee test(net): assert the child and worker proxy seam by Node version
NODE_USE_ENV_PROXY reaches Node 24.0+ and 22.21+, while engines admits 22.19.
Assert the direct connection on an older runtime instead of only the proxied
one, so the seam is executable rather than prose.
2026-08-29 13:17:11 +08:00
Yichen Jiang 545e2ad914 feat(net): route every outbound request through the configured proxy
Node's built-in fetch ignores HTTP_PROXY, so every harness request connected
directly regardless of what the user exported. Resolve one policy from the
launch environment and install it as undici's global dispatcher, then wire the
four surfaces a global dispatcher cannot reach: web_fetch's pinned transport,
the OTLP exporter's node:http agent, the E2B SDK's own proxy option, and the
environment a child process or worker thread is given.

Each outbound call site carries an egress test that drives its real code path
through a fake proxy; that measurement is what found the OTLP and E2B gaps.
2026-08-29 13:17:11 +08:00
pku-xht aaa5117ebd fix(subprocess): preserve literal spawn error stacks 2026-08-29 13:08:43 +08:00
pku-xht c0e7b98169 test(subprocess): preserve optional spawn error keys 2026-08-29 13:02:36 +08:00
pku-xht 13f3b2c172 fix(subprocess): match native spawn error semantics 2026-08-29 12:13:30 +08:00
pku-xht 60dd357a02 fix(subprocess): preserve native spawn error shape 2026-08-29 11:36:27 +08:00
pku-xht 1760649ba7 refactor(subprocess): derive native owner state 2026-08-29 11:28:33 +08:00
pku-xht a416b13eb5 fix(subprocess): preserve Windows search miss errors 2026-08-29 10:28:44 +08:00
pku-xht 5aab793045 fix(subprocess): preserve clean Windows range settlement 2026-08-29 09:08:34 +08:00
pku-xht 6e7b152de7 fix(subprocess): preserve native runner contracts 2026-08-29 07:57:59 +08:00
pku-xht 23af4410f6 fix(subprocess): resolve source runner loader absolutely 2026-08-29 06:14:15 +08:00
pku-xht a825b8d042 fix(subprocess): close native containment contract gaps 2026-08-29 05:56:29 +08:00
pku-xht 40279aea17 fix(subprocess): preserve native runner stdio 2026-08-29 00:03:12 +08:00
pku-xht 635c35991c test(subprocess): type Linux exec mock 2026-08-28 22:38:18 +08:00
pku-xht a0bc2ea803 fix(subprocess): preserve native runner launch semantics 2026-08-28 22:34:09 +08:00
pku-xht aca5c0cb2b fix(subprocess): release Windows runner stdio owners 2026-08-28 21:29:09 +08:00
pku-xht 32b2b24099 fix(subprocess): close runner stdio handles 2026-08-28 20:30:11 +08:00
pku-xht 8096aba953 Merge remote-tracking branch 'origin/master' into codex/subprocess-native-containment 2026-08-28 19:55:24 +08:00
pku-xht 8ef28f76c0 fix(subprocess): preserve Windows runner spawn semantics 2026-08-28 19:55:16 +08:00
pku-xht 9aecbad9dd fix(subprocess): keep runner worker-loadable 2026-08-28 19:16:34 +08:00
pku-xht b65575442d Merge origin/master into codex/subprocess-native-containment 2026-08-28 18:34:22 +08:00
_Kerman 71c34ff13a docs: refresh module graph 2026-08-28 18:18:07 +08:00
pku-xht a95f0b368f fix(subprocess): contain escaped descendants with native owners 2026-08-28 18:15:49 +08:00
_Kerman ebce3a5f04 refactor(agent): make runtime identity explicit 2026-08-28 17:44:56 +08:00
creatixchu f3c69c2c3f refactor(tool-fs): keep image sniffing tool-local 2026-08-28 16:10:19 +08:00
creatixchu 8d337b2b32 Merge remote-tracking branch 'origin/master' into worktree/fix-3269-read-image 2026-08-28 15:37:32 +08:00
creatixchu 6f08798981 docs(tool-fs): sharpen extension notes and pin dotfile edge cases 2026-08-28 15:37:27 +08:00
creatixchu adfd7074f3 Merge remote-tracking branch 'origin/master' into worktree/steer-followup-images 2026-08-28 15:23:15 +08:00
creatixchu 3b2e5105e6 Merge remote-tracking branch 'origin/master' into worktree/steer-followup-images 2026-08-28 15:19:28 +08:00
creatixchu aaa692033b test(snapshots): project new attachment-path fixtures into packed layout 2026-08-28 15:16:20 +08:00
_Kerman 4096b0b408 refactor(time-context): scan turn messages in reverse 2026-08-28 15:02:12 +08:00
creatixchu 7222e17dc0 fix(tool-fs): accept extension-less attachment paths in read_image 2026-08-28 15:02:04 +08:00
_Kerman 1b6f9a1b51 refactor(session-telemetry): simplify capture replay 2026-08-28 14:58:11 +08:00
_Kerman 32d681f023 fix(subagent): preserve empty restored model selection
Detect explicit empty seeds through the existing end-seed marker and remove the redundant Session.seeded API.
2026-08-28 14:55:46 +08:00
_Kerman 47e6448e23 perf(session): avoid unnecessary event snapshots 2026-08-28 14:17:21 +08:00
_Kerman bcfec8d1c3 perf(session): reuse immutable event snapshots 2026-08-28 13:43:16 +08:00
_Kerman 5660f44d29 perf(session): separate indexed and snapshot log reads 2026-08-28 13:25:58 +08:00
Turtle 15f2997bcb cleanup: omit unneeded invariant companions 2026-08-28 13:12:52 +08:00
creatixchu 878857a5f2 Merge remote-tracking branch 'origin/master' into worktree/steer-followup-images 2026-08-28 10:35:50 +08:00
Chinesezjc 206fb8b53c test(session): resolve one relative root on both sides of the jsonl round-trip 2026-08-28 10:21:26 +08:00
Dudu-0223 ec493c2db8 feat(subagent): unify adjacent agent delivery on steer 2026-08-28 01:04:46 +08:00
creatixchu b9060b4f9b Merge remote-tracking branch 'origin/master' into worktree/steer-followup-images
# Conflicts:
#	packages/context/file-reference-local/tests/search.spec.ts
2026-08-27 23:29:17 +08:00
creatixchu 61f65ffd48 test: allow Windows title diagnostic latency 2026-08-27 23:27:14 +08:00
creatixchu 0158adc926 Merge remote-tracking branch 'origin/master' into worktree/steer-followup-images
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
2026-08-27 22:33:20 +08:00
creatixchu 6f446e196b ci: retrigger pull request workflows 2026-08-27 22:29:06 +08:00
creatixchu 267bdd60aa test: allow loaded Windows coverage timing 2026-08-27 22:26:06 +08:00
creatixchu 266440c5a7 test: allow Windows merge-driver latency 2026-08-27 21:25:46 +08:00
creatixchu 56f1a3bde6 test: gate unreadable directory case to POSIX 2026-08-27 21:23:49 +08:00
creatixchu 318bf7d2c1 test: account for Windows chmod coverage 2026-08-27 20:44:35 +08:00
creatixchu eb349d56e6 Merge remote-tracking branch 'origin/master' into worktree/steer-followup-images 2026-08-27 20:44:04 +08:00
creatixchu 145f936946 test: stabilize queued image browser snapshot 2026-08-27 20:29:25 +08:00
creatixchu 21d2d9395d refactor: align prompt admission and echo ownership 2026-08-27 20:14:18 +08:00
creatixchu b71d0a35ef Merge remote-tracking branch 'origin/master' into worktree/steer-followup-images 2026-08-27 19:46:54 +08:00
creatixchu 2c1cc3e778 refactor: narrow closing-turn wake tracking 2026-08-27 19:37:25 +08:00
creatixchu 53f5418a72 fix: 稳定 steer 提交回显位置 2026-08-27 17:25:36 +08:00
creatixchu 5bb24c03f1 test: avoid untyped catalog matcher 2026-08-27 16:57:12 +08:00
creatixchu abe185205b fix: scope prompt catalog type to client 2026-08-27 16:49:15 +08:00
creatixchu b67663c583 fix: retain prompt parts in client catalog 2026-08-27 16:42:11 +08:00
creatixchu bf85410fbb Merge remote-tracking branch 'origin/master' into worktree/steer-followup-images 2026-08-27 16:35:03 +08:00
creatixchu ba810b3539 fix: harden subagent image follow-up admission 2026-08-27 16:31:04 +08:00
creatixchu 2951512e18 docs: refresh module graph for subagent attachments 2026-08-27 15:59:03 +08:00
creatixchu 381ea9fc5d Merge branch 'master' into worktree/steer-followup-images
# Conflicts:
#	packages/api/session-controller/src/client/contract/session.ts
2026-08-27 15:53:14 +08:00
creatixchu 7c38fd8102 fix: deliver images reliably with steer and follow-up messages
A steer or follow-up accepted while a turn is closing is now claimed by a
fresh turn at the driver's clean exit instead of stranding in the inbox;
cancellation and pre-step rejection still park accepted work. Continuable
subagent follow-ups accept image parts: the wire is upload-shaped, the Host
admits and persists each batch before inbox acceptance, and delivery is
refused when the child model declines image input. The queue dock renders
durable image thumbnails instead of an [image] text marker.

Fixes #3186
2026-08-27 15:30:35 +08:00
pku-xht c302bedc3a test(subprocess): defer fake runner disconnect 2026-08-27 02:37:00 +08:00
pku-xht ef0815db7f chore(subprocess): document disconnect recheck 2026-08-27 01:33:06 +08:00
pku-xht 1250b41054 docs(subprocess): clarify Windows runner disconnect 2026-08-27 00:57:21 +08:00
pku-xht 81257defd2 fix(subprocess): preserve clean Windows runner close 2026-08-27 00:41:59 +08:00
pku-xht 07408ff0f1 fix(subprocess): preserve failed teardown state 2026-08-26 23:43:15 +08:00
pku-xht 3caa9e4f5a fix(subprocess): retain failed cleanup ownership 2026-08-26 22:16:20 +08:00
pku-xht aa4d80c0a9 Merge origin/master into codex/subprocess-native-containment 2026-08-26 20:05:15 +08:00
pku-xht 166004a6a8 fix(subprocess): preserve Windows startup errors 2026-08-26 20:01:10 +08:00
pku-xht 6a34a0dd4b fix(subprocess): isolate Linux native target group 2026-08-26 19:00:40 +08:00
pku-xht 215c8c8132 fix(subagent): wait for real startup evidence 2026-08-26 18:51:14 +08:00
pku-xht 20f04373c8 Merge commit 'bd88d2ee9f08b3c3aba8c06df527a91d8b76b51d' into codex/subprocess-native-containment
# Conflicts:
#	packages/e2b/subprocess-e2b/README.i18n.yaml
#	packages/e2b/subprocess-e2b/README.md
#	packages/e2b/subprocess-e2b/README.zh.md
#	packages/subprocess/README.i18n.yaml
#	packages/subprocess/README.md
#	packages/subprocess/README.zh.md
#	packages/subprocess/subprocess-local/README.i18n.yaml
#	packages/subprocess/subprocess-local/README.md
#	packages/subprocess/subprocess-local/README.zh.md
#	packages/subprocess/subprocess/README.i18n.yaml
#	packages/subprocess/subprocess/README.md
#	packages/subprocess/subprocess/README.zh.md
#	packages/subprocess/win32-process/README.i18n.yaml
#	packages/subprocess/win32-process/README.md
#	packages/subprocess/win32-process/README.zh.md
2026-08-26 15:25:12 +08:00
pku-xht cf6f25d283 fix(subprocess): keep native runner private 2026-08-26 14:10:08 +08:00
pku-xht 678cfdfdb4 Merge commit '0c177e17a23692d018a79bae59ac9a2db6eba59c' into codex/subprocess-native-containment
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md
#	.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/input.json
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
#	packages/bundle/acp-app/package.json
#	packages/examples/jsonrpc-demo/src/packaged-bin.ts
#	packages/subagent/subagent-acp/src/run.ts
#	packages/subagent/subagent-acp/tests/subagent-acp.spec.ts
#	packages/subprocess/subprocess-local/README.i18n.yaml
#	packages/subprocess/subprocess-local/README.md
#	packages/subprocess/subprocess-local/README.zh.md
#	pnpm-lock.yaml
#	scripts/smoke-python-runtime.py
2026-08-25 23:22:25 +08:00
pku-xht ff413cfe5e fix(subprocess): align async pid evidence 2026-08-25 22:24:20 +08:00
pku-xht 26969588b7 fix(subprocess): address native containment review findings 2026-08-25 21:51:22 +08:00
pku-xht 8e9bac4a27 fix(subprocess): align native containment contract 2026-08-25 20:06:00 +08:00
pku-xht ae77bc0b2f fix(subprocess): defer native wait allocation 2026-08-22 09:18:31 +08:00
pku-xht df00bb9c44 test(subprocess): make stream EOF checks causal 2026-08-22 08:58:18 +08:00
pku-xht da042b8e10 test(subprocess): cover native settlement edges 2026-08-22 08:46:33 +08:00
pku-xht eb17028720 fix(subprocess): preserve post-start runner failures 2026-08-22 08:23:34 +08:00
pku-xht b3fcca9598 refactor(subprocess): remove synthetic abort race 2026-08-22 08:00:30 +08:00
pku-xht 63df2b31a7 docs(subprocess): document runner lifecycle helpers 2026-08-22 07:58:00 +08:00
pku-xht 71e27e4667 fix(subprocess): close native lifecycle gaps 2026-08-22 07:35:51 +08:00
pku-xht bde6a9a041 test(subprocess): keep validation assertions explicit 2026-08-22 06:51:45 +08:00
pku-xht 7228c821b7 refactor(subprocess): centralize stream settlement 2026-08-22 06:40:12 +08:00
pku-xht 923f919b49 test(subprocess): remove Windows cwd recursively 2026-08-22 06:22:13 +08:00
pku-xht 610ed618e9 fix(subprocess): release Windows target cwd 2026-08-22 06:04:54 +08:00
pku-xht 6e1b8eda77 fix(subprocess): preserve runner result boundary 2026-08-22 05:30:09 +08:00
pku-xht 0c80f9e7a1 test(subprocess): align native evidence with plan 2026-08-22 05:05:31 +08:00
pku-xht b6dc88be51 fix(subprocess): preserve forced Linux outcomes 2026-08-22 04:59:36 +08:00
pku-xht df8e3d7c37 fix(subprocess): settle pre-start Windows runner failures 2026-08-22 04:58:31 +08:00
pku-xht 3acb847442 fix(subprocess): preserve clean spawn failure settlement 2026-08-21 23:32:27 +08:00
pku-xht fa8b83816e fix(subprocess): defer native handshake allocation 2026-08-21 23:03:59 +08:00
pku-xht 4997fb7706 Merge master into native containment 2026-08-21 23:00:57 +08:00
pku-xht e2de9667d3 Merge master into native containment 2026-08-21 22:50:27 +08:00
pku-xht f72ce2299a fix(subprocess): keep native Job ownership in runner 2026-08-21 22:49:56 +08:00
pku-xht a17c5822b5 Merge master into native containment
# Conflicts:
#	packages/subprocess/win32-process/package.json
#	scripts/check-workspace-constraints.ts
2026-08-21 22:10:22 +08:00
pku-xht 153f1579e1 refactor(subprocess): restore native containment baseline 2026-08-21 22:08:49 +08:00
pku-xht ee1a933e82 Merge remote-tracking branch 'origin/codex/subprocess-native-containment' into codex/subprocess-native-containment 2026-08-21 13:06:42 +08:00
pku-xht ac69b1e0c4 fix(subprocess): decouple Windows target stdio 2026-08-21 12:56:34 +08:00
Chinesezjc 32f369c3a0 test(subprocess): widen Windows stdout-end race budget to 5s
The native Windows containment tests expect the stdout stream to end
shortly after the direct target exits, but 1s was too tight under the
Windows CI runner's cold-start and process-teardown jitter. Use a 5s
bounded race so the assertion still proves EOF eventually arrives
without flaking on slow runner startup.
2026-08-21 11:57:52 +08:00
pku-xht 60999be602 test(shell): remove stale lint suppression 2026-08-21 11:19:37 +08:00
pku-xht 5b215932f8 fix(subprocess): hand off Windows process observation 2026-08-21 11:18:43 +08:00
pku-xht b03e52fab0 refactor(subprocess): simplify Windows runner settlement 2026-08-21 10:20:24 +08:00
pku-xht ea7de60840 fix(subprocess): keep Windows Job ownership in parent 2026-08-21 09:51:21 +08:00
pku-xht e70405847c fix(subprocess): complete runner resource release 2026-08-21 08:37:50 +08:00
pku-xht f913c813d2 fix(subprocess): harden managed-range cleanup 2026-08-21 08:21:33 +08:00
pku-xht 43b093a502 fix(subprocess): close runner pipe handles 2026-08-21 08:08:10 +08:00
pku-xht 889cbd45f1 fix(subprocess): order runner stdio shutdown 2026-08-21 07:49:15 +08:00
pku-xht 975afc9e47 fix(subprocess): release Windows runner stdio 2026-08-21 07:36:08 +08:00
pku-xht 36db13dfb3 fix(subprocess): require verified range settlement 2026-08-21 07:20:43 +08:00
pku-xht 3f2f381209 docs(subprocess): align provider-owned termination semantics 2026-08-21 06:20:25 +08:00
pku-xht c7d228c737 test(subprocess): make Windows EOF proof deterministic 2026-08-21 05:58:53 +08:00
pku-xht bf5a8e42a3 fix(subprocess): keep shared handle semantics provider-neutral 2026-08-21 05:42:12 +08:00
pku-xht e6bc1f2e1d fix(subprocess): close managed launch gaps 2026-08-21 05:08:36 +08:00
pku-xht 7fec86d6a1 refactor(subprocess): derive runner execution plane 2026-08-21 03:25:17 +08:00
pku-xht 2c0ebebdf8 test(subprocess): type close interleaving fixture 2026-08-21 03:00:48 +08:00
pku-xht 63b038e469 fix(subprocess): preserve close snapshot state 2026-08-21 02:59:09 +08:00
pku-xht 81374783d3 fix(subprocess): close native runner lifecycle gaps 2026-08-21 02:57:53 +08:00
pku-xht 97e0c9607d test(subprocess): cover native probe fallback 2026-08-21 01:55:20 +08:00
pku-xht 273c2847e5 fix(subprocess): support packaged native runner 2026-08-21 01:17:12 +08:00
pku-xht 1fc04feb77 fix(subprocess): close native platform CI gaps 2026-08-20 23:59:55 +08:00
pku-xht 21820b6816 test(subprocess): cover async scope failures 2026-08-20 23:47:19 +08:00
pku-xht 60c729250e test(subprocess): preserve Windows job descendant 2026-08-20 23:34:13 +08:00
pku-xht 436f9e9686 fix(subprocess): preserve native failure semantics 2026-08-20 23:24:22 +08:00
pku-xht 6df3ef4f97 refactor(subprocess): pass runner pid to liveness probe 2026-08-20 22:46:49 +08:00
pku-xht f6a56d4882 test(subprocess): align native platform fixtures 2026-08-20 22:41:03 +08:00
pku-xht b25e790e36 test(subprocess): cover runner liveness polling 2026-08-20 22:37:52 +08:00
pku-xht 0f3db79902 docs(subprocess): record native systemd evidence 2026-08-20 22:32:06 +08:00
pku-xht b9c0028f95 fix(subprocess): launch systemd scopes without pipe mode 2026-08-20 22:28:30 +08:00
pku-xht eb60d74155 fix(subprocess): harden native range settlement 2026-08-20 22:16:24 +08:00
pku-xht 8b81d77d54 refactor(subprocess): use mode as fallback warning latch 2026-08-20 20:58:33 +08:00
pku-xht a160bd55fc Merge PR1 into native containment 2026-08-20 20:38:46 +08:00
pku-xht ad44ba547a test(subagent-acp): explain fallback warning coexistence 2026-08-20 20:35:08 +08:00
pku-xht 2ee78dd576 Merge commit '10ba2cf9aed8aaf7198bf4a12e1773e1c5dfa627' into codex/subprocess-native-containment 2026-08-20 20:14:03 +08:00
pku-xht 6532fff458 test(subagent-acp): allow provider fallback warning 2026-08-20 20:02:57 +08:00
pku-xht a7b64e24ee Merge PR1 into native containment 2026-08-20 20:01:20 +08:00
pku-xht cd1a8552f7 Merge codex/subprocess-win32-process-primitives into codex/subprocess-native-containment 2026-08-20 19:29:33 +08:00
pku-xht e9c095ab4b Merge codex/subprocess-win32-process-primitives into codex/subprocess-native-containment 2026-08-20 19:18:42 +08:00
pku-xht 1ada79af81 test(subprocess): cover settled scope waits 2026-08-20 18:58:36 +08:00
pku-xht 700812811e Merge codex/subprocess-win32-process-primitives into codex/subprocess-native-containment 2026-08-20 18:45:37 +08:00
pku-xht 7185a62d58 fix(subprocess): harden native runner lifecycle 2026-08-20 18:41:30 +08:00
pku-xht d778e83b2b fix(subprocess): route fallback warning through logger 2026-08-20 17:38:01 +08:00
pku-xht 4c164cd163 fix(subprocess): close native containment CI gaps 2026-08-20 17:29:22 +08:00
pku-xht 884cd6be70 Merge codex/subprocess-win32-process-primitives into codex/subprocess-native-containment
# Conflicts:
#	packages/subprocess/win32-process/package.json
2026-08-20 16:27:21 +08:00
pku-xht 894f6aeb8a fix(subprocess): contain escaped descendants with native owners 2026-08-20 16:26:19 +08:00
7865 changed files with 247250 additions and 87879 deletions

No files matched your search

+2 -2
View File
@@ -2,5 +2,5 @@
# side 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/README.md
README.md: ae8e4724d610c97d74910d7dec5c95af69e93281
README.zh.md: 8cecc7068d9efc5e2ebb78d2301d03633f70f137
README.md: 8bf1adf875b54eb4580b4d189dfeed07c9f671c0
README.zh.md: ff9bdb358d584d4f4ad0aea295c31d8d8fff9376
+1 -1
View File
@@ -20,7 +20,7 @@ The active lifecycle tree is the working inventory: browse its lifecycle/class f
## Classification
Each Agent Note belongs to one path-encoded class from the closed set in `scripts/agent-note-tree.ts`; the classification gate rejects other folders. Adding a class requires updating the canonical set and this section. See the [classification Agent Note](implemented/process/2026-06-20-agent-note-classification.md).
Each Agent Note belongs to one path-encoded class from the closed set in `scripts/agent-note-tree.ts`; the classification gate rejects other folders. Adding a class requires updating the canonical set and this section.
| Class | What it covers |
|---|---|
+1 -1
View File
@@ -22,7 +22,7 @@
## 分类
每份 Agent Note 属于 `scripts/agent-note-tree.ts` 中封闭集合里的一个路径编码类别;分类门禁拒绝其他文件夹。新增类别需要同时更新规范集合与本节。见[分类 Agent Note](implemented/process/2026-06-20-agent-note-classification.zh.md)。
每份 Agent Note 属于 `scripts/agent-note-tree.ts` 中封闭集合里的一个路径编码类别;分类门禁拒绝其他文件夹。新增类别需要同时更新规范集合与本节。
| 类别 | 覆盖范围 |
|---|---|
@@ -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/architecture/2026-06-11-runtime-arg-validation.md
2026-06-11-runtime-arg-validation.md: 22283c76719a26f733a8125bf263810d53a92c3c
2026-06-11-runtime-arg-validation.zh.md: f748b7e01b233edb8b3303898cc339dfacd16967
@@ -1,6 +1,7 @@
# Agent Note: Runtime arg validation at the model boundary
Status: implemented
Archived: 2026-09-04
English | [中文](2026-06-11-runtime-arg-validation.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 模型边界处的运行时参数校验
Status: implemented
Archived: 2026-09-04
[English](2026-06-11-runtime-arg-validation.md) | 中文
@@ -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/architecture/2026-06-11-structured-error-taxonomy.md
2026-06-11-structured-error-taxonomy.md: a5c1c6e6120eefd3bc96090cfa4536fb83afa796
2026-06-11-structured-error-taxonomy.zh.md: 54a937c5595aa5645e4cc0f66a6d1a2efc232588
@@ -1,6 +1,7 @@
# Agent Note: Structured error taxonomy
Status: implemented
Archived: 2026-09-04
English | [中文](2026-06-11-structured-error-taxonomy.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 结构化错误分类体系
Status: implemented
Archived: 2026-09-04
[English](2026-06-11-structured-error-taxonomy.md) | 中文
@@ -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/architecture/2026-06-17-filesystem-capability-seam.md
2026-06-17-filesystem-capability-seam.md: a0c898c1d127a7828037b3a59d04ff73c82e31ba
2026-06-17-filesystem-capability-seam.zh.md: 0442333a0a7cbc4fcae0f4b02db1700ce6aafc9e
@@ -1,6 +1,7 @@
# Agent Note: Filesystem capability seam — ctx.fs, local backend, and model-facing filesystem tools
Status: implemented
Archived: 2026-09-04
English | [中文](2026-06-17-filesystem-capability-seam.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 文件系统能力 seam——ctx.fs、本地后端与面向模型的文件系统工具
Status: implemented
Archived: 2026-09-04
[English](2026-06-17-filesystem-capability-seam.md) | 中文
@@ -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/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.md
2026-06-18-agent-lifecycle-and-ownership-contracts.md: 012346d9e5b8bf4fd661423b3c398e93e513659d
2026-06-18-agent-lifecycle-and-ownership-contracts.zh.md: 4f8aaac32dfa3d84a449f12441c23371f1a3a27d
@@ -1,6 +1,7 @@
# Agent Note: Agent lifecycle and ownership contracts
Status: implemented
Archived: 2026-09-04
English | [中文](2026-06-18-agent-lifecycle-and-ownership-contracts.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: Agent 生命周期与所有权约定
Status: implemented
Archived: 2026-09-04
[English](2026-06-18-agent-lifecycle-and-ownership-contracts.md) | 中文
@@ -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/implemented/architecture/2026-06-18-shared-persistence-write-coordinator.md
2026-06-18-shared-persistence-write-coordinator.md: 5c324f2c0c2b951f664bcf92725a36c4975fd3a1
2026-06-18-shared-persistence-write-coordinator.zh.md: 51ef76189cb9276214bf05bbd1dbd8e3755daa35
@@ -0,0 +1,53 @@
# Agent Note: Shared persistence write coordinator
Status: implemented
Archived: 2026-08-31
English | [中文](2026-06-18-shared-persistence-write-coordinator.zh.md)
## Problem
The JSONL provider needs correctness-heavy write orchestration around its storage primitives: per-Session state, `session/created` adoption, prefix reads, write-behind control, per-id operation serialization, HMR seeding, and dispose drains. Keeping that lifecycle in the Service Definition prevents an out-of-tree provider from copying it. The removed first-party database provider demonstrated the duplication cost; the [JSONL-only persistence decision](../simplification/2026-08-30-jsonl-only-session-persistence.md) owns its removal.
## Decision
`dsh-session-persistence` exports a backend-agnostic `PersistenceCoordinator`. The JSONL provider composes one (`new PersistenceCoordinator(ctx, this)`), implements the small `PersistenceBackend` hook interface, and delegates its stateful public methods (`create`/`append`/`prepare`/`load`/`inspect`/`readFrom`) to it. Backend-owned metadata and revision listing bypass the coordinator.
Composition, not inheritance. The coordinator is a concrete class the backend holds, not a base class the backend extends. The risk that a coordinator makes unusual backends fight an inheritance hierarchy is avoided: a backend exposes only the hooks and cannot reach the coordinator's private orchestration state. A third-party backend MAY still implement the abstract service directly without the coordinator, including immutable logical inspection and the default preparation fallback through `load`.
The coordinator holds one lifecycle entry for each exact live `Session`: initialization plus a package-private write controller that owns pending events, a fixed batching deadline, the active write, failure retention, and the shared flush barrier. Each `session/event` enters that bounded write path, and `session/flush` bypasses the wait to observe quiescence. The [flush-controller simplification](../simplification/2026-07-23-collapse-persistence-flush-state.md) owns controller consolidation; the [bounded batching decision](2026-08-08-bounded-session-persistence-write-batching.md) owns scheduling cadence.
Creation borrows the exact `Session.events` snapshot as its persistence seed. `Session` has already detached, validated, and deeply frozen every event, and the snapshot array remains stable when later appends replace the cached view. The coordinator and its backend hooks only read this typed in-process value, so cloning the complete log again would duplicate the ownership work described by the [agent-scope runtime decision](2026-07-12-agent-scope-runtime-design.md#session-append-materialize-validate-commit-notify). Public persistence `append()` still snapshots caller-owned input at its API boundary.
Prepared-session suffixes and events admitted to the write-behind queue retain their existing copies. Those paths establish asynchronous queue ownership one suffix or event at a time and have no measured whole-log clone cost; removing their copies remains a separate ownership audit rather than part of creation-seed borrowing.
The coordinator retires a session from `session/disposed`: it waits for the controller's initialization and current flush, serializes a final drain, and removes the controller and owned per-id state only after success. A failure leaves the controller discoverable for backend teardown to retry. Settled per-id chain tails remove themselves only when they are still current, so a completion cannot erase a newer operation for the same id. Backend teardown unregisters write-path listeners, flushes every remaining controller, awaits per-id operations, and then closes the backend.
### The hook interface (`PersistenceBackend<TornMarker>`)
Five required members plus optional empty-materialization and lifecycle hooks form the only boundary between the coordinator and storage:
- `name` — backend label for the dispose-failure `AggregateError`.
- `loadStored(id)` — read one stored prefix by id across every storage scope. Preparation, logical load/inspection, physical suffix reads, live adoption, and the create-collision probe share this lookup. The coordinator asserts the returned id and rejects a stored/live cwd mismatch before repair or state publication.
- `appendBatch(meta, events, isMaterialized)` — durably append a contiguous batch, lazily materializing the session ATOMICALLY when not yet materialized. Ordinary creation therefore cannot leave an abandoned materialized-but-empty session.
- `materializeHeader?(meta)` — explicitly persist a header-only session for `SessionPersistence.ensureMaterialized(session)`. This is reserved for a lifecycle frontend that treats an empty session itself as a resumable durable resource; [standard ACP automation controls](../feature/2026-08-22-standard-acp-automation-controls.md) are the first consumer. Backends that support that lifecycle implement the hook; lazy creation remains the default.
- `commitRepair(meta, tornMarker, closers)` — make a crash repair durable: truncate the torn tail (iff `tornMarker !== undefined`) and append `closers`. **NOT required to be atomic** — JSONL legitimately truncates then appends in two fsync'd steps. Used by `prepare`/`load` (truncate + synthetic closers) and live adoption (truncate only, `closers = []`).
- `list()` — list all stored metadata.
- `close?()` — optional lifecycle teardown for a provider with owned resources; JSONL omits it. The dispose effect awaits it after the quiescence drain so a close failure never masks a drain error.
### The opaque torn marker
The single design choice that keeps the seam clean: the crash-repair "where is the torn tail" token is opaque to the coordinator. The coordinator computes the synthetic closers (it owns `interruptedTurnClosers` from `dsh-session`), but it only tests `tornMarker !== undefined` and passes the value straight back to `commitRepair`; it never inspects it. JSONL carries the byte offset to truncate to plus any complete events decoded from an incomplete final frame, while another provider may choose its own marker type. The coordinator therefore knows neither byte lengths nor frame recovery state.
## Testing
The shared `runPersistenceContract` proves that JSONL `inspect` balances an interrupted logical view without changing storage or revisions before `prepare` or `load` commits recovery. `runCoordinatorContract` (`tests/coordinator-contract.ts`) covers adoption, HMR, collision, Session and provider disposal drains, and crash-tail repair through an in-memory reference and JSONL. `persistence.spec.ts`, `preparations.spec.ts`, and `write-behind.spec.ts` cover preparation reuse and reservation, bounded prepared-state eviction, fixed-window follow-up batches, live-controller cleanup, same-id chain-tail races, failed-batch retry, and close ordering. JSONL specs retain storage mechanics and the through-coordinator torn-tail case that exercises the opaque-marker branch.
## Alternatives considered
- **A base class the backends extend** — rejected for composition: a backend exposes only the hooks, cannot reach the coordinator's private orchestration state, and a third-party backend may still implement the abstract service directly without the coordinator at all.
- **A wider hook API** — each candidate hook folds away: there is no scope-specific live lookup because `loadStored` plus the coordinator's cwd check preserves the collision boundary, no storage-locator generic because validated JSONL metadata reproduces its path, no separate `materialize` hook because the first batch must commit atomically with materialization, no separate create-collision probe because it is `loadStored(id) !== undefined`, and no coordinator pass-through for `list()` because listing needs none of the orchestration.
## Consequences
The coordinator adds one indirection, an opaque torn marker, detached Session-retirement tasks, and bounded prepared Session state, but centralizes correctness-heavy orchestration for the JSONL provider and future implementations. Session disposal remains an observe-only event, so the Session owner does not await persistence retirement; the coordinator contains failures, preserves pending events in the live controller, and makes provider teardown the quiescence boundary. Its hook surface stays narrow: identity, adoption, collision checks, preparation, and immutable inspection reuse `loadStored`; materialization stays atomic inside `appendBatch`; and listing bypasses the coordinator. Read models use `inspect` rather than `load`, so observing a persisted open turn does not commit interruption closers; the [Session preparation decision](2026-08-05-session-preparation.md) owns reuse, reservation, and publication. A new provider implements storage primitives rather than copy the bounded write lifecycle.
@@ -0,0 +1,53 @@
# Agent Note: 共享持久化写入协调器
Status: implemented
Archived: 2026-08-31
[English](2026-06-18-shared-persistence-write-coordinator.md) | 中文
## 问题
JSONL provider 需要在其存储原语周围执行对正确性要求很高的写入编排:逐 Session 状态、`session/created` 接管、前缀读取、write-behind 控制、按 id 串行执行、HMR 种子注入与 dispose 排空。把该生命周期放在 Service Definition 中,可以避免仓库外 provider 重复实现。已删除的 first-party 数据库 provider 证明了这种重复成本;其删除由 [JSONL-only 持久化决策](../simplification/2026-08-30-jsonl-only-session-persistence.zh.md)负责。
## 决策
`dsh-session-persistence` 导出后端无关的 `PersistenceCoordinator`。JSONL provider 组合一个协调器实例(`new PersistenceCoordinator(ctx, this)`)、实现小型 `PersistenceBackend` 钩子接口,并把有状态公开方法(`create`/`append`/`prepare`/`load`/`inspect`/`readFrom`)委托给协调器。由后端拥有的元数据与修订版本列举会绕过协调器。
组合,而非继承。协调器是后端持有的具体类,不是后端继承的基类。协调器让非常规后端与继承层级作斗争的风险由此规避:后端只暴露钩子,无法触及协调器的私有编排状态。第三方后端仍然可以完全不使用协调器、直接实现抽象服务,包括不可变逻辑检查,以及通过 `load` 实现的默认准备回退。
协调器为每个存活的 `Session` 实例持有一个生命周期条目:初始化,加上一个包私有写入控制器,后者负责待处理事件、固定批处理截止时间、活跃写入、失败保留和共享 flush 屏障。每个 `session/event` 都进入这条有界写入路径,`session/flush` 则绕过等待以观察完全停稳。控制器归并由 [flush 控制器简化](../simplification/2026-07-23-collapse-persistence-flush-state.zh.md)定义;调度节奏由[有界批处理决策](2026-08-08-bounded-session-persistence-write-batching.zh.md)定义。
创建流程将 `Session.events` 的原始快照借作持久化种子。`Session` 已经分离、验证并深度冻结每个事件,后续追加会替换缓存视图,因此该快照数组保持稳定。协调器及其后端钩子只读取这个有类型的进程内值;再次克隆完整日志会重复 [agent scope 运行时决策](2026-07-12-agent-scope-runtime-design.zh.md#session-append-materialize-validate-commit-notify)规定的所有权工作。持久化服务的公开 `append()` 仍在 API 边界为调用方拥有的输入创建快照。
已准备 Session 的后缀,以及进入 write-behind 队列的事件,仍保留现有复制。这些路径会逐个后缀或事件建立异步队列所有权,且没有已测得的完整日志克隆成本;移除这些复制属于单独的所有权审计,不属于创建种子的借用决策。
协调器通过 `session/disposed` 退役会话:它等待控制器完成初始化和当前 flush,串行执行最后一次排空,且仅在成功后才移除控制器与其拥有的每 id 状态。失败时保持控制器可被找到,以供后端 teardown(拆除)重试。每个 id 的已结算链尾仅在其仍是当前链尾时才移除自身,因此旧操作完成后不会抹除同一 id 的新操作。后端 teardown 会注销写入路径监听器、flush 每个剩余的控制器、等待所有按 id 串行化的操作,最后关闭后端。
### 钩子接口(`PersistenceBackend<TornMarker>`)
五个必需成员加可选的空会话实体化与生命周期钩子,构成协调器与存储之间唯一的边界:
- `name`——后端标签,用于 dispose 失败时的 `AggregateError`。
- `loadStored(id)`——按 id 跨所有存储范围读取一个已存储前缀。准备、逻辑加载/检查、物理后缀读取、存活会话接管与创建碰撞探测共用此查找。协调器会断言返回的 id,并在修复或发布状态之前拒绝已存储记录与存活会话的 cwd 不匹配。
- `appendBatch(meta, events, isMaterialized)`——持久追加一个连续批次,在尚未物化时原子地惰性物化会话。因此,普通创建不会留下被放弃的已物化空会话。
- `materializeHeader?(meta)`——为 `SessionPersistence.ensureMaterialized(session)` 显式持久化仅含 header 的会话。它只供把空会话本身视为可恢复持久资源的生命周期前端使用;[标准 ACP 自动化控制](../feature/2026-08-22-standard-acp-automation-controls.zh.md)是第一个 consumer。支持该生命周期的后端实现此钩子;惰性创建仍是默认行为。
- `commitRepair(meta, tornMarker, closers)`——使崩溃修复持久化:截断损坏的尾部(当且仅当 `tornMarker !== undefined`)并追加 `closers`。**不要求原子性**——JSONL 合理地分两步 fsync,先截断再追加。用于 `prepare`/`load`(截断 + 合成收尾事件)和存活会话接管(仅截断,`closers = []`)。
- `list()`——列出所有已存储的元数据。
- `close?()`——供拥有资源的 provider 使用的可选生命周期清理;JSONL 省略该钩子。dispose effect 在排空至完全停稳后 await 它,因此 close 失败不会掩盖排空错误。
### 不透明的 torn marker
保持 seam 整洁的唯一设计选择:崩溃修复中「损坏尾部在哪里」的 token 对协调器是不透明的。协调器计算合成收尾事件(它拥有来自 `dsh-session` 的 `interruptedTurnClosers`),但只测试 `tornMarker !== undefined` 并将值原样传回 `commitRepair`,从不检视其内容。JSONL 携带要截断到的字节偏移,以及从不完整最终帧中解码出的任何完整事件;其他 provider 可以选择自己的 marker 类型。协调器因此既不了解字节长度,也不了解帧恢复状态。
## 测试
共享 `runPersistenceContract` 证明 JSONL 的 `inspect` 会配平被中断的逻辑视图但不改变存储或修订版本,随后由 `prepare` 或 `load` 提交恢复。`runCoordinatorContract`(`tests/coordinator-contract.ts`)通过内存参考实现与 JSONL 覆盖接管、HMR、碰撞、Session 与 provider dispose 排空和崩溃尾部修复。`persistence.spec.ts`、`preparations.spec.ts` 与 `write-behind.spec.ts` 覆盖准备复用与预留、有界准备状态淘汰、固定窗口后续批次、存活控制器清理、同 id 链尾竞态、失败批次重试与关闭顺序。JSONL 规格保留存储机制,以及覆盖不透明 marker 分支的经由协调器崩溃尾部用例。
## 曾考虑的替代方案
- **后端继承的基类**——否决,改用组合:后端只暴露钩子,无法触及协调器的私有编排状态,且第三方后端仍可完全不使用协调器、直接实现抽象服务。
- **更宽的钩子 API**——每个候选钩子都被折叠掉:没有限定存储范围的存活会话查找,因为 `loadStored` 加上协调器的 cwd 检查即可维持碰撞边界;没有存储定位器泛型,因为经验证的 JSONL 元数据可还原其路径;没有单独的 `materialize` 钩子,因为首批事件必须与物化原子提交;没有单独的创建碰撞探测,因为它就是 `loadStored(id) !== undefined`;`list()` 也不经由协调器透传,因为列举不需要任何编排。
## 后果
协调器增加一层间接、一个不透明 torn marker、脱离 Session 生命周期的退役任务,以及有界的已准备 Session 状态,但为 JSONL provider 与未来实现集中管理对正确性要求很高的编排。Session dispose 仍是仅观察事件,因此 Session owner 不等待持久化退役;协调器收容失败、在存活控制器中保留待处理事件,并以 provider teardown 为完全停稳边界。其钩子面保持窄小:标识校验、接管、碰撞检查、准备与不可变检查共用 `loadStored`;物化保持在 `appendBatch` 内原子完成;列举绕过协调器。读模型使用 `inspect` 而非 `load`,因此观察已持久化但仍开放的轮次时不会提交中断收尾事件;复用、预留与发布由 [Session 准备阶段决策](2026-08-05-session-preparation.zh.md)定义。新 provider 只需实现存储原语,而无需复制有界写入生命周期。
@@ -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/architecture/2026-06-20-branded-ids.md
2026-06-20-branded-ids.md: 3078ebc7035c8c5a86c7a743a0452b0ebddf6c7d
2026-06-20-branded-ids.zh.md: 3a7d7c319c9fc14724af306b8c601afa759a18e7
@@ -1,6 +1,7 @@
# Agent Note: Branded IDs everywhere they belong
Status: implemented
Archived: 2026-09-04
English | [中文](2026-06-20-branded-ids.zh.md)
@@ -51,7 +52,7 @@ Kept deliberately narrow per the "not every string needs a brand" policy. Each o
- **`ModelId`** (`GenerateOptions.model`, the `LlmRuntime` adapter-registry key) — a real cross-package lookup key (config → agent → llm → adapter); a reasonable next brand, left out only to keep this decision's blast radius focused.
- **`ToolName`** (the `ToolRuntime` key) — author-defined, human-readable, and rarely confused with another id; the weakest candidate, likely not worth a brand.
- **`ErrorCode`** (`HarnessError.code`) — a closed vocabulary (`ABORTED`, `NO_ADAPTER`, …), not a per-instance id; better served by a string-literal union than a brand, if anything.
- **Numeric ordinals** — turn number, step number, and the event `seq` are `number`, not `string`, so `Branded<string>` does not apply; a parallel `number & { readonly [BRAND]: B }` variant could brand them, but they are positional ordinals rarely passed across boundaries, so the payoff is low.
- **Other numeric ordinals** — the [Session sequence and log-offset decision](2026-08-31-session-sequence-and-log-offset-brands.md) brands event identities and log gaps because they cross persistence and reference seams. Turn and step numbers remain plain numbers: they are payload-local ordinals and are not interchangeable with Session event positions.
- **Validated construction** — `brandString<T>()` performs no runtime check, and every boundary (ACP `sessionId`, provider-issued `call.id`, the empty-string fallback in `dsh-llm-deepseek`) trusts the raw string. A `SessionId.parse()` / `isValid()` companion that throws on malformed input at boundaries is a genuine gap, but it is a runtime-behavior change with its own design (what is "malformed"? what happens on failure?) and belongs in its own decision.
## Verification
@@ -1,6 +1,7 @@
# Agent Note: 在所有应有之处使用 branded ID
Status: implemented
Archived: 2026-09-04
[English](2026-06-20-branded-ids.md) | 中文
@@ -51,7 +52,7 @@ const owner = brandString<OwnerToken>('session-1')
- **`ModelId`**(`GenerateOptions.model`,`LlmRuntime` 适配器注册表的键):一个真正的跨包查找键(config → agent → llm → 适配器);合理的下一个 brand,仅为控制本决策的影响范围而暂不纳入。
- **`ToolName`**(`ToolRuntime` 的键):由作者定义、人类可读,且很少与其他 id 混淆;最弱的候选,可能不值得加 brand。
- **`ErrorCode`**(`HarnessError.code`):一个封闭词汇(`ABORTED`、`NO_ADAPTER`……),不是逐实例的 id;如果要做,string 字面量联合类型比 brand 更合适。
- **数值序号**:轮次号、步骤号和事件 `seq` 是 `number` 而非 `string`,`Branded<string>` 不适用;可以用并行的 `number & { readonly [BRAND]: B }` 变体来 brand 它们,但它们是位置序号、很少跨边界传递,收益较低。
- **其他数值序号**:[Session 序列号与日志偏移决策](2026-08-31-session-sequence-and-log-offset-brands.zh.md)会为事件身份与日志间隙加 brand,因为它们跨越 persistence 与引用 seam。turn 与 step number 保持普通 number:它们是 payload-local ordinal,不会与 Session 事件位置互换。
- **带校验的构造**:`brandString<T>()` 不执行运行时检查,且每个边界(ACP `sessionId`、提供方签发的 `call.id`、`dsh-llm-deepseek` 中的空字符串回退)都信任裸 string。一个在边界处对格式错误的输入抛异常的 `SessionId.parse()` / `isValid()` 配套工具确实是缺口,但它属于运行时行为变更,有自己的设计问题(什么算「格式错误」?失败时会怎样?),应在独立决策中处理。
## 验证
@@ -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/architecture/2026-06-30-bash-stdin-env-trusted-plugin-api.md
2026-06-30-bash-stdin-env-trusted-plugin-api.md: b9883c88d091e6e932da7c65b8b7fe4d107c0fa4
2026-06-30-bash-stdin-env-trusted-plugin-api.zh.md: 884b83de21243e27fa39f7840adfffebc398a9b0
@@ -1,6 +1,7 @@
# Agent Note: stdin + extra env on the bash seam
Status: implemented
Archived: 2026-09-04
English | [中文](2026-06-30-bash-stdin-env-trusted-plugin-api.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 在 bash seam 上支持 stdin 与额外 env
Status: implemented
Archived: 2026-09-04
[English](2026-06-30-bash-stdin-env-trusted-plugin-api.md) | 中文
@@ -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/architecture/2026-07-02-fs-per-session-cwd.md
2026-07-02-fs-per-session-cwd.md: 81dafda9ba71bd2746926e8baa0f4eaf76748429
2026-07-02-fs-per-session-cwd.zh.md: aa05ed41615f29d580595a66d4743d4baf02b1a9
@@ -1,6 +1,7 @@
# Agent Note: Resolve filesystem paths against the caller's session cwd
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-02-fs-per-session-cwd.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 相对文件系统路径按调用方的会话 cwd 解析
Status: implemented
Archived: 2026-09-04
[English](2026-07-02-fs-per-session-cwd.md) | 中文
@@ -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/architecture/2026-07-05-subagent-provider-lifecycle-events.md
2026-07-05-subagent-provider-lifecycle-events.md: a15c3e6faee993902547174fe9ea235d07d9ec2f
2026-07-05-subagent-provider-lifecycle-events.zh.md: 49e55a3b148775ed7e676b5f55058ef1427a86c6
@@ -1,6 +1,7 @@
# Agent Note: Subagent provider-lifecycle events — `subagent/provider-added` / `subagent/provider-removed`
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-05-subagent-provider-lifecycle-events.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: Subagent 提供方生命周期事件——`subagent/provider-added` / `subagent/provider-removed`
Status: implemented
Archived: 2026-09-04
[English](2026-07-05-subagent-provider-lifecycle-events.md) | 中文
@@ -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/architecture/2026-07-06-tool-result-retention-library.md
2026-07-06-tool-result-retention-library.md: 5ac8547036ed0b45ec6e55e6fb213a98b7c3df8f
2026-07-06-tool-result-retention-library.zh.md: b18fdd60f529f9e6df6b8fc7e3c90f9a39e65fc8
@@ -1,6 +1,7 @@
# Agent Note: Tool result retention library
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-06-tool-result-retention-library.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 工具结果保留库
Status: implemented
Archived: 2026-09-04
[English](2026-07-06-tool-result-retention-library.md) | 中文
@@ -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/architecture/2026-07-12-scoped-layers-store.md
2026-07-12-scoped-layers-store.md: d3060696ef54c8d06cd0724179dec49682c721e1
2026-07-12-scoped-layers-store.zh.md: f5482a5a76724128fb445fbd7c21a2f61b8634c1
@@ -1,6 +1,7 @@
# Agent Note: Shared scoped-layer storage
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-12-scoped-layers-store.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 共享作用域分层存储
Status: implemented
Archived: 2026-09-04
[English](2026-07-12-scoped-layers-store.md) | 中文
@@ -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/architecture/2026-07-15-llm-model-catalog-and-acp-selection.md
2026-07-15-llm-model-catalog-and-acp-selection.md: c5f6644d4746a8a962e7ab843493fda3862a8c0a
2026-07-15-llm-model-catalog-and-acp-selection.zh.md: 539f2f9a2f9d3d7b48b3ecabca4b401e32c5702c
@@ -1,6 +1,7 @@
# Agent Note: Advisory LLM catalogs and per-session ACP model selection
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-15-llm-model-catalog-and-acp-selection.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 建议性 LLM 目录与 ACP 会话级模型选择
Status: implemented
Archived: 2026-09-04
[English](2026-07-15-llm-model-catalog-and-acp-selection.md) | 中文
@@ -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/architecture/2026-07-15-lsp-capability-seam.md
2026-07-15-lsp-capability-seam.md: 3cce6eb3c7d8afef53aa675440c7eea1e990721d
2026-07-15-lsp-capability-seam.zh.md: c424a794a6662a655565dde6337c49543c5a8085
@@ -1,6 +1,7 @@
# Agent Note: LSP capability seam and model-facing query tool
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-15-lsp-capability-seam.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: LSP 能力 seam 与面向模型的查询工具
Status: implemented
Archived: 2026-09-04
[English](2026-07-15-lsp-capability-seam.md) | 中文
@@ -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/architecture/2026-07-15-replay-token-meter-service.md
2026-07-15-replay-token-meter-service.md: 1e6832f1bd049a9568b3af3b925211f0665de288
2026-07-15-replay-token-meter-service.zh.md: 6d00d5e1511aa66818689ccec7d4b023c291f9aa
@@ -1,6 +1,7 @@
# Agent Note: Replay token meter service
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-15-replay-token-meter-service.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 回放式 token 计量服务
Status: implemented
Archived: 2026-09-04
[English](2026-07-15-replay-token-meter-service.md) | 中文
@@ -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/architecture/2026-07-17-local-spill-startup-cleanup.md
2026-07-17-local-spill-startup-cleanup.md: c9567cab8b1193b9ea6dbc0ad3fae2bc18af9656
2026-07-17-local-spill-startup-cleanup.zh.md: 97f6d641ab7e09da401c5632804f6e27ad78d850
@@ -1,6 +1,7 @@
# Agent Note: One-shot startup cleanup for local spill files
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-17-local-spill-startup-cleanup.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 本地 spill 文件的一次性启动清理
Status: implemented
Archived: 2026-09-04
[English](2026-07-17-local-spill-startup-cleanup.md) | 中文
@@ -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/architecture/2026-07-19-package-owned-invariant-service.md
2026-07-19-package-owned-invariant-service.md: 6ebdd0edbe04766280fb9aae7067ba861b2ce010
2026-07-19-package-owned-invariant-service.zh.md: dde72faed7249d64b939aaca1bc5d452eeed7bde
@@ -0,0 +1,106 @@
# Agent Note: Package-owned invariant service contract
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-19-package-owned-invariant-service.zh.md)
## Problem
Runtime invariant checks span session traces, agent state, scoped dispatch, and request reconstruction. Putting all checks in one diagnostics package makes that package import product vocabularies from unrelated domains, centralizes tests away from their owners, and requires the central package to change whenever a product package adds or removes a check.
Deployments that opt into diagnostics need more than presence or absence of one plugin. Such a composition carries the known invariant contributions while permitting a global off switch and package-selective diagnostics. Selection must remain stable when a package loads later or reloads under HMR, and disabled contributions must not allow two plugins to claim the same package name silently.
Published ownership must be mechanically complete. Without a repository rule, a package can expose a partial companion, dependency, or publication map and remain broken until a maintainer notices the gap; packages that publish none must keep their reason reviewable in the README.
## Decision
### One registry service, package-owned contributions
`@deepseek-ai/dsh-invariants` is a product-independent Cordis service plugin that registers `ctx.invariants`. It owns configuration, registration uniqueness, child-fiber lifecycle, and package-attributed failures. It imports no session, agent, scope, or agent-loop package and contains none of their checks.
A workspace package publishes a `./invariant` companion plugin only when it owns an independently observable event or mutable-data relationship. The companion registers its exact full npm name. Packages without such a relationship omit the companion and publication wiring and record the reason in their README; generated placeholders, empty installers, and synthetic API-shape assertions are forbidden by the [runtime-contract Agent Note](2026-07-19-package-invariant-runtime-contracts.md) and [omission decision](../simplification/2026-08-28-omit-unneeded-invariant-companions.md). Package root entrypoints do not import or register diagnostics implicitly, so loading a root package does not change runtime checking or require the invariant service.
### Configuration and selection
```ts
interface Config {
enabled?: boolean
package_allowlist?: string[]
package_blocklist?: string[]
}
```
Defaults are `enabled: true`, `package_allowlist: []`, and `package_blocklist: []`. For a full registration name, selection is:
```ts
export function selected(enabled: boolean, package_allowlist: RegExp[], package_blocklist: RegExp[], packageName: string): boolean {
return enabled
&& (
package_allowlist.length === 0
|| package_allowlist.some(pattern => pattern.test(packageName))
)
&& !package_blocklist.some(pattern => pattern.test(packageName))
}
```
Blocklist matches override allowlist matches. Each list entry is a case-sensitive JavaScript regex source compiled by `new RegExp(pattern)`. Matching is unanchored unless callers supply `^` and `$`; slash-delimited syntax and flags are not interpreted. Startup rejects blank, whitespace-padded, invalid, or duplicate sources within either list. A source that matches no loaded package remains valid because registration order, later loading, and HMR must not change config validity.
### Registration and failure ownership
The public registration boundary is `ctx.invariants.register(packageName, installer)`. It reserves one active registration per full npm package name even when filters disable installation, and returns the effect disposer. Disposing the companion or service releases the reservation and all contribution state.
An enabled installer runs in a dedicated child Cordis fiber owned by the service. `InvariantInstaller.inject` declares the child fiber's service API explicitly; the registry carries no product-specific dependency metadata. The service joins a returned installer promise before registration succeeds, so asynchronous startup checks remain transactional. The installer receives a bound `fail(message)` reporter. Calling it throws an `Error` subclass named `InvariantError` with stable code `INVARIANT` and the registering `packageName`; it does not extend a product-package error base.
Registration setup is transactional. If an installer fails after registering listeners, the child fiber is disposed completely and the name reservation is released before the failure escapes. Filtered registrations create no child but retain their reservation until disposal. Reloading a companion therefore begins with one clean installer state; stateful contributions rebuild baselines from their owning services.
The former functional-plugin entry point and one-argument `InvariantError` constructor are not retained as compatibility APIs. The repository is pre-release and all call sites move to the service and package-attributed error together.
### Initial stateful companions and exhaustive ownership
| Companion entry | Registration name | Owned checks |
|---|---|---|
| `@deepseek-ai/dsh-session/invariant` | `@deepseek-ai/dsh-session` | session sequence, turn/step enclosure, and same-step call/result trace |
| `@deepseek-ai/dsh-agent/invariant` | `@deepseek-ai/dsh-agent` | agent-status transitions |
| `@deepseek-ai/dsh-scope/invariant` | `@deepseek-ai/dsh-scope` | scoped-event carrier presence and subject consistency |
| `@deepseek-ai/dsh-agent-loop/invariant` | `@deepseek-ai/dsh-agent-loop` | model-request reconstruction |
These four owners supplied the initial stateful checks. Later owners add companions for real event or mutable-data relationships, while packages without one omit the companion and document why. Every published companion is a separately bundled `./invariant` export with its own declarations and Loader-safe namespace plugin shape.
`verify-package-invariants` discovers every workspace package, accepts clean omission, and rejects partial companion wiring, generated markers, empty installers, installers that omit or ignore the reporter, foreign or unresolved registration names, missing `./invariant` exports or published files, missing invariant peer/development dependencies and project references, and bundle overrides that omit a published companion entry.
### Scoped-event semantic map
The generated scoped-event subject resolver lives in `dsh-scope`, beside the contract and invariant that consume it. `gen-scoped-events` uses the root TypeScript Program to enumerate `this: Scoped<Base>` declarations, infer routing-key types from real `scopeTarget(base, key)` calls, and require one unambiguous payload subject or an explicit unsupported marker. The committed runtime map imports no event-owner package, so semantic completeness does not expand either the service or scope package's runtime closure.
### Example composition and SDK output
The `dsh-sdk-minimal` patch mounts the service and all four stateful companion subpaths as explicit rows. A subpath entry adds its installable root npm package rather than treating the subpath as a package name. The shipped base-backed config trees omit the service and companions under the [shipped-config decision](../simplification/2026-08-03-omit-invariants-from-shipped-config.md).
Workspace constraints recognize the separate invariant bundle, and package exports, project references, build configuration, dependency declarations, and the lockfile describe the same publication metadata. Generated config catalogs, module graphs, and API documentation derive from those sources.
## Testing
Service tests cover defaults, global disablement, allow/block selection, blocklist precedence, anchoring, unanchored matching, case sensitivity, invalid configuration, zero-match patterns, late registration, duplicate ownership, disposal, rollback, and HMR re-registration. Owners with executable checks keep positive and negative behavior beside the companion source.
Composition tests cover standard-spine forwarding and generated SDK entries. Loader tests preserve each companion namespace, while built plain-Node smokes exercise the compiled subpath exports. The scoped-event freshness gate reruns its semantic Program analysis.
Every Vitest configuration loads a test host that mounts an explicitly enabled service before an ordinary Cordis root's first plugin and adds the current test package's companion when one exists. One exhaustive topology mounts all published companions once; focused service and owner tests construct their own invariant topology so they can exercise disablement, filtering, rollback, and reload without duplicate ownership. Gate tests also execute every published companion's `apply` function and verify that it calls `register` with its manifest name, rather than accepting source text alone.
## Alternatives considered
- **Keep all checks in `dsh-invariants`.** Rejected because the registry would continue importing every checked product domain, owner changes would require central edits, and package tests would remain detached from the contracts they protect.
- **Let root package entrypoints register checks implicitly when `ctx.invariants` happens to exist.** Rejected because root behavior would depend on composition order and optional service presence, diagnostics could not be selected independently, and package loading would hide a registration effect outside an explicit companion.
- **Discover every `invariant.ts` file automatically at runtime.** Rejected because filesystem/package discovery is not a runtime ownership contract, makes bundled publication ambiguous, and cannot express explicit Cordis load order or dependency installation. Build-time generation, verification, and the test host may enumerate the source tree because they validate repository completeness rather than composing a shipped deployment.
- **Validate allow/block entries against the currently loaded package set.** Rejected because a zero-match pattern can intentionally target a later or HMR-loaded contribution; current load order must not determine config validity.
## Consequences
- Product packages own and test their relational assertions while the service stays product-independent.
- Only owners with a meaningful runtime relationship pay the publication, dependency, listener, or trace-state cost of a companion; other packages record the omission reason in their README.
- Compositions that mount the diagnostics can disable all checks or select package names without changing their plugin tree.
- Explicit companion entries make diagnostic cost and ownership visible in Cordis config and package exports.
- One selected contribution adds one child fiber and its listener/state cost, while filtered registrations retain only name ownership.
- Regex sources are deployment configuration and remain fixed until the service reloads.
- Ordinary Vitest roots install the owning test package's selected companion when published; one exhaustive topology pays the full child-fiber cost once for repository-wide registration coverage.
- Session storage validation, snapshotting, freezing, cited source-event validation, and surface acceptance remain always on and are not affected by invariant selection.
@@ -0,0 +1,106 @@
# Agent Note: 包拥有的不变式服务约定
Status: implemented
Archived: 2026-09-04
[English](2026-07-19-package-owned-invariant-service.md) | 中文
## 问题
运行时不变式检查跨越会话轨迹、agent(智能体)状态、作用域 dispatch 和请求重建。如果所有检查都放在一个诊断包中,该包就必须导入彼此无关的产品领域词汇,测试也会离开真正的所有者;任何产品包新增或移除检查时,都要修改中央包。
选择启用诊断的部署还需要比“是否加载一个插件”更细的控制。这类组合会携带已知的不变式贡献,同时允许全局关闭或按包选择诊断。包稍后加载或在 HMR(热模块替换)下重载时,选择结果必须保持稳定;被过滤的贡献也不能让两个插件静默占用同一个包名。
已发布的包所有权必须机械完整。若没有仓库规则,包可能暴露不完整的 companion、依赖或发布映射,并一直保持损坏,直到维护者发现;不发布 companion 的包则必须在 README 中保留可评审的原因。
## 决策
### 一个注册表服务,贡献归包所有
`@deepseek-ai/dsh-invariants` 是与产品无关的 Cordis 服务插件,注册 `ctx.invariants`。它只负责配置、注册唯一性、子 fiber 生命周期和带包归属的失败;不导入 session、agent、scope 或 agent-loop 包,也不包含这些包的检查。
只有拥有可独立观察的事件或可变数据关系时,工作区包才发布 `./invariant` 伴随插件;该 companion 会注册自己完整且准确的 npm 包名。没有该关系的包会省略 companion 与发布接线,并在 README 中记录原因;[运行时约定 Agent Note](2026-07-19-package-invariant-runtime-contracts.zh.md) 与[省略决策](../simplification/2026-08-28-omit-unneeded-invariant-companions.zh.md)禁止生成占位符、空 installer 和合成 API 形状断言。包的根入口不会隐式导入或注册诊断,因此加载根包不会改变运行时检查,也不要求不变式服务存在。
### 配置与选择
```ts
interface Config {
enabled?: boolean
package_allowlist?: string[]
package_blocklist?: string[]
}
```
默认值为 `enabled: true`、`package_allowlist: []` 和 `package_blocklist: []`。对完整注册名的选择规则为:
```ts
export function selected(enabled: boolean, package_allowlist: RegExp[], package_blocklist: RegExp[], packageName: string): boolean {
return enabled
&& (
package_allowlist.length === 0
|| package_allowlist.some(pattern => pattern.test(packageName))
)
&& !package_blocklist.some(pattern => pattern.test(packageName))
}
```
blocklist 匹配优先于 allowlist 匹配。每个条目都是区分大小写的 JavaScript 正则表达式源,通过 `new RegExp(pattern)` 编译。除非调用方提供 `^` 与 `$`,否则匹配不锚定;系统不会解析斜杠包围语法或 flags。服务启动会拒绝空白、首尾带空白、无效或同一列表内重复的源。没有匹配当前已加载包的有效源仍然合法,因为注册顺序、稍后加载和 HMR 不应改变配置有效性。
### 注册与失败归属
公开注册边界是 `ctx.invariants.register(packageName, installer)`。即使过滤器禁止安装,它也会为每个完整 npm 包名保留唯一的活跃注册,并返回 effect disposer。卸载伴随插件或服务都会释放注册名及全部贡献状态。
启用的 installer 在服务拥有的独立 Cordis 子 fiber 中运行。`InvariantInstaller.inject` 显式声明该子 fiber 的服务 API;注册表不携带产品专用依赖元数据。服务会在注册成功前等待 installer 返回的 promise,因此异步启动检查仍具有事务性。installer 接收绑定后的 `fail(message)` 报告器。调用它会抛出名为 `InvariantError` 的 `Error` 子类,保留稳定代码 `INVARIANT` 并记录注册方 `packageName`;该错误不继承产品包中的错误基类。
注册启动是事务性的。如果 installer 在注册监听器后失败,子 fiber 会完整释放,并在失败向外传播前解除包名占用。被过滤的注册不创建子 fiber,但会保留占用直到 dispose(资源释放)。伴随插件重载时总会从干净的 installer 状态开始;有状态贡献从其所属服务重建基线。
原有函数式插件入口与单参数 `InvariantError` 构造函数不作为兼容 API 保留。仓库处于预发布阶段,所有调用方会一起迁移到服务和带包归属的错误。
### 首批有状态伴随插件与完整所有权
| 伴随入口 | 注册名 | 所属检查 |
|---|---|---|
| `@deepseek-ai/dsh-session/invariant` | `@deepseek-ai/dsh-session` | 会话序列、轮次/步骤包围关系和同一步骤的调用/结果轨迹 |
| `@deepseek-ai/dsh-agent/invariant` | `@deepseek-ai/dsh-agent` | agent 状态转换 |
| `@deepseek-ai/dsh-scope/invariant` | `@deepseek-ai/dsh-scope` | 作用域事件载体的存在性与主体一致性 |
| `@deepseek-ai/dsh-agent-loop/invariant` | `@deepseek-ai/dsh-agent-loop` | 模型请求重建 |
这四个所有者提供了首批有状态检查。后续所有者会为真实事件或可变数据关系增加 companion,没有该关系的包则省略 companion 并记录原因。每个已发布伴随入口都是单独打包的 `./invariant` export,具有独立声明和对 Loader 安全的命名空间插件形态。
`verify-package-invariants` 会发现每个工作区包,接受完整省略,并拒绝不完整的 companion 接线、生成标记、空 installer、缺少或不使用失败报告器的 installer、外部或无法解析的注册名、缺失的 `./invariant` export 或发布文件、缺失的不变式对等依赖(peer dependency)、开发依赖及项目引用,以及遗漏已发布伴随入口的自定义构建配置。
### 作用域事件语义映射
生成的作用域事件主体解析表位于 `dsh-scope`,与消费它的约定和不变式相邻。`gen-scoped-events` 使用根 TypeScript Program 枚举 `this: Scoped<Base>` 声明,从真实 `scopeTarget(base, key)` 调用推断路由键类型,并要求唯一、无歧义的 payload 主体或显式 unsupported 标记。提交的运行时映射不导入事件所有者包,因此语义完整性不会扩大服务包或 scope 包的运行时依赖闭包。
### 示例组合与 SDK 输出
`dsh-sdk-minimal` patch 将该服务与四个有状态配套子路径作为显式配置行挂载。子路径配置行会添加可安装的根 npm 包,而不会把子路径误当成包名。根据[交付配置决策](../simplification/2026-08-03-omit-invariants-from-shipped-config.zh.md),交付的、基于 base 的配置树会省略该服务及其配套插件。
Workspace 约束识别独立的不变式 bundle;包 exports、项目引用、构建配置、依赖声明和 lockfile 描述同一份发布元数据。生成的配置目录、模块图和 API 文档都从这些源派生。
## 测试
服务测试覆盖默认值、全局关闭、allow/block 选择、blocklist 优先级、锚定与非锚定匹配、大小写敏感、无效配置、零匹配模式、延迟注册、重复所有权、dispose、回滚和 HMR 重新注册。具备可执行检查的所有者会把正向与负向行为保留在 companion 源码旁边。
组合测试覆盖标准主干转发和生成的 SDK 条目。Loader 测试固定每个伴随命名空间,构建后的纯 Node 冒烟测试覆盖编译子路径 export。作用域事件新鲜度门禁会重新执行语义 Program 分析。
每个 Vitest 配置都会加载测试宿主;在普通 Cordis 根上下文启动第一个插件之前,宿主会挂载显式启用的服务,并在当前测试包存在伴随插件时添加它。一个完整拓扑会一次挂载所有已发布伴随插件;服务与所有者的聚焦测试自行构建不变式拓扑,从而在不发生重复所有权冲突的前提下覆盖关闭、过滤、回滚与重载。门禁测试还会执行每个已发布伴随插件的 `apply` 函数,并验证它调用 `register` 时使用 manifest(元数据清单)中的包名,而不是只检查源码文本。
## 考虑过的替代方案
- **把所有检查保留在 `dsh-invariants`。** 不予采纳,因为注册表仍要导入所有被检查的产品领域,所有者变更仍需中央编辑,测试也继续远离被保护的约定。
- **当 `ctx.invariants` 恰好存在时,让根包入口隐式注册检查。** 不予采纳,因为根入口行为会依赖组合顺序与可选服务是否存在,诊断无法独立选择,而且包加载会隐藏一个不在显式伴随插件中的注册 effect。
- **在运行时自动发现所有 `invariant.ts` 文件。** 不予采纳,因为文件系统或包发现不是运行时所有权约定,会让 bundle 发布含义不清,也无法表达显式 Cordis 加载顺序或依赖安装。构建期生成与校验以及测试宿主可以枚举源码树,因为它们验证的是仓库完整性,而不是组合已发布的部署。
- **根据当前已加载包集合验证 allow/block 条目。** 不予采纳,因为零匹配模式可能有意指向稍后加载或 HMR 加载的贡献;当前加载顺序不能决定配置有效性。
## 后果
- 产品包拥有并测试自己的关系断言,服务保持与产品无关。
- 只有具备有意义运行时关系的所有者才承担 companion 的发布、依赖、listener 或 trace 状态成本;其他包在 README 中记录省略原因。
- 挂载诊断的组合无需改变插件树即可关闭全部检查或按包名选择。
- 显式伴随条目让诊断成本和所有权在 Cordis 配置与包 export 中可见。
- 每个选中贡献增加一个子 fiber 及其 listener/状态成本,被过滤注册则只保留包名占用。
- 正则表达式源属于部署配置,在服务重载前保持固定。
- 当前测试包发布伴随插件时,普通 Vitest 根上下文会安装其中被选中的伴随插件;一个完整拓扑只支付一次全部子 fiber 成本,用于覆盖整个仓库的注册。
- 会话存储验证、快照、冻结、引用的源事件验证与 surface 接受规则始终启用,不受不变式选择影响。
@@ -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/architecture/2026-07-20-todo-event-ownership.md
2026-07-20-todo-event-ownership.md: 3dfcd604393d05265eb895fa50647338830bd38f
2026-07-20-todo-event-ownership.zh.md: 8dabf8f0cde4ad8af325b00eb1be9d7b7011233f
@@ -1,6 +1,7 @@
# Agent Note: todo event types belong to their producer
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-20-todo-event-ownership.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: todo 事件类型归其生产方所有
Status: implemented
Archived: 2026-09-04
[English](2026-07-20-todo-event-ownership.md) | 中文
@@ -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/architecture/2026-07-22-unified-send-and-coalesced-user-messages.md
2026-07-22-unified-send-and-coalesced-user-messages.md: d2e39f4efd122d9e0dbb45a082779afa2ff42941
2026-07-22-unified-send-and-coalesced-user-messages.zh.md: 37c43fcb7bfa81b177e8ed00876e913e3ddf6ad6
@@ -1,6 +1,7 @@
# Agent Note: Unify agent delivery on send(target × wakeup) and coalesce injected context into user/message
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-22-unified-send-and-coalesced-user-messages.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 将 agent 投递统一到 send(target × wakeup) 并把注入的上下文合并进 user/message
Status: implemented
Archived: 2026-09-04
[English](2026-07-22-unified-send-and-coalesced-user-messages.md) | 中文
@@ -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/architecture/2026-07-23-toolview-dissolution.md
2026-07-23-toolview-dissolution.md: d84255f697886556a46c0511aa89f2c4bfd886d8
2026-07-23-toolview-dissolution.zh.md: 9ae339361193a9b97f7bba44904af0c01e7f3fa0
@@ -1,6 +1,7 @@
# Agent Note: Toolview dissolution — tool rows are per-view keyed slots
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-23-toolview-dissolution.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: toolview 溶解——工具行即 per-view keyed slot
Status: implemented
Archived: 2026-09-04
[English](2026-07-23-toolview-dissolution.md) | 中文
@@ -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/architecture/2026-07-24-adapter-owned-reasoning-effort-capabilities.md
2026-07-24-adapter-owned-reasoning-effort-capabilities.md: f5c240145dc7f405f8bc1f66b6b5f7f68991eb80
2026-07-24-adapter-owned-reasoning-effort-capabilities.zh.md: 81994d4908bd9531cc7db35634bf768372ace1d7
@@ -1,6 +1,7 @@
# Agent Note: Adapter-owned reasoning effort capabilities
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-24-adapter-owned-reasoning-effort-capabilities.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 适配器持有的推理强度能力
Status: implemented
Archived: 2026-09-04
[English](2026-07-24-adapter-owned-reasoning-effort-capabilities.md) | 中文
@@ -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/architecture/2026-07-25-web-command-surfaces-and-assembly.md
2026-07-25-web-command-surfaces-and-assembly.md: bfb7d2697a979efc8101581d42f4ab223d1b1e97
2026-07-25-web-command-surfaces-and-assembly.zh.md: d81f70403d22efb2203bbe221a45035fc3d6503f
@@ -1,6 +1,7 @@
# Agent Note: Web command business surfaces and assembly (ui-commands / ui-skill / ui-subagent)
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-25-web-command-surfaces-and-assembly.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: Web 命令业务面与装配(ui-commands / ui-skill / ui-subagent)
Status: implemented
Archived: 2026-09-04
[English](2026-07-25-web-command-surfaces-and-assembly.md) | 中文
@@ -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/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md
2026-07-25-web-input-machine-and-slash-pipeline.md: b6d485d495717770ebb5148880b3c8c1cb23b948
2026-07-25-web-input-machine-and-slash-pipeline.zh.md: 69ed9a40f4dd9a316f147e3077c9167e1ee46eeb
@@ -1,6 +1,7 @@
# Agent Note: Web input state machine, composer slots, and the slash pipeline (ui-conversation input / ui-input-trigger)
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-25-web-input-machine-and-slash-pipeline.zh.md)
@@ -48,14 +49,14 @@ Calls that stay un-evented (registry registration → explicit call → await):
A trigger/menu/pick pipeline with zero knowledge of "commands":
- The service holds only the source registry (`InputTriggerSource{trigger: '/'|'@', name, order?, candidates, onPick, matchSpace?, matchEnter?}`; (trigger,name) unique; the optional `order` sorts the roster — lower first, default 0, ties keep registration order — and that sorted roster is both group order and polling order) and `sessionOf(sctx)`. Implementing a match hook IS the declaration of participation in space/enter adjudication; the pipeline polls in roster order, the first non-undefined answer wins, and no claimant means the default sink. matchSpace is synchronous (space fires mid-keystroke; hot cache only); matchEnter is asynchronous (it may await the source's own warmup, and a warmup failure rejects).
- The controller holds the single authoritative hit (span included; retained for Space after the menu closes), the per-session menu store, the candidate-fetch generation, keyboard arbitration (combobox mode: focus stays in the composer surface, ↑↓/Enter/Escape are intercepted and all pass the IME composition guard, with the single exception Shift+Enter unconditionally going first), and pick orchestration (outcome → self-dispatched bail events). `toggleSource(name, syntheticHit)` is the chrome-launch path: it seeds only that registered source over the caller's composer selection and publishes `launcher = name` until close; ordinary typed tracking clears the launcher and restores the full trigger roster. Both paths render the same MenuView and execute the same `onPick` chain. A `dismiss()` verb backs MenuView's injected `onDismiss` (a pointer down outside both the menu and the surrounding composer card closes the menu; MenuView also localizes group titles through the `slash.menu` locale namespace and clamps its height to the viewport space above the composer via ui-primitives' `useAnchoredMaxHeight`); at each session scope's birth it runs `warm(projection)` once over the source roster — within that scope the projection holds only the stable sessionId, with no published/capability transitions; the scope disposer tears down the controller.
- The controller holds the single authoritative hit (span included; retained for Space after the menu closes), the per-session menu store, the candidate-fetch generation, keyboard arbitration (combobox mode: focus stays in the composer surface; ↑↓/Enter/Escape are intercepted; Tab settles a highlighted completion, using the candidate's drill action when available and its ordinary pick otherwise, while no highlight preserves native focus traversal; all arbitration passes the IME composition guard, with the single exception Shift+Enter unconditionally going first), and pick orchestration (outcome → self-dispatched bail events). `toggleSource(name, syntheticHit)` is the chrome-launch path: it seeds only that registered source over the caller's composer selection and publishes `launcher = name` until close; ordinary typed tracking clears the launcher and restores the full trigger roster. Both paths render the same MenuView and execute the same `onPick` chain. A `dismiss()` verb backs MenuView's injected `onDismiss` (a pointer down outside both the menu and the surrounding composer card closes the menu; MenuView also localizes group titles through the `slash.menu` locale namespace and clamps its height to the viewport space above the composer via ui-primitives' `useAnchoredMaxHeight`); at each session scope's birth it runs `warm(projection)` once over the source roster — within that scope the projection holds only the stable sessionId, with no published/capability transitions; the scope disposer tears down the controller.
- Trigger-detection word boundaries (`user@host` and URL `/` never trigger) and the guard tiers (plain: `/` everywhere + `@` inline / claimed: `/` suppressed, `@` live / frozen: none) are the frozen pure core.
### hub / facade: the resident shell and the strict-session input body
- The hub (trigger/decoration registries + send orchestration) takes the slash/command services as optional `ctx.get()` dependencies: without ui-input-trigger or the command surfaces, input still sends and receives normally — graceful degradation.
- Each materialized Session has exactly one `SessionInputShell` (the facade), created and torn down with the session scope; with no session, no input machine is built. `ConversationRoot` is itself the `session-maybe` resident shell, holding HeroShell, the Workspace picker, the composer stack, and the chain-fallback frame. It always owns the same scrollport and composer seat; separate strict-session header and body outlets fill those fixed regions after a Session appears.
- The composer bar is one `session-maybe` slot entry rendered unconditionally: with no session the same InputBar renders inert (machine faces absent, `disabled` owner prop), and once `connectWorkspace` returns a blank session the same instance goes live — the composer surface DOM survives the no-session → blank transition and every later phase flip; `ConversationRoot`, the Hero, and the layout skeleton hold throughout.
- The composer bar is one `session-maybe` slot entry rendered unconditionally: with no session the same InputBar renders inert (machine faces absent, `disabled` owner prop), and once `connectWorkspace` returns a blank session the same instance goes live — the composer surface DOM survives the no-session → blank transition and every later phase flip; `ConversationRoot`, the Hero, and the layout skeleton hold throughout. The memoized InputBar renders its overlay, left, right, and dock child slots after the renderer has bound their standard props; `ConversationRoot` passes only scalar data and callbacks, so an unrelated shell render does not create fresh ReactNode owner props or invalidate the bar.
- ConversationRoot's Hero criterion is `sessionId === undefined || (composerPhase === 'blank' && (openState === 'open' || summaryBlank === true))`: a summary-proven blank Session remains Hero in every open state, while an unproven Session settles during loading. The first submit enters engaging synchronously, and a failure keeps the composer and the error context rather than falling back to the blank Hero; the sidebar's blank bit flips false only after a prompt is successfully accepted.
- Sending unifies in the hub defaultSink: after an optimistic draft clear it goes only through `session.prompt` with `mode:'queue'` (the Web UI has no steer entry; host-wire `mode:'steer'` remains outside this machine); backfill happens only when it fails and the live draft is still empty — a user who has kept typing is never overwritten. No Draft materialize or attach transaction exists.
- When the blank Hero re-picks the Workspace, the shell calls `connectWorkspace`; if the target session differs, the non-empty draft moves from the current shell to the target shell before the new id is opened, and the old blank session survives but is no longer current.
@@ -67,8 +68,8 @@ skill/@subagent references skip the placeholder + occurrence identity chain —
- PickOutcome gains a `{text}` arm; the new scoped bail event `slash/input-insert-text` `{text, span}` (the same contract as the other three: draftRev CAS, returning true ⟺ an actual rewrite); facade.insertText goes through setDraft concatenation — zero machine changes.
- Sources get an optional `lexicon?(session)` hook: a synchronous hot-snapshot name roster, with `undefined` = data not warm — zero decoration, never triggering a fetch (the render path stays synchronous and side-effect-free); the paired optional `subscribeLexicon?(session, listener)` hook is the invalidation channel for rolls that change after warm (catalog settles, children spawn/exit). The controller aggregates the rolls into its `lexicon` snapshot store (re-polling on each source notification); sources registered after scope birth are warmed and folded in via the service's live-controller broadcast.
- `decorations.scanTextRefs`: a word-boundary scan of the draft (`/name`, `@name` at line start / after whitespace; `x/name` never hits) against the roster; a hit becomes a `TextRefNode` entity in the Lexical tree (the claim decoration has precedence on the leading-token seat — [the Lexical composer note](2026-08-20-web-composer-lexical-editor.md)); an edit breaking the match shape reverts the entity to plain text.
- Sending is the literal text (no more `<skill>` serialization); on the bubble side MessageItem decorates both shapes (the legacy `<skill>` tag + plain-text tokens).
- `decorations.scanTextRefs`: a word-boundary scan of the draft (`/name`, `@name` at line start / after whitespace; `x/name` never hits; a `/name` token also ends at whitespace or the draft end — the whitespace-bounded shape of the host skill gesture, so `/nfs-hg/xxx` is a path and `/plan。` is prose; the sent-text projection `projectUserText` in ui-primitives applies the same shape) against the roster; a hit becomes a `TextRefNode` entity in the Lexical tree (the claim decoration has precedence on the leading-token seat — [the Lexical composer note](2026-08-20-web-composer-lexical-editor.md)); an edit breaking the match shape reverts the entity to plain text.
- Sending is the literal text (no more `<skill>` serialization); on the bubble side `projectUserText` decorates a plain-text `/name` token only when the same step logged a `skill-invocation` injection for that name — ui-chat's `SkillNameProjector` attaches the step's injected names to the direct message Node, the way the recall projector attaches session labels — so `/123` or a stray `/word` stays plain; a command-input bubble (ui-goal) names its executed command the same way and renders the token as a `command` chip; `@name` tokens still decorate by shape.
- Decoration reactivity: the shell subscribes to the controller's lexicon store and re-scans the document on each roll change, so a roll that settles after the scope-birth prewarm lights existing draft tokens up without any menu interaction or unrelated re-render.
### Per-session provide contributions and the private keyboard surface
@@ -105,6 +106,7 @@ The state machine's entire behavior is covered by pure-JS unit tests (event sequ
| Dual draft persistence {text, occurrences} | The mirror writing the clipboard projection adds zero new concepts; chip degradation across refresh is acceptable |
| The native textarea undo stack | Unreliable under controlled + programmatic writes; the paste two-step undo semantics can only be self-managed — both sides retired with the textarea itself; Lexical's history owns undo now |
| The InputBar receiving a 16-member wiring-callback bundle | The consumption matrix proved 11 members InputBar-exclusive and 1 a dead member; the standard-kit channel lets components fetch their own, with the keyboard surface passed privately in-package |
| `ConversationRoot` rendering InputBar's child slots into owner props | Fresh React elements defeat the bar's memo boundary; the bar already receives `renderSlot` and owns the exact positions |
| Space adjudication also claiming execute-kind commands | The misfire defense: after a space the whole line is an ordinary prompt; irreversible side effects keep explicit entry points only |
| A generic tokenPattern decoration mechanism | Structured occurrence records replace pattern scanning |
| A placeholder select resident in the tool row | Named seats stay empty until registration; a placeholder clashing with the real implementation is two sources of truth |
@@ -1,6 +1,7 @@
# Agent Note: Web 输入状态机、composer slot 与 slash 流水线(ui-conversation input / ui-input-trigger)
Status: implemented
Archived: 2026-09-04
[English](2026-07-25-web-input-machine-and-slash-pipeline.md) | 中文
@@ -48,14 +49,14 @@ Status: implemented
对「命令」零知识的触发/菜单/pick 流水线:
- 服务只有 source 注册表(`InputTriggerSource{trigger: '/'|'@', name, order?, candidates, onPick, matchSpace?, matchEnter?}`;(trigger,name) 唯一;可选 `order` 对 roster 排序——越小越靠前、默认 0、同值保持注册序——排序后的 roster 同时是组序与轮询序)与 `sessionOf(sctx)`。实现 match 钩子即参与空格/回车裁决的声明;流水线按 roster 序轮询,首个非 undefined 应答胜出,无人认领落 default sink。matchSpace 同步(空格在击键中触发,只许热缓存);matchEnter 异步(可 await 源自身预热,预热失败即 reject)。
- controller 持有唯一权威 hit(含 span;菜单关闭后为 Space 保留)、每会话 menu store、候选 fetch generation、键盘仲裁(combobox 模式:焦点始终在编辑器表面,↑↓/Enter/Escape 拦截且全程过 IME composition 守卫,唯一例外 Shift+Enter 无条件先行),以及 pick 编排(outcome → 自派 bail 事件)。`toggleSource(name, syntheticHit)` 是 chrome launcher 路径:它基于调用方的编辑器 selection,只 seed 对应的已注册 source,并发布 `launcher = name` 直至关闭;普通的键入式 tracking 会清除 launcher 并恢复完整的 trigger roster。两条路径渲染同一个 MenuView,并执行同一条 `onPick` 链。`dismiss()` 动词支撑 MenuView 注入的 `onDismiss`(指针落在菜单与所在 composer 卡片之外即关闭菜单;MenuView 还经 `slash.menu` locale 命名空间本地化组标题,并经 ui-primitives 的 `useAnchoredMaxHeight` 把高度收敛到 composer 上方的视口空间);每个会话作用域出生时对 source roster 做一次 `warm(projection)`,projection 在该 scope 内只有稳定的 sessionId,无 published/能力跃迁;scope disposer 拆除 controller。
- controller 持有唯一权威 hit(含 span;菜单关闭后为 Space 保留)、每会话 menu store、候选 fetch generation、键盘仲裁(combobox 模式:焦点始终在编辑器表面;↑↓/Enter/Escape 会被拦截;Tab 会选定高亮补全项,候选项可下钻时走 drill 动作,否则走普通 pick,无高亮时保留原生焦点遍历;所有仲裁都经过 IME composition 守卫,唯一例外是 Shift+Enter 无条件先行),以及 pick 编排(outcome → 自派 bail 事件)。`toggleSource(name, syntheticHit)` 是 chrome launcher 路径:它基于调用方的编辑器 selection,只 seed 对应的已注册 source,并发布 `launcher = name` 直至关闭;普通的键入式 tracking 会清除 launcher 并恢复完整的 trigger roster。两条路径渲染同一个 MenuView,并执行同一条 `onPick` 链。`dismiss()` 动词支撑 MenuView 注入的 `onDismiss`(指针落在菜单与所在 composer 卡片之外即关闭菜单;MenuView 还经 `slash.menu` locale 命名空间本地化组标题,并经 ui-primitives 的 `useAnchoredMaxHeight` 把高度收敛到 composer 上方的视口空间);每个会话作用域出生时对 source roster 做一次 `warm(projection)`,projection 在该 scope 内只有稳定的 sessionId,无 published/能力跃迁;scope disposer 拆除 controller。
- 触发检测词边界(`user@host`、URL `/` 永不触发)、守卫分档(plain:`/` 到处 + `@` 行内 / claimed:`/` 抑制、`@` 活 / frozen:全无)为冻结纯核。
### hub / facade:常驻外壳与严格会话输入体
- hub(trigger/decoration 注册表 + 发送编排)对 slash/command 服务是可选 `ctx.get()` 依赖:无 ui-input-trigger/命令面时输入正常收发,优雅降级。
- 每个实体会话只有一个 `SessionInputShell`(facade),随会话作用域创建和拆除;无会话时不造 input machine。`ConversationRoot` 自身是 `session-maybe` 常驻外壳,持有 HeroShell、Workspace picker、composer stack 与 chain fallback 外框。它始终拥有同一个 scrollport 与 composer seat;会话出现后,彼此独立的严格会话 header 和 body outlet 只填入这些固定区域。
- composer bar 是一个无条件渲染的 `session-maybe` slot entry:无会话时同一个 InputBar 以惰性态渲染(machine face 缺席、`disabled` owner prop),`connectWorkspace` 返回 blank 会话后同一实例转为 live——编辑器表面 DOM 在无会话 → blank 切换及其后每次 phase 翻转中都不重建;`ConversationRoot`、Hero 与布局骨架全程保持。
- composer bar 是一个无条件渲染的 `session-maybe` slot entry:无会话时同一个 InputBar 以惰性态渲染(machine face 缺席、`disabled` owner prop),`connectWorkspace` 返回 blank 会话后同一实例转为 live——编辑器表面 DOM 在无会话 → blank 切换及其后每次 phase 翻转中都不重建;`ConversationRoot`、Hero 与布局骨架全程保持。memoized InputBar 在 renderer 绑定各 child slot 的标准 props 后自行渲染 overlay、left、right 与 dock;`ConversationRoot` 只传标量数据和回调,因此无关 shell render 不会制造新的 ReactNode owner prop 或使 bar 失效。
- ConversationRoot 的 Hero 判据是 `sessionId === undefined || (composerPhase === 'blank' && (openState === 'open' || summaryBlank === true))`:summary 已证实为空的会话在任何 open state 下都保持 Hero,未经证实的会话则在 loading 期间进入 settling。首次 submit 同步进入 engaging,失败也保留 composer 与错误上下文,不退回 blank Hero;sidebar 的 blank 位只在提示词成功受理后翻 false。
- 发送统一在 hub defaultSink:乐观清稿后只走 `session.prompt` 且固定 `mode:'queue'`(Web UI 无 steer 入口;host 线缆上的 `mode:'steer'` 不经此 machine);失败且 live draft 仍为空才回填,用户已经继续输入则不覆盖。不存在 Draft materialize 或 attach 事务。
- blank Hero 改选 Workspace 时,外壳调用 `connectWorkspace`;目标会话不同时把非空 draft 从当前 shell 搬到目标 shell,再 open 新 id,旧 blank 会话留存但不再 current。
@@ -67,8 +68,8 @@ skill/@subagent 引用不走占位符 + occurrence 身份链——纯文本引
- PickOutcome 增 `{text}` arm;新 scoped bail 事件 `slash/input-insert-text` `{text, span}`(与另三个同约定:draftRev CAS、返回 true ⟺ 实际改写);facade.insertText 走 setDraft 拼接,机器零改动。
- source 可选 `lexicon?(session)` 钩子:同步热快照名录,`undefined` = 数据未热——零装饰、永不触发 fetch(渲染路径保持同步无副作用);配对的可选 `subscribeLexicon?(session, listener)` 钩子是名录在 warm 之后仍会变化(目录 settle、子代生灭)时的失效通道。controller 把各名录聚合进自己的 `lexicon` 快照 store(每次 source 通知重拉);scope 出生后才注册的 source 由服务广播给活 controller,补 warm 并并入名录。
- `decorations.scanTextRefs`:词边界扫描 draft(行首/空白后的 `/name`、`@name`,`x/name` 永不命中)对照名录,命中即成为 Lexical 树中的 `TextRefNode` 实体(claim 装饰对行首 token 席位有优先权——见 [Lexical composer note](2026-08-20-web-composer-lexical-editor.zh.md));编辑破坏匹配形状时实体还原为普通文本。
- 发送即原文(不再 `<skill>` 序列化);气泡侧 MessageItem 双形状装饰(legacy `<skill>` 标签 + 纯文本 token)。
- `decorations.scanTextRefs`:词边界扫描 draft(行首/空白后的 `/name`、`@name`,`x/name` 永不命中;`/name` token 还必须止于空白或 draft 末尾——与宿主 skill gesture 同样以空白为界,因此 `/nfs-hg/xxx` 是路径、`/plan。` 是普通文本;ui-primitives 中已发送文本的投影 `projectUserText` 采用同一形状)对照名录,命中即成为 Lexical 树中的 `TextRefNode` 实体(claim 装饰对行首 token 席位有优先权——见 [Lexical composer note](2026-08-20-web-composer-lexical-editor.zh.md));编辑破坏匹配形状时实体还原为普通文本。
- 发送即原文(不再 `<skill>` 序列化);气泡侧 `projectUserText` 只在同一步骤记录了该名字的 `skill-invocation` 注入时才装饰纯文本 `/name` token——ui-chat 的 `SkillNameProjector` 把该步骤注入的 skill 名挂到直接消息节点上,与 recall 投影挂会话标签的方式相同——因此 `/123` 或随手敲的 `/词` 保持普通文本;指令输入气泡(ui-goal)以同样方式指明其已执行的指令,把 token 渲染为 `command` chip;`@name` token 仍按形状装饰。
- 装饰响应性:shell 订阅 controller 的 lexicon store,每次名录变化重扫全文档,scope 出生预热后才 settle 的名录会直接点亮已有 draft token,无需菜单交互或无关重渲染。
### 每会话供数贡献与键盘私面
@@ -105,6 +106,7 @@ skill/@subagent 引用不走占位符 + occurrence 身份链——纯文本引
| draft 双持久化 {text, occurrences} | mirror 写剪贴板投影零新概念;chip 跨刷新降级可接受 |
| 原生 textarea undo 栈 | 受控 + 程序化写入下不可靠;粘贴两段 undo 语义只能自管——两侧都随 textarea 一并退役;undo 现归 Lexical history |
| InputBar 收 16 员 wiring 回调包 | 消费矩阵实证 11 员 InputBar 独占、1 员死成员;标准件通道让组件自取,键盘面包内私递 |
| 由 `ConversationRoot` 把 InputBar child slot 渲染为 owner prop | 新 React element 会击穿 bar 的 memo 边界;bar 已收到 `renderSlot`,也拥有这些位置 |
| 空格裁决也认领即执行型命令 | 误触发防线:空格后整行是普通提示词;不可逆副作用只留显式入口 |
| 通用 tokenPattern 装饰机制 | 结构化 occurrence 记录取代模式扫描 |
| 占位 select 常驻工具行 | 具名 slot 在注册前保持为空;占位件与真实现冲突时是两个真源 |
@@ -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/architecture/2026-07-26-job-registry-seam.md
2026-07-26-job-registry-seam.md: d1a8cfb7bc4f1a8e313dfa8d59a5d0e5f8106190
2026-07-26-job-registry-seam.zh.md: 1624a410407d8e6ac8cc85a6fe1480e0867eef6d
@@ -1,6 +1,7 @@
# Agent Note: The job registry is a capability seam (`dsh-jobs` / `dsh-jobs-local`)
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-26-job-registry-seam.zh.md)
@@ -16,7 +17,7 @@ The [background-job runtime](2026-06-20-generic-long-running-tool-runtime.md) sh
- **`@deepseek-ai/dsh-jobs-local` (Service Provider)** — `LocalJobRegistry`, the process-local registry: the in-memory store, per-kind id counters, waiter bookkeeping, `TASK_WAIT_TIMEOUT` deadline code, owner-cleanup effects, force-fail teardown, and the default-10 configurable admission policy. Admission derives `running` plus `stopping` capacity from the same records per exact owner, with one unowned bucket; it adds no public count or second state owner. The `dsh-timeout` dependency and Schemastery-owned provider config live here; the Service Definition package has no provider dependencies.
- **`@deepseek-ai/dsh-tool-jobs` (Consumer)** — unchanged; it injects `'jobs'` and never imports provider types.
Compositions load `dsh-jobs-local` where they previously loaded `dsh-jobs` (the CLI cordis.yml row, `agent-spine-demo`, test harnesses, the tool-catalog generator boot). Producer misconfiguration diagnostics ("background jobs unavailable: load …") name `dsh-jobs` — the Service Definition package that declares the absent `ctx.jobs` service — and the Service Definition package's own APIs (its README and the direct-mount fence) point at Service Providers, so the producer message stays correct when another backend becomes the recommended default. Producers, `JobKindMap` declaration merges, and the controller keep importing `@deepseek-ai/dsh-jobs` only.
Compositions load `dsh-jobs-local` where they previously loaded `dsh-jobs` (`dsh-base`, `sdk-minimal`, test harnesses, and the tool-catalog generator boot). Producer misconfiguration diagnostics ("background jobs unavailable: load …") name `dsh-jobs` — the Service Definition package that declares the absent `ctx.jobs` service — and the Service Definition package's own APIs (its README and the direct-mount fence) point at Service Providers, so the producer message stays correct when another backend becomes the recommended default. Producers, `JobKindMap` declaration merges, and the controller keep importing `@deepseek-ai/dsh-jobs` only.
The seam keeps the in-process contract semantics unchanged: `JobStart.run()` still passes callbacks and exact `Agent` objects, so a durable or cross-process backend still has design work to do before it can satisfy this Service Definition (identity, restart, ownership, observation). The split moves that future work out of every Consumer's dependency graph; it does not pre-design the backend.
@@ -1,6 +1,7 @@
# Agent Note: 任务注册表是一个能力 seam(`dsh-jobs` / `dsh-jobs-local`)
Status: implemented
Archived: 2026-09-04
[English](2026-07-26-job-registry-seam.md) | 中文
@@ -16,7 +17,7 @@ Status: implemented
- **`@deepseek-ai/dsh-jobs-local`(Service Provider)**——`LocalJobRegistry`,即进程内注册表:内存存储、按 kind 划分的 id 计数器、等待方簿记、`TASK_WAIT_TIMEOUT` deadline 代码、所有者清理 effect、强制失败的拆除,以及默认值为 10 且可配置的准入策略。准入从同一组记录中按确切 owner 派生 `running` 加 `stopping` 容量,并为无 owner 任务使用一个共享桶;它不新增公开计数或第二个状态 owner。`dsh-timeout` 依赖与由 Schemastery 管理的 Service Provider 配置都位于此包;Service Definition 包不含任何提供方依赖。
- **`@deepseek-ai/dsh-tool-jobs`(Consumer)**——保持不变;它注入 `'jobs'`,从不导入提供方类型。
各组合在原先加载 `dsh-jobs` 的位置改为加载 `dsh-jobs-local`:CLI(命令行界面)的 cordis.yml 配置项、`agent-spine-demo`、各测试 harness,以及工具目录生成器的启动流程。生产方的配置错误诊断信息(「background jobs unavailable: load …」)点名 `dsh-jobs`——即声明缺失的 `ctx.jobs` 服务的 Service Definition 包;Service Definition 包自身的 API(其 README 与直接挂载防线)会指向各 Service Provider,因此当另一个后端日后成为推荐默认时,生产方的消息依旧正确。生产方、`JobKindMap` 声明合并和控制器仍然只导入 `@deepseek-ai/dsh-jobs`。
各组合在原先加载 `dsh-jobs` 的位置改为加载 `dsh-jobs-local`:`dsh-base`、`sdk-minimal`、各测试 harness,以及工具目录生成器的启动流程。生产方的配置错误诊断信息(「background jobs unavailable: load …」)点名 `dsh-jobs`——即声明缺失的 `ctx.jobs` 服务的 Service Definition 包;Service Definition 包自身的 API(其 README 与直接挂载防线)会指向各 Service Provider,因此当另一个后端日后成为推荐默认时,生产方的消息依旧正确。生产方、`JobKindMap` 声明合并和控制器仍然只导入 `@deepseek-ai/dsh-jobs`。
该 seam 保持进程内约定语义不变:`JobStart.run()` 仍然传入回调和确切的 `Agent` 对象,因此持久化或跨进程后端在能满足此 Service Definition 之前仍有设计工作要做(身份、重启、所有权、观察)。这次拆分把该项未来工作移出了每个 Consumer 的依赖图;它并不预先设计后端。
@@ -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/architecture/2026-07-26-packed-chunk-rows-by-default.md
2026-07-26-packed-chunk-rows-by-default.md: c230c1f1faf5e597321654ebd01d60fae725f518
2026-07-26-packed-chunk-rows-by-default.zh.md: e354efdf6bb68c02f30dc17c8d4ba17a495b61bd
@@ -1,6 +1,7 @@
# Agent Note: Make packed chunk rows the default JSONL layout
Status: implemented
Archived: 2026-09-01
English | [中文](2026-07-26-packed-chunk-rows-by-default.zh.md)
@@ -18,7 +19,7 @@ Reading is unconditional and layout-blind. Packed, unpacked, and mixed files loa
### Logical events and physical rows
The JSONL packing path stays at the `dsh-session` storage seam through `packChunkRuns()` and `decodeStorageRecord()`. The encoder recognizes exact delta-event shapes, preserves unrecognized events verbatim, and packs only runs of at least three. A packed row is encoding vocabulary, not a `SessionEventMap` member: it never enters `Session.events` or fires `session/event`. The [packed session-history transport decision](2026-08-15-packed-session-history-transport.md) reuses this vocabulary for a bounded lossless wire interval without changing those event semantics.
The JSONL packing path stays at the `dsh-session` storage seam through `packChunkRuns()` and `decodeStorageRecord()`. The encoder recognizes exact delta-event shapes, preserves unrecognized events verbatim, and packs only runs of at least three. A packed row is encoding vocabulary, not a `SessionEventMap` member: it never enters the Session log or fires `session/event`. The [packed session-history transport decision](2026-08-15-packed-session-history-transport.md) reuses this vocabulary for a bounded lossless wire interval without changing those event semantics.
The JSONL backend packs each durable append batch. Raw `compression: 'none'` and default Zstandard framing carry the same logical storage records; selecting raw mode for reviewable fixtures does not disable packing. Repository replay readers and normalizers decode the shared row format instead of maintaining snapshot-specific codecs.
@@ -1,6 +1,7 @@
# Agent Note: 将打包分片行设为默认 JSONL 布局
Status: implemented
Archived: 2026-09-01
[English](2026-07-26-packed-chunk-rows-by-default.md) | 中文
@@ -18,7 +19,7 @@ JSONL 存储 seam 可以在不改变逻辑日志的情况下减少这部分封
### 逻辑事件与物理行
JSONL 打包路径保留在 `dsh-session` 的存储 seam,并通过 `packChunkRuns()` 和 `decodeStorageRecord()` 实现。编码器识别精确的增量事件形态,原样保留无法识别的事件,并且只打包至少包含 3 个事件的连续段。打包行属于编码词汇,不是 `SessionEventMap` 成员:它绝不会进入 `Session.events`,也不会触发 `session/event`。[打包会话历史传输决策](2026-08-15-packed-session-history-transport.zh.md)会为有界的无损协议区间复用该词汇,而不改变这些事件语义。
JSONL 打包路径保留在 `dsh-session` 的存储 seam,并通过 `packChunkRuns()` 和 `decodeStorageRecord()` 实现。编码器识别精确的增量事件形态,原样保留无法识别的事件,并且只打包至少包含 3 个事件的连续段。打包行属于编码词汇,不是 `SessionEventMap` 成员:它绝不会进入 Session 日志,也不会触发 `session/event`。[打包会话历史传输决策](2026-08-15-packed-session-history-transport.zh.md)会为有界的无损协议区间复用该词汇,而不改变这些事件语义。
JSONL 后端会打包每个持久追加批次。原始模式 `compression: 'none'` 与默认 Zstandard 帧承载相同的逻辑存储记录;为使 fixture 便于评审而选择原始模式,不会禁用打包。仓库中的回放读取器和规范化器会解码共享行格式,而不维护快照专用编解码器。
@@ -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/architecture/2026-07-26-subprocess-seam.md
2026-07-26-subprocess-seam.md: bd8cba2197a56acef2ab12e9b43e254fbc744ee5
2026-07-26-subprocess-seam.zh.md: ba23649e9e68f578bdc9ba26a026981d0afe981f
@@ -1,6 +1,7 @@
# Agent Note: The subprocess service is its own seam under the bash executors (`dsh-subprocess` / `dsh-subprocess-local`)
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-26-subprocess-seam.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 进程服务是 bash 执行器之下的独立 seam(`dsh-subprocess` / `dsh-subprocess-local`)
Status: implemented
Archived: 2026-09-04
[English](2026-07-26-subprocess-seam.md) | 中文
@@ -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/architecture/2026-07-27-dispose-ladder-to-consumer.md
2026-07-27-dispose-ladder-to-consumer.md: 7e1b189c1d3a32c6f812bba5d5f06f7a6a89c29b
2026-07-27-dispose-ladder-to-consumer.zh.md: 6c61cad5d4a62c5c976894f72d0ff5e9c69184bc
@@ -1,6 +1,7 @@
# Agent Note: The dispose ladder belongs to its consumer, not the subprocess seam
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-27-dispose-ladder-to-consumer.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: dispose 阶梯归其消费方所有,而非 subprocess seam
Status: implemented
Archived: 2026-09-04
[English](2026-07-27-dispose-ladder-to-consumer.md) | 中文
@@ -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/architecture/2026-07-28-directory-picker-capability-seam.md
2026-07-28-directory-picker-capability-seam.md: e2f3312b7429078eb81cba62ab1727e71fe67b74
2026-07-28-directory-picker-capability-seam.zh.md: 41a05febe58c353242cc389e20bbf84b3620b7c9
@@ -1,6 +1,7 @@
# Agent Note: A capability-discriminated directory-picker seam for the web-GUI host
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-28-directory-picker-capability-seam.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: web GUI 宿主的能力可辨识目录选择 seam
Status: implemented
Archived: 2026-09-04
[English](2026-07-28-directory-picker-capability-seam.md) | 中文
@@ -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/architecture/2026-07-28-user-settings-seam.md
2026-07-28-user-settings-seam.md: 75fef5ed976d80acb4e26133c2b98d8504042121
2026-07-28-user-settings-seam.zh.md: 9797e5a3288a7709f3541784778c514890015410
@@ -1,6 +1,7 @@
# Agent Note: user-settings seam (`ctx.settings`) and the file provider
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-28-user-settings-seam.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 用户设置 seam(`ctx.settings`)与文件提供方
Status: implemented
Archived: 2026-09-04
[English](2026-07-28-user-settings-seam.md) | 中文
@@ -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/architecture/2026-07-29-package-regrouping.md
2026-07-29-package-regrouping.md: 7073d868fe73f75477cf9a6fa2c5f7c425d014a8
2026-07-29-package-regrouping.zh.md: b33ecf1600ce9c9796e932c14c5df9782bb3a94b
@@ -1,6 +1,7 @@
# Agent Note: Regroup packages/ by measured clustering
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-29-package-regrouping.zh.md)
@@ -21,13 +22,13 @@ Five regrouping decisions remain current; every other group keeps its prior boun
| Group | Members (folder names) | From |
|---|---|---|
| `session/` | session-persistence, session-persistence-jsonl, session-persistence-sqlite, session-checkpoint-policy, session-projection, session-projection-cache, session-title, session-title-llm, session-title-first-prompt-llm, session-title-all-prompts-llm, session-telemetry, session-telemetry-otel | `session-persistence/` + `session-projection/` + `session-title/` + `telemetry/` |
| `session/` | session-persistence, session-persistence-jsonl, session-checkpoint-policy, session-projection, session-projection-cache, session-title, session-title-llm, session-title-first-prompt-llm, session-title-all-prompts-llm, session-telemetry, session-telemetry-otel | `session-persistence/` + `session-projection/` + `session-title/` + `telemetry/` |
| `interaction/` | user-questions, user-approval, permission-presets, tool-ask-user, commands, tui | `ui/` |
| `boot/` | app-boot | `ui/` |
| `guard/` | repeat-tool-reminder, timeout-policy | `guard/` + `timeout/` |
| `extensions/` | tool-cordis | `cordis/` |
- **`session/`** is the durable session data plane: the persistence seam with its backends and checkpoint policy, the projection fold that serves whole values from that log, log-backed titles, and OTel reporting. The title fold is itself load-bearing for the read side (`session-query` peer-depends on `dsh-session-title`), so titles belong with the data plane, not in a derived-services annex. The plain name is deliberate (prefer names a human would say); the nearby `core/session` package remains the live in-memory service, while this group is the durable family around it. `session-query/` stays a standalone group — the read/tool surface has its own model tools and SQLite FTS backend and is consumed independently of persistence internals.
- **`session/`** is the durable session data plane: the persistence seam with its JSONL provider and checkpoint policy, the projection fold that serves whole values from that log, log-backed titles, and OTel reporting. The title fold is itself load-bearing for the read side (`session-query` peer-depends on `dsh-session-title`), so titles belong with the data plane, not in a derived-services annex. The plain name is deliberate (prefer names a human would say); the nearby `core/session` package remains the live in-memory service, while this group is the durable family around it. `session-query/` stays a standalone group — the read/tool surface has its own model tools and SQLite FTS backend and is consumed independently of persistence internals.
- **`interaction/`** is the human-collaboration plane plus the terminal channel that answers it: the question/approval seams, the permission preset, the model-facing `ask_user_question` tool, the human-command registry (`plan-mode` and `command-goal` already consume `commands` together with the interaction seams), and `tui` — the interactive channel is the plane's richest provider and consumer (peer edges to `commands` and `user-questions`), and a one-package `tui/` group would spend a top-level name on one plugin.
- **`boot/`** is a role-complete single-package group: the shared boot glue that belongs to no channel and no assembly (consumed by `apps/cli` and test-only Loader drivers).
- **`guard/`** keeps its documented role, loop-hygiene guards, and gains the tool-call timeout enforcer, dissolving the one-package `timeout/` group whose name collided with `util/timeout`.
@@ -1,6 +1,7 @@
# Agent Note: 按实测聚类重新划分 packages/ 分组
Status: implemented
Archived: 2026-09-04
[English](2026-07-29-package-regrouping.md) | 中文
@@ -21,13 +22,13 @@ Status: implemented
| 组 | 成员(目录名) | 来源 |
|---|---|---|
| `session/` | session-persistence、session-persistence-jsonl、session-persistence-sqlite、session-checkpoint-policy、session-projection、session-projection-cache、session-title、session-title-llm、session-title-first-prompt-llm、session-title-all-prompts-llm、session-telemetry、session-telemetry-otel | `session-persistence/` + `session-projection/` + `session-title/` + `telemetry/` |
| `session/` | session-persistence、session-persistence-jsonl、session-checkpoint-policy、session-projection、session-projection-cache、session-title、session-title-llm、session-title-first-prompt-llm、session-title-all-prompts-llm、session-telemetry、session-telemetry-otel | `session-persistence/` + `session-projection/` + `session-title/` + `telemetry/` |
| `interaction/` | user-questions、user-approval、permission-presets、tool-ask-user、commands、tui | `ui/` |
| `boot/` | app-boot | `ui/` |
| `guard/` | repeat-tool-reminder、timeout-policy | `guard/` + `timeout/` |
| `extensions/` | tool-cordis | `cordis/` |
- **`session/`** 是持久会话数据平面:持久化 seam 连同其各后端与检查点策略、从该日志折叠(fold)出全量值并对外提供的投影、基于日志的标题,以及 OTel 上报。标题折叠本身就是读取侧的承重构件(`session-query` 对 `dsh-session-title` 声明对等依赖),所以标题属于数据平面,而非某个「派生服务」附属区。用这个朴素的名字是有意为之(名字要像人起的);旁边的 `core/session` 包仍是常驻内存的实时服务,本组则是围绕它的持久家族。`session-query/` 保持独立成组:这个读取/工具面自带模型工具和 SQLite FTS 后端,其消费不依赖持久化内部实现。
- **`session/`** 是持久会话数据平面:持久化 seam 连同其 JSONL provider 与检查点策略、从该日志折叠(fold)出全量值并对外提供的投影、基于日志的标题,以及 OTel 上报。标题折叠本身就是读取侧的承重构件(`session-query` 对 `dsh-session-title` 声明对等依赖),所以标题属于数据平面,而非某个「派生服务」附属区。用这个朴素的名字是有意为之(名字要像人起的);旁边的 `core/session` 包仍是常驻内存的实时服务,本组则是围绕它的持久家族。`session-query/` 保持独立成组:这个读取/工具面自带模型工具和 SQLite FTS 后端,其消费不依赖持久化内部实现。
- **`interaction/`** 是人机协作平面加上应答它的终端通道:提问/批准 seam、权限预设、面向模型的 `ask_user_question` 工具、人类命令注册表(`plan-mode` 与 `command-goal` 已经把 `commands` 和各交互 seam 放在一起消费),以及 `tui`——这个交互通道是该平面功能最丰富的提供方与消费方(对 `commands` 与 `user-questions` 均有对等依赖边),而一个单包 `tui/` 组会把一个顶层名字花在一个插件上。
- **`boot/`** 是角色完备的单包组:不归属任何通道也不归属任何组装的共享 boot 胶水(被 `apps/cli` 与仅限测试的 Loader driver 消费)。
- **`guard/`** 保留其文档记载的角色(循环卫生守卫),并新纳入强制执行工具调用超时的包;那个与 `util/timeout` 撞名的单包组 `timeout/` 随之解散。
@@ -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/architecture/2026-07-29-request-level-llm-config-credentials.md
2026-07-29-request-level-llm-config-credentials.md: dda5cd6710ad432a25bce1214078098f4e797559
2026-07-29-request-level-llm-config-credentials.zh.md: e521920586c8fe9d3a498e0369d1693096562973
@@ -1,6 +1,7 @@
# Agent Note: request-level LLM configuration and the credential seam
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-29-request-level-llm-config-credentials.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 请求级 LLM 配置与凭据 seam
Status: implemented
Archived: 2026-09-04
[English](2026-07-29-request-level-llm-config-credentials.md) | 中文
@@ -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/architecture/2026-07-30-adapter-owned-max-token-defaults.md
2026-07-30-adapter-owned-max-token-defaults.md: 30b1840a9ff80092609698e63d061a7d82503e5d
2026-07-30-adapter-owned-max-token-defaults.zh.md: 770c61ce1514fa8e16d4cbabed4dd97b5b7b40fb
@@ -1,6 +1,7 @@
# Agent Note: Adapter-owned max-token defaults
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-30-adapter-owned-max-token-defaults.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: 适配器持有的最大 token 默认值
Status: implemented
Archived: 2026-09-04
[English](2026-07-30-adapter-owned-max-token-defaults.md) | 中文
@@ -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/architecture/2026-07-30-client-locale-full-rollout.md
2026-07-30-client-locale-full-rollout.md: 381a0ed642d7452cb4be2c9a755bf33c120cba76
2026-07-30-client-locale-full-rollout.zh.md: 81ae013e86c6ecb608a15c3664c5203233e27e40
@@ -1,6 +1,7 @@
# Agent Note: Full client copy rollout onto the typed locale seat
Status: implemented
Archived: 2026-09-04
English | [中文](2026-07-30-client-locale-full-rollout.zh.md)
@@ -1,6 +1,7 @@
# Agent Note: client 文案全量接入 typed locale 席位
Status: implemented
Archived: 2026-09-04
[English](2026-07-30-client-locale-full-rollout.md) | 中文
@@ -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/architecture/2026-07-30-command-row-copy-contract.md
2026-07-30-command-row-copy-contract.md: e5f1828e433015a1381ae4f7951c518bb6040107
2026-07-30-command-row-copy-contract.zh.md: 7efe1aa65ddd992e64807e229b1da682f5bc320b
Loaded 100 of 7865 files, more files were not shown because too many files have changed in this diff. Show more