Skip to content

refactor: route storeOriginal through fsutil.WriteFileAtomic (iss-79) - #51

Merged
REPPL merged 2 commits into
mainfrom
fix/iss-79-storeoriginal-inline-atomic-write
Jul 13, 2026
Merged

refactor: route storeOriginal through fsutil.WriteFileAtomic (iss-79)#51
REPPL merged 2 commits into
mainfrom
fix/iss-79-storeoriginal-inline-atomic-write

Conversation

@REPPL

@REPPL REPPL commented Jul 12, 2026

Copy link
Copy Markdown
Owner

What

memory ingest's storeOriginal was a fifth inline temp + os.O_EXCL + fsync +
rename durable write that the iss-32 consolidation missed — open-coded (not a
named func), so the name-based canonical-primitive detector could not see it, and
diverging from fsutil.WriteFileAtomic by omitting the parent-directory fsync
and the explicit chmod.

How

  • storeOriginal now routes through fsutil.WriteFileAtomic(target, rawBytes, 0o644), keeping the sources-dir symlink/non-directory os.Lstat guard ahead of
    the write. The orphaned itoa helper (only caller was the removed temp-name
    line) is deleted.
  • Detector-first: TestNoInlineAtomicWriteSequences extends the
    one-canonical-primitive check to flag any non-fsutil file pairing os.O_EXCL
    with os.Rename — the inline-atomic-write signature the name-based regex
    missed. (capture's allocator uses syscall.O_EXCL for a reservation with no
    rename, so it is correctly not flagged.) Watched it flag ingest.go, then pass
    after the reroute.
  • Added TestIngestKeepOriginalWritesSourceCanonically (success path: bytes +
    0644 mode via the canonical primitive).

Behaviour-preserving from the caller's view; strengthens crash-safety.

Review

Correctness: PROMOTE. Security: PROMOTE (target name is a hex hash + safeExt,
no traversal; os.Rename keeps leaf-symlink non-following; symlink-dir guard
retained; adds chmod + parent-fsync hardening).

The correctness review found a sixth inline atomic write —
rules/inject.go SaveState (CreateTemp+Rename, no fsync) — which the
os.O_EXCL-keyed detector does not catch. Filed as iss-82 (route it +
broaden the detector to the CreateTemp idiom) rather than widening this scoped
change; the detector comment documents the gap.

Scope

internal/core/memory/{ingest,writer,memory_test}.go, internal/fsutil/ canonical_test.go, CHANGELOG, ledger (resolves iss-79, files iss-82). Full
make preflight green (build, vet, gofmt, tests, -race).

Part of drain #2. Chain: branched from main; independent of iss-76/iss-73.

Assisted-by: Claude:claude-opus-4-8

REPPL added 2 commits July 12, 2026 22:54
memory ingest's storeOriginal was a fifth inline temp + os.O_EXCL + fsync +
rename durable write that the iss-32 consolidation missed -- it was open-coded,
not a named func, so the name-based canonical-primitive detector could not see
it, and it diverged from fsutil.WriteFileAtomic by omitting the parent-directory
fsync and the explicit chmod.

storeOriginal now routes through fsutil.WriteFileAtomic(target, rawBytes, 0644),
keeping the sources-dir symlink/non-directory guard ahead of the write. The
orphaned itoa helper (its only caller was the removed temp-name line) is deleted.

Detector-first: TestNoInlineAtomicWriteSequences extends the one-canonical-
primitive check to flag any non-fsutil file pairing os.O_EXCL with os.Rename --
the inline-atomic-write signature the name-based regex missed (capture's
allocator uses syscall.O_EXCL for a reservation with no rename, so it is
correctly not flagged). Watched it flag ingest.go, then pass after the reroute.
Added TestIngestKeepOriginalWritesSourceCanonically: --keep-original lands the
source bytes with an explicit 0644 mode via the canonical primitive.

Behaviour-preserving from the caller's view; strengthens crash-safety.

Assisted-by: Claude:claude-opus-4-8
iss-79's storeOriginal reroute lands in this branch. The correctness review
surfaced a sixth inline atomic write -- rules/inject.go SaveState (CreateTemp+
Rename, no fsync) -- which the os.O_EXCL-keyed detector does not catch;
captured as iss-82 (route it + broaden the detector to the CreateTemp idiom)
rather than widening this scoped change.

Assisted-by: Claude:claude-opus-4-8
@REPPL
REPPL merged commit 1075bf2 into main Jul 13, 2026
12 checks passed
@REPPL
REPPL deleted the fix/iss-79-storeoriginal-inline-atomic-write branch July 13, 2026 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant