- llm-retry: validate config before registering the projection unit;
document the branded-retry-id zod cast; start stateVersion at 1.
- agent-loop: register turnBoundary only after every config validation,
so a rejected constructor leaves no unit behind; the defensive-cap
test no longer needs fiber cleanup.
- agent-instructions: keep newest-first per-scope change history so the
latest visible change survives a surface replacement shadowing the
newest one (restores the previous scan-visible semantics); add a
regression test for the delete-after-shadow sequence.
- tool-skill: keep catalog-message history so a shadowed newest catalog
message still falls back to the latest visible digest.
- session-query-sqlite: drop the unused required sessionProjections
injection.
- plan-mode: restore the command/done error-drop regression test and the
cold-replay command/done fold; drop the inaccurate state-reference
comment.
- tool-todo: remove a stray blank line; document the turnBoundary
reader contract on the projection type.
Drop the persist?: boolean opt-in: every unit's state — client-visible and
host-only alike — is now written to the projection cache. A unit can no
longer silently skip the durable cache, host-only units no longer need an
explicit flag to participate in cold restore, and the persist-sharing
conflict check disappears with the field.
- ProjectionDefinition/ErasedDefinition lose persist; register overloads
simplify; checkpoint/restoreFloor/restore fold every registered unit.
- Registry and cache tests drop the persist:true fixtures and the
persistence-policy sharing test.
- READMEs and the state-and-client-views note record the uniform rule;
cordis API catalog and subsystem signatures regenerated.
- Keep cleaning remaining roots even if one cleanup rejects.
- Collapse the duplicated Windows-EPERM rationale to one comment.
- Dispose the cold-resume context's second JsonlSessionPersistence handle on
the shared root before afterEach removes it.
Remove 15 workspaces entries from knip.json: 2 keys naming packages that no
longer exist (packages/util/home, packages/client/web-ui) and 13 entries
whose entry/project equal the packages/*/* glob default. knip selects one
config per matched key by specificity, so a removed entry either lost an
unresolvable target or fell back to an identical glob config; knip still
runs clean (0 issues). 655 lines, down from 790.
The continuation spec cleaned each mkdtemp root with rmSync in afterEach
without closing the JsonlSessionPersistence handle first. On Windows,
rmSync recursive over a directory whose file handle is still open fails
with EPERM, surfacing intermittently in native complete as
dsh-subagent-continuation-* cleanup failures. Close the persistence
fiber before rmSync (mirrors jsonl.spec.ts), preserving per-root
dispose-then-delete order.
L55 said 'An additional serial Linux reference runs ...', but L53 already lists the
self-hosted serial Linux standby as the existing reference, so 'additional'
implied a second one. Reword to 'The self-hosted serial Linux reference runs ...'
and mirror in zh L55. Re-record the i18n hash.
Per review: the self-hosted serial standby is not portable evidence — portable
means standard GitHub-hosted capacity without repository-external runner
configuration, which the self-hosted vm-backup/dsh-win-ci pools do not satisfy.
In 2026-07-22-evidence-based-larger-hosted-runners L73, distinguish the two:
standard-hosted compatibility jobs preserve portable evidence, while the
self-hosted serial standby preserves complete-aggregate evidence. Update the en
and zh pair and re-record the i18n hash.
Keep the remaining current-state Agent Notes in line with removing the hosted
serial-linux job (PR #2744), per the implemented-note rule that mechanisms stay
current in the same change that alters them:
- 2026-07-30-web-browser-snapshot-ci-gate (L15/L21): the hosted default-branch
Linux serial job no longer produces the browser cache; pull requests restore
the archived cache without a master producer, and only the self-hosted standby
runs the comparison on master.
- 2026-07-24-web-gui-browser-e2e-lane (L49): no hosted Linux serial producer of
the browser cache remains; the self-hosted standby runs the same gate.
- 2026-07-23-portable-required-pull-request-ci (L19): the serial completeness
check is now provided by the self-hosted vm-backup/dsh-win-ci standby lanes,
with serial-macos as the only disabled hosted serial.
- 2026-07-22-evidence-based-larger-hosted-runners (L17/L53/L73): serial
completeness evidence comes from the self-hosted standby pools; no hosted
Linux serial reference remains.
All four en/zh pairs updated with consistent current-state wording (no deletion
narrative) and i18n hashes re-recorded; note-format still passes.
Address the review findings from the fresh pass on PR #2744:
- 2026-07-21 note L31: the enabled serial references run on the self-hosted
vm-backup/dsh-win-ci pools and the only remaining disabled hosted serial is
serial-macos (macos-latest); removed the stale hosted ubuntu-latest/windows-2025
serial framing and the outdated 'when enabled, serial / windows' clause.
- Drop remaining change-narrative from both notes: L19 (serial / linux, macos)
and the 2026-07-26 caching note L16/L34 now state only current facts without
deletion dates/PR numbers; the no-producer fact has one home (L16). zh.ms'
'直至其过期为逐出' corrected to '直至其被逐出'. Bilingual hashes re-recorded.
- ci.yml TODO notes that re-enabling serial-macos does not restore a Linux
hosted-cache producer and records the seeder-vs-remove decision direction.
- The Playwright restore's failover-skip comment is now self-contained (the
VM's persistent browser cache is warm) instead of pointing at the coveragelane
rationale, which is pnpm-store-specific.
Verification: scripts/ci-workflow.spec.ts passes (12/12), YAML re-parses,
both translation pairs consistent, git diff --check clean.
Apply review feedback on the serial-linux removal (PR #2744):
ci.yml:
- Rewrite the new comments as current-state statements, not change
narrative (dsh-prose-standard): the TODO names serial-macos as the one
remaining disabled hosted serial job; serial-macos's intro and the
self-hosted standby's frozen-archive note no longer narrate the deletion.
- The self-hosted standby's frozen-archive comment states its own reason
(full history to resolve DSH_ARCHIVE_BASE_REF against github.event.before)
instead of referenceing a now-nonexistent hosted serial reference.
- Move the hosted-cache comment above the pnpm restore so it covers both
restore-keys fallback steps, and describe the real consequence (matches the
archived entry until evict, then cold) instead of the false
'cold on a lockfile change'. Restore the per-step failover-skip note.
Agent Note 2026-07-26-pnpm-action-setup-for-symmetric-ci-caching:
- Update the restore-only bullet and the consequences closing line (it
described serial-linux as the active master-push producer of the pnpm store
cache) to state that no master job produces these hosted keys since the
producer was removed; the Problem and Alternatives sections are historical
context and are left unchanged. Re-record the bilingual pair hashes.
Verification: scripts/ci-workflow.spec.ts passes (12/12), YAML re-parses,
both translation pairs consistent, git diff --check clean.
- Translate the zh Agent Note's title and section headings and align
its rail terminology with the established zh READMEs (轨道).
- Disambiguate 'the browser's listener' to WorkspaceBrowser's in the
English note.
- Record the in-flight outside-click exception in the ui-workspace
README (both languages) and the owning workspace-sidebar feature
note, cross-linked to the bug-fix note.
- Add an apps/web real-browser scenario pinning the document-level
bubble the jsdom test cannot replay: one real rail click must leave
the search expanded and focused, and a genuine outside click must
dismiss it afterwards. Negative-controlled against the unguarded
code (fails in 12s on the aria-expanded assertion).
- Register the new e2e file in the host tsconfig face and the client
face's exclude list.
The rail search click flips the shell wide and mounts the outside-click
dismissal listener during its own dispatch; the click then bubbles to
document with the unmounted rail button as its target — outside
searchRoot — so the listener dismissed the search it just opened. The
listener now stays off while the rail gesture is in flight
(searchOnExpand), which already ends exactly when focus lands.
The regression test replays the document-level bubbling order that
fireEvent on the button alone does not exercise.