You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Tracking S4a: guarded write CAS core with per-path FIFO chain #1399
Tracking issue for the S4a PR (branch feat/guarded-write-s4a; PR to be opened after review).
Part of the file-write safety series — plan: easonLiangWorldedtech/Zoo-Code#33, epic: #1375. Item: S4a — Guarded write CAS core. Stacks on #1383 (S1 version tokens), #1394 (S2 observation registry), and #1395 (S3 atomic publish) — the branch is built on all three; S4b wires it into the save paths.
Scope
New src/core/tools/guardedWrite.ts: a compare-and-swap layer over the S1/S2/S3 primitives. Decision table per absolute path:
unobserved + absent → createIfAbsent
unobserved + present → fail (file not read yet — read the file, then retry), forcing the model to re-read
observed + absent → createIfAbsent
observed + present → replaceIfVersion (version mismatch → stale fail: stale version — re-read the file, then retry)
Typed error classes carrying the exact remediation texts; per-absolute-path tail-promise FIFO chain (in-process, no lockfile) so concurrent writes to the same path serialize and different paths stay parallel.
Pure core module: no tool wiring, no DiffViewProvider changes (that is S4b).
Acceptance
Every decision-table row has a deterministic unit test, including both exact remediation strings
Same-path writes serialize (FIFO); cross-path writes run in parallel
Uses only the existing S1 (versionToken), S2 (ObservationRegistry), S3 (safeWriteText) APIs — no new deps, no lockfiles
CI green (ubuntu unit-test gate), 100% codecov patch coverage
The four production deferrals from #1405, as rows on this tracker (lane s3-1395, 2026-11-09T19:11:50ZZ)
This tracker has zero comments, and four production rows from #1405 were owed here as rows rather than as thread replies. They are the rows whose answers say deferred with the cost named, and the cost is the headroom: 497 of 500 counted executable lines, head 8186900, PR base 73931fe, mergeBase 73931fe (the two are the same commit here), 128 selectors, selectorsHash 1607fe96287f443b, read in C:/work/Zoo-Code-fork/wt-s3-1405 which sits at that head with 0 porcelain rows.
row 4509757215 - src/utils/safeWriteJson.ts:487 (f9073dcd64e9 at 8186900bfc) - Minor, data integrity. New-path race between createTempFilePath and openSync. Agreed on the mechanism, deferred to a follow-up unit of feat(tools): guarded write CAS core with per-path FIFO chain (S4a, #1375) #1405. Our rows 4509875370, 4515846457.
row 4509757220 - src/utils/safeWriteJson.ts:494 - Minor, data integrity. The stage fd is reopened by _flushFileToDisk at :531-542, so any fix has to carry that constraint. Our rows 4509875636, 4515846842.
row 4509757226 - src/utils/safeWriteJson.ts:497 - Major, security. Publication ordering: stage at 0o600 then apply the target mode, versus publishing the mode the target already has. This one wants a ruling, not a patch - option (a) as first stated does not survive the Windows measurement recorded in 4510022724. Our rows 4509875902, 4510022724, 4515847254.
row 4510030261 - src/core/config/importExport.ts:360 - Minor, stability. The live half of the notification pair: webviewMessageHandler awaits exportSettings... and the refusal path escapes the notification. Our rows 4510045316, 4515848805.
The fifth open production question on #1405 is row 4504216100 (src/utils/safeWriteJson.ts:225), and it is not a deferral but an escalation: the lock-key contract - link name, resolved referent, or target path - is a design decision for the code owner, filed upstream as #2375, and a third unit is already writing against the current shape. Our rows on it: 4504471311, 4509442284, 4509807777, 4509827755, 4515844907.
What is not owed here: five test-only rows on #1405 were accepted and are recorded on #1991 (4509757197, 4509757204, 4509757233, 4510030249, 4510030255), and row 4509757207 is satisfied at 8186900bfc. Nothing pushed, nothing resolved, nothing re-requested by this lane; #1399's own branch state is untouched by this comment.
— lane s3-1395. Measurement and artefacts as described in the #1991 comment of the same timestamp.
Activity
fix(tools): use the exact Zoo-Code-Org#1399 remediation texts and cre…
easonLiangWorldedtech commentedon Nov 9, 2026
The four production deferrals from #1405, as rows on this tracker (lane s3-1395, 2026-11-09T19:11:50ZZ)
This tracker has zero comments, and four production rows from #1405 were owed here as rows rather than as thread replies. They are the rows whose answers say deferred with the cost named, and the cost is the headroom: 497 of 500 counted executable lines, head 8186900, PR base 73931fe, mergeBase 73931fe (the two are the same commit here), 128 selectors, selectorsHash 1607fe96287f443b, read in C:/work/Zoo-Code-fork/wt-s3-1405 which sits at that head with 0 porcelain rows.
src/utils/safeWriteJson.ts:487(f9073dcd64e9at8186900bfc) - Minor, data integrity. New-path race betweencreateTempFilePathandopenSync. Agreed on the mechanism, deferred to a follow-up unit of feat(tools): guarded write CAS core with per-path FIFO chain (S4a, #1375) #1405. Our rows 4509875370, 4515846457.src/utils/safeWriteJson.ts:494- Minor, data integrity. The stage fd is reopened by_flushFileToDiskat :531-542, so any fix has to carry that constraint. Our rows 4509875636, 4515846842.src/utils/safeWriteJson.ts:497- Major, security. Publication ordering: stage at0o600then apply the target mode, versus publishing the mode the target already has. This one wants a ruling, not a patch - option (a) as first stated does not survive the Windows measurement recorded in 4510022724. Our rows 4509875902, 4510022724, 4515847254.src/core/config/importExport.ts:360- Minor, stability. The live half of the notification pair:webviewMessageHandlerawaitsexportSettings...and the refusal path escapes the notification. Our rows 4510045316, 4515848805.The fifth open production question on #1405 is row 4504216100 (
src/utils/safeWriteJson.ts:225), and it is not a deferral but an escalation: the lock-key contract - link name, resolved referent, or target path - is a design decision for the code owner, filed upstream as #2375, and a third unit is already writing against the current shape. Our rows on it: 4504471311, 4509442284, 4509807777, 4509827755, 4515844907.What is not owed here: five test-only rows on #1405 were accepted and are recorded on #1991 (4509757197, 4509757204, 4509757233, 4510030249, 4510030255), and row 4509757207 is satisfied at
8186900bfc. Nothing pushed, nothing resolved, nothing re-requested by this lane; #1399's own branch state is untouched by this comment.— lane s3-1395. Measurement and artefacts as described in the #1991 comment of the same timestamp.