Skip to content

chore: track current tool releases; showcase redstamp 0.5.1 audit truncation-detection#25

Merged
askalf merged 1 commit into
masterfrom
chore/track-tool-releases-audit-truncation
Jul 16, 2026
Merged

chore: track current tool releases; showcase redstamp 0.5.1 audit truncation-detection#25
askalf merged 1 commit into
masterfrom
chore/track-tool-releases-audit-truncation

Conversation

@askalf

@askalf askalf commented Jul 16, 2026

Copy link
Copy Markdown
Owner

chore: track current tool releases; showcase redstamp 0.5.1 audit truncation-detection

Bump the three pinned tools to their current vetted master heads:

  • @askalf/redstamp -> v0.5.1 (security release: audit tail-truncation detection,
    writeRoots confinement, constant-time daemon token)
  • @askalf/truecopy -> latest master
  • @askalf/strongroom -> latest master

redstamp 0.5.1 gives its hash-chained audit the same tail-truncation protection
strongroom already has via its HMAC tip: a valid chain PREFIX still verifies, so
lopping off the newest verdicts slipped a bare verify(); pinning the head in a
checkpoint (verifyAuditFile(path, { head, count })) catches it. The composed gate
already holds { head, count } in memory as it records, so the fourth-guarantee
demo/test now shows this end-to-end.

  • test/audit.test.mjs: +1 test — tail-truncation caught against the gate's checkpoint
    while the bare chain waves the prefix through.
  • demo/audit-demo.mjs: adds the truncation beat (edit-detection unchanged).
  • README: the "fourth guarantee" section now covers tail-truncation, no longer
    crediting it to strongroom alone.

No tool-surface change: dump-tools --check + truecopy gate both clean; 17/17 tests,
all demos pass.

…ncation-detection

Bump the three pinned tools to their current vetted master heads:
- @askalf/redstamp  -> v0.5.1 (security release: audit tail-truncation detection,
  writeRoots confinement, constant-time daemon token)
- @askalf/truecopy  -> latest master
- @askalf/strongroom -> latest master

redstamp 0.5.1 gives its hash-chained audit the same tail-truncation protection
strongroom already has via its HMAC tip: a valid chain PREFIX still verifies, so
lopping off the newest verdicts slipped a bare verify(); pinning the head in a
checkpoint (verifyAuditFile(path, { head, count })) catches it. The composed gate
already holds { head, count } in memory as it records, so the fourth-guarantee
demo/test now shows this end-to-end.

- test/audit.test.mjs: +1 test — tail-truncation caught against the gate's checkpoint
  while the bare chain waves the prefix through.
- demo/audit-demo.mjs: adds the truncation beat (edit-detection unchanged).
- README: the "fourth guarantee" section now covers tail-truncation, no longer
  crediting it to strongroom alone.

No tool-surface change: dump-tools --check + truecopy gate both clean; 17/17 tests,
all demos pass.

@sprayberry-reviewer sprayberry-reviewer left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review from the Sprayberry Labs fleet code reviewer (sprayberry-reviewer bot — independent, gating).

Verdict: no blocking issues found — approving.


What I checked

1. SHA pin consistency — package.json ↔ package-lock.json (root dep ↔ node_modules resolved)

All three bumps are coherent across both files:

Package New SHA (package.json / lock root / lock node_modules)
@askalf/redstamp 27c26851e175045a3e274042c96760cf52dce9da × 3 ✓
@askalf/strongroom 43c9ca600ced5f9acc755590bc324e95764a5195 × 3 ✓
@askalf/truecopy 951460e003ab16ef86ea5f297c6523c09b4fba4e × 3 ✓

The overrides field in package.json pins the redstamp transitive dep used by strongroom and truecopy — unchanged, correct.

2. New test logic — test/audit.test.mjs (lines 70–97)

Traced the full execution path:

  • runTrilogy() always produces exactly 10 in-memory audit entries across its 4 beats (4+1+2+3). audit.flush(trailPath) writes them all to disk. audit.entries.at(-1) is safe — 10 entries guaranteed.
  • Checkpoint is captured from in-memory state before disk tampering — correctly models an in-process gate holding state an on-disk attacker can't reach.
  • lines.length >= 3 precondition: with 10 entries on disk, dropping 2 leaves 8 — the bare chain remains internally valid (each link's prev still matches its predecessor), so verifyAuditFile(trailPath).ok === true holds. The >= 3 floor is conservative but sound.
  • The checkpoint assertion caught.reason === 'truncated' is the correct discriminant for the new redstamp 0.5.1 { head, count } verification path.

3. Demo logic — demo/audit-demo.mjs (lines 71–104)

const fresh = runTrilogy() correctly starts a new vault in a fresh tmpdir (each runTrilogy() call sets KEEPER_HOME to its own isolated dir). The demo's self-check at lines 93–96:

if (!barePrefix.ok || vsCheckpoint.ok || vsCheckpoint.reason !== 'truncated') {
  console.error('demo failed: tail-truncation was not caught against the checkpoint');
  process.exit(1);
}

…correctly fails the demo if (a) the bare chain didn't pass the prefix (unexpected), (b) the checkpoint didn't catch it (unexpected), or (c) the reason string changed. Logic is right.

4. CI

All four checks pass: test (17/17), verify pinned tool surface, CodeQL, analyze (javascript-typescript).

5. README

Documentation accurately describes the tail-truncation scenario, the verifyAuditFile(path, checkpoint) API, and the in-memory checkpoint model. No misleading claims.


What's good

The fourth-guarantee story is now complete: edit → caught, mid-log deletion → caught, tail-truncation → caught (with checkpoint). The design correctly puts the checkpoint in the in-process gate (not on disk), so the only tamper surface the attacker controls — the JSONL file — can't defeat it. The test exercises all three branches cleanly and the demo self-checks its own invariants.

@askalf
askalf merged commit ff2bebe into master Jul 16, 2026
4 checks passed
@askalf
askalf deleted the chore/track-tool-releases-audit-truncation branch July 16, 2026 21:25
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.

2 participants