Skip to content

Fix WriteBack corrupting anchor table when patching verification fields#24

Merged
quad341 merged 4 commits into
mainfrom
deploy/crn-4dxi-gate
Jul 22, 2026
Merged

Fix WriteBack corrupting anchor table when patching verification fields#24
quad341 merged 4 commits into
mainfrom
deploy/crn-4dxi-gate

Conversation

@quad341

@quad341 quad341 commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Summary

WriteBack now safely patches the verified_at and fingerprint fields
inside an entry's [anchor] TOML table:

  • If a field already has a line, it's updated in place.
  • If a field is missing, it's appended — without corrupting the
    [anchor] table header line that follows.

The previous append path had a slice-aliasing hazard: writing the new
line could silently overwrite part of the surrounding TOML structure
instead of cleanly inserting it.

Testing

Added byte-level tests that assert on the raw file contents (not just
struct equality) covering: first verify (insert), second verify
(update in place), indent preservation on both replace and append, and
a missing-anchor-table error path that writes nothing.

go build, go vet, gofmt, and go test ./... -race all pass.

quad341 and others added 3 commits July 22, 2026 00:28
…5.1)

Replace the full-struct TOML re-encode in Entry.WriteBack() with a
line-based patch that touches only verified_at (top-level) and
anchor.fingerprint -- the two fields verifyCmd ever sets before calling
WriteBack. Every other line of the on-disk frontmatter, including field
order, indentation, and empty collections like `scope = []`, now passes
through byte-for-byte unchanged instead of being dropped or reformatted
on every `cairn verify`.

ParseEntry is refactored to share a new splitFrontmatter helper with
WriteBack rather than duplicating the +++-fence-finding logic. marshal()
and Create() are untouched -- Create still needs a full encode since
there's no prior on-disk text to preserve.

Region slicing uses three-index slice expressions to cap each region's
capacity at its own length, so an append in one region (inserting a new
key) can't silently write through into the next region's shared backing
array.

Adds five byte-level tests (first verify / re-verify / indent
preservation on replace and append / missing-anchor-table error path)
that assert against raw file bytes and line-by-line diffs, since
value-equality checks alone can't distinguish a surgical patch from a
full re-encode.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Documents the 7-criterion deploy gate evaluation for the verified_at
and fingerprint TOML write-back patch (crn-6az.5.1, reviewed crn-mtqa)
ahead of opening the release PR.
@quad341
quad341 enabled auto-merge (squash) July 22, 2026 19:13
@quad341
quad341 merged commit 3070f4f into main Jul 22, 2026
2 checks passed
quad341 added a commit that referenced this pull request Jul 23, 2026
…nches.go (crn-j1uh)

origin/main gained two independent features since this branch forked:
entry.go's own splitFrontmatter/tomlQuote (PR #24) and branches.go's own
ReviewBranch/ListReviewBranches for stale-branch tracking (PR #39, crn-0yv.1).
Both pairs collide with review.go's pre-existing identically-named
declarations once merged.

- tomlQuote: consolidated. entry.go's version is a strict, behavior-compatible
  superset for review.go's validated-input call sites (TopicKey/AnchorType/
  Scope, already passed through ValidatePathSegment); deleted review.go's
  duplicate, zero call-site changes needed.
- splitFrontmatter: renamed to splitFrontmatterForPatch in review.go. Not
  substitutable with entry.go's version -- different input type (string vs
  []byte), different return contract (bool-flag+body vs sentinel-error+
  closeAndBody), and review.go's closing-fence retention is required by
  patchFrontmatterFields for byte-exact surgical reassembly.
- ReviewBranch/ListReviewBranches: renamed to ReviewMergeBranch/
  ListReviewMergeBranches in review.go. branches.go's versions serve the
  librarian sweep's age/SHA-tracked notify-escalate bookkeeping; review.go's
  serve the interactive list/show/merge review flow. Different shapes for
  different concerns, developed independently -- not a merge candidate.

Verified: gofmt, go vet, go build, go test ./... -race -count=1, and
golangci-lint (cache-cleaned) all clean across every package, run from the
module root. Specifically confirmed both ListReviewBranches test families
(branches_test.go's, unchanged, and review_test.go's, renamed) pass side by
side with no cross-talk, and TestMergeReviewBranchRejectsInvalidAnchorType /
TestTomlQuoteEscapesBackslashAndDoubleQuote still pass against the shared
entry.go implementation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
quad341 added a commit that referenced this pull request Jul 23, 2026
…nches (#40)

* Add cairn review CLI verb: list/show/merge for shared-tier review branches

Implements AF1/AF2 of crn-xw3's design: the review half of the propose/
review flow crn-419's remember command already writes one side of.
review list derives tier from the changed entry file's path (never the
branch name); review show renders the diff plus a parsed Entry so a
reviewer can inspect real content before any merge; review merge
surgically patches only reviewer-specified frontmatter fields, blocks
on an obvious secret pattern unless overridden, --no-ff merges with the
"librarian: merge <branch> — <title> (<bead>)" convention, deletes the
branch, and reindexes — aborting cleanly with no partial state on any
failure up through the merge itself.

Refs crn-ffm.

* fix(cairn): validate --anchor-type in review merge (crn-8emp)

opts.AnchorType flowed straight into tomlQuote unvalidated, unlike
TopicKey/Scope. An embedded newline produced invalid TOML that merged
successfully before Reindex choked on it, corrupting the default
branch and breaking every store read path (IterEntries) until
hand-fixed. Validate AnchorType via ValidatePathSegment in
MergeReviewBranch, matching the existing TopicKey/Scope pattern, with
a regression test pinning the newline-injection case reported in
review.

Addresses the blocking finding from cairn/reviewer's crn-8emp review
(mail gm-wisp-9h17fbl).

* fix(cairn): resolve review.go symbol collisions with entry.go and branches.go (crn-j1uh)

origin/main gained two independent features since this branch forked:
entry.go's own splitFrontmatter/tomlQuote (PR #24) and branches.go's own
ReviewBranch/ListReviewBranches for stale-branch tracking (PR #39, crn-0yv.1).
Both pairs collide with review.go's pre-existing identically-named
declarations once merged.

- tomlQuote: consolidated. entry.go's version is a strict, behavior-compatible
  superset for review.go's validated-input call sites (TopicKey/AnchorType/
  Scope, already passed through ValidatePathSegment); deleted review.go's
  duplicate, zero call-site changes needed.
- splitFrontmatter: renamed to splitFrontmatterForPatch in review.go. Not
  substitutable with entry.go's version -- different input type (string vs
  []byte), different return contract (bool-flag+body vs sentinel-error+
  closeAndBody), and review.go's closing-fence retention is required by
  patchFrontmatterFields for byte-exact surgical reassembly.
- ReviewBranch/ListReviewBranches: renamed to ReviewMergeBranch/
  ListReviewMergeBranches in review.go. branches.go's versions serve the
  librarian sweep's age/SHA-tracked notify-escalate bookkeeping; review.go's
  serve the interactive list/show/merge review flow. Different shapes for
  different concerns, developed independently -- not a merge candidate.

Verified: gofmt, go vet, go build, go test ./... -race -count=1, and
golangci-lint (cache-cleaned) all clean across every package, run from the
module root. Specifically confirmed both ListReviewBranches test families
(branches_test.go's, unchanged, and review_test.go's, renamed) pass side by
side with no cross-talk, and TestMergeReviewBranchRejectsInvalidAnchorType /
TestTomlQuoteEscapesBackslashAndDoubleQuote still pass against the shared
entry.go implementation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* chore: release gate PASS for cairn-review-cli-verb

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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