Fix WriteBack corrupting anchor table when patching verification fields#24
Merged
Conversation
…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
enabled auto-merge (squash)
July 22, 2026 19:13
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>
Closed
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
WriteBacknow safely patches theverified_atandfingerprintfieldsinside an entry's
[anchor]TOML table:[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, andgo test ./... -raceall pass.