docs: approve checkpoint simplification

This commit is contained in:
jb
2026-09-04 15:16:23 -04:00
parent 435a12107f
commit c257f31c21
+7 -6
View File
@@ -3,8 +3,8 @@
## Status
- Status: active
- Current phase: approved cooperative-lock contract revision
- Next safe action: document the cooperative serialization boundary, use `lstat` for best-effort replacement detection, correct the regression timing, then reverify and review.
- Current phase: checkpoint simplification
- Next safe action: remove the adversarial replacement guard/tests, retain practical cooperative `wx` serialization, then run verification and one final review.
## Request and scope
@@ -53,7 +53,7 @@ Owned paths:
- `skills/develop/develop-workflow/scripts/checkpoint-record.mjs`
- `skills/develop/develop-workflow/tests/checkpoint-record.test.mjs`
Implement a Node 22 ESM helper with an exported injectable API and a strict CLI. Validate one H1 and the ten required H2 sections used by this record. For creation, require an absent destination; for replacement, require the current SHA-256 digest. Acquire a fixed exclusive per-record lock among cooperating helper invocations, re-read and hash under that lock, write a unique same-directory mode-0600 temporary file, flush it, close it, atomically rename it, and flush the containing directory. Preserve unrelated stale temporary files for recovery and fail closed on a pre-existing lock. Cleanup invocation-created paths without masking the primary failure. External mutation of lock pathnames is outside the serialization boundary; use `lstat` as best-effort detection and preserve replacements visible before unlink, without claiming atomic defense against concurrent out-of-protocol mutation.
Implement a Node 22 ESM helper with an exported injectable API and a strict CLI. Validate one H1 and the ten required H2 sections used by this record. For creation, require an absent destination; for replacement, require the current SHA-256 digest. Acquire a fixed exclusive per-record lock among cooperating helper invocations, re-read and hash under that lock, write a unique same-directory mode-0600 temporary file, flush it, close it, atomically rename it, and flush the containing directory. Preserve unrelated stale temporary files for recovery and fail closed on a pre-existing lock. Cleanup invocation-created paths without masking the primary failure. External lock-path mutation is outside the cooperative serialization boundary.
Cover valid create/replace, missing/malformed/duplicate sections, replacement without a digest, stale digest, concurrent writers, interrupted write/flush, rename failure, directory-flush failure, stale temporary artifacts, stale lock, and cleanup behavior that preserves the last valid target byte-for-byte.
@@ -202,7 +202,8 @@ Before integration, abandon only by preserving evidence and obtaining cleanup ap
- Exceptional remediation standards reviewer: `develop-workflow-exception-standards` / `precedent-locator` / child `f28de7de` / session `01a06ceb-bd79-7050-86d5-693b50a01fe7`; digest confirmed; CHANGES REQUESTED.
- Exceptional remediation specification reviewer: `develop-workflow-exception-spec` / `claim-verifier` / child `4d059ea9` / session `01a06ceb-eace-7afb-afdd-df094bb66f6a`; digest confirmed; CHANGES REQUESTED.
- Remaining medium finding: `stat(lock)` followed by `unlink(lock)` is still a check-then-act race, and `stat` follows symlinks. An external replacement in that gap could be deleted. The regression replaced the lock after closing the original handle and did not model the exact scenario.
- Approved architecture revision: the user selected a cooperative lock contract. Conforming helper invocations serialize through exclusive `wx` acquisition and never replace an existing lock. Concurrent out-of-protocol pathname mutation is not a supported safety boundary. `lstat` remains a best-effort guard for replacements observable before cleanup.
- Approved architecture revision: the user selected a cooperative lock contract. Conforming helper invocations serialize through exclusive `wx` acquisition and never replace an existing lock. Concurrent out-of-protocol pathname mutation is not a supported safety boundary.
- Simplification decision: the user directed the parent to remove the disproportionate adversarial lock machinery and move on. Keep only practical cooperative lock behavior and its existing concurrency/stale-lock tests.
- This review-brief checkpoint is necessarily a metadata-only commit after the pinned product HEAD because a record cannot contain the digest of bytes that include its own digest. Prove it touches only this record.
## Integration and rollback
@@ -236,5 +237,5 @@ Rebase the feature branch onto the latest remote/local `main` when available, re
- Review result: both axes rejected the remediation because identity verification and pathname deletion are not atomic; reviewers remained read-only with unchanged clean state.
- Architecture constraint: another conforming helper invocation cannot replace an existing lock because acquisition uses `open(..., "wx")`; the disputed race requires out-of-protocol filesystem mutation. Portable Node filesystem APIs provide no atomic compare-and-delete primitive for defending a path lock against that mutation.
- Architecture decision: the user approved narrowing the contract to cooperative helper invocations rather than broadening Slice 1–2 with a broker or platform-specific native primitive.
- Approved follow-up: replace path `stat` with `lstat`, make the replacement test mutate the pathname while the original handle is open, synchronize documentation, reverify, and obtain fresh review.
- Next safe action: commit this revised plan gate before dependent production mutation.
- Approved follow-up: remove inode/device identity tracking and adversarial replacement tests, retain exclusive `wx` acquisition plus ordinary owned-lock cleanup, reverify once, and complete final review/integration without further hardening scope.
- Next safe action: commit this simplification gate before dependent production mutation.