Development record
Sixth divergent inline atomic write, and a detector-coverage gap: internal/core/rules/inject.go SaveState open-codes a durable write as os.CreateTemp + Write + Close + os.Rename with NO fsync and no parent-dir fsync -- weaker crash-safety than even the storeOriginal inline write iss-79 consolidated. It is not routed through fsutil.WriteFileAtomic, and the iss-79 detector (TestNoInlineAtomicWriteSequences) keys on os.O_EXCL + os.Rename so it does NOT flag the CreateTemp+Rename idiom. Fix: route SaveState through fsutil.WriteFileAtomic, and broaden the canonical-primitive detector to also flag inline os.CreateTemp + os.Rename sequences (watch it flag inject.go, then drain). Deferred from iss-79 to keep that change scoped to storeOriginal. Acceptance corpus: inject.go SaveState; the broadened detector must flag it before the fix and pass after. Found during iss-79 correctness review.
Sixth divergent inline atomic write, and a detector-coverage gap: internal/core/rules/inject.go SaveState open-codes a durable write as os.CreateTemp + Write + Close + os.Rename with NO fsync and no parent-dir fsync -- weaker crash-safety than even the storeOriginal inline write iss-79 consolidated. It is not routed through fsutil.WriteFileAtomic, and the iss-79 detector (TestNoInlineAtomicWriteSequences) keys on os.O_EXCL + os.Rename so it does NOT flag the CreateTemp+Rename idiom. Fix: route SaveState through fsutil.WriteFileAtomic, and broaden the canonical-primitive detector to also flag inline os.CreateTemp + os.Rename sequences (watch it flag inject.go, then drain). Deferred from iss-79 to keep that change scoped to storeOriginal. Acceptance corpus: inject.go SaveState; the broadened detector must flag it before the fix and pass after. Found during iss-79 correctness review.
Frontmatter
| id | iss-82 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | minor |
.abcd/work/issues/resolved/iss-82-rules-inject-savestate-inline-atomic.md
open on GitHub ↗ · commit history ↗
mentions1
- iss-79fifth divergent atomic write: internal/core/memory/ingest.go storeOriginal (~:806) is an inline temp(.memtmp,O_EXCL)+fsync+rename durable write that iss-32's consolidation left untouched — it is inline, not a named func, so TestNoNonCanonicalAtomicWritePrimitives (name-based) cannot catch it, and it was outside iss-32's named 4-copy corpus. It differs from canonical fsutil.WriteFileAtomic: no parent-dir fsync, no explicit chmod. Consolidate it onto fsutil.WriteFileAtomic(target, material.rawBytes, 0644) (keeping the pre-existing sources-dir symlink guard), OR extend the canonical-primitive detector to catch inline temp+rename sequences. Safe today (has its own symlink guard); this is a completeness/consistency follow-up.