Repository navigation
Pin the identity anchor in a fixture and re-derive machine moves - #372
Merged
MaxGhenis merged 8 commits intoOct 20, 2026
Merged
Conversation
The identity anchor lived as a literal in test_identity_uuid_map_matches_reviewed_anchor, so only a hand edit of the test could move it. Every first observation that enriches a docket placeholder or mints an identity moves it, so each such resolver append (chronicle#361, #369) merged with Arch checks red and held every other pull request into this branch until a curation PR (#363, #371) moved the literal by hand. The pin now lives in tests/fixtures/series_catalog/identity_anchor.json, unchanged (d5b88530...). A curator still moves it with move null and a dated entry in the test's history. A machine may also move it, recording from_sha256 and one event per identity tuple it changed; build_series_catalog.identity_anchor_problems re-derives from_sha256 from the current catalog and those events and accepts only mints of full identities under fresh UUIDs and enrichments of entity-free placeholders under the same UUID and concept. A remint, supersede, retire, entity change on a full identity or any unrecorded change is reported. Property tests: any sanctioned append recorded as a move is accepted, and each of eleven ways a move can misstate its append is reported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 1 (in-session Opus) showed identity_anchor_problems accepts a self-consistent record with a false origin: remint (u_old, a) as (u_new, a), record "mint u_new" with from_sha256 = the current catalog minus u_new, and the record re-derives cleanly. The function only sees the current catalog, so it cannot know where the branch was. identity_anchor_continuity_problems requires a move that changes the pin to start from the base commit's pin, and refuses a mint whose UUID the base registry already holds (a revive is a curator's call). A new Arch checks step, "Identity anchor move continues the base pin", runs it against the same comparison base as the registry append-only step. The fixture comment and docstring now say exactly what each check proves. Also: a non-string event kind is reported instead of raising TypeError. Tests: the review's forged-origin case, a property that a move continues the base exactly when it starts from the base's pin, the CLI, and malformed kinds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 2 (hard tier, served by Opus 5.5 with the Codex lanes held): - P3-1: the digest covers the catalog's tuples as a list, duplicates included, while identity_anchor_problems undoes events on sets, so a repeated row or a UUID on two rows could hide a change. A machine move over such a catalog is now reported. - P3-2: a mint that repeats an identity the prior catalog already binds (the same concept, geography and entity under a second UUID) is reported. - P3-8: the continuity step leaves a new branch's first push to its pull request run (no comparison base of its own; a branch cut before the latest machine move would compare an older move with today's pin), and the CLI treats a missing identity anchor fixture as nothing to check. - P3-11: the soundness property is parametrized over its 13 mutations, so one Hypothesis can never exercise fails; the append generator binds each identity once, as a real catalog does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 3 (hard tier, Opus 5.5), P3-B: two mints of one identity in one move, or a placeholder enriched onto an identity another row already binds, left the prior catalog's identities untouched and so passed the mint-collision check. A machine move now requires every identity in the current catalog to be bound once (real catalogs are: 221 rows, 221 identities at every commit checked). Two new parametrized mutations cover both cases; each fails without the check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 4 nit: with rows, UUIDs and identities unique in the current catalog, the mint-reuse and mint-collision checks cannot fire; they stay as a guard in case the uniqueness rule is ever relaxed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
marked this pull request as ready for review
October 20, 2026 15:56
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.
This is the Chronicle half of the fix for resolver appends merging past a red required "Arch checks". The Thesis half is ThesisInstitute/thesis#377: the resolver writes provable curation into its own proposals and awaits Arch checks. Land this PR first; until it lands, #377 cannot move the anchor and reports it as curation still needed.
Why
The Thesis resolver's admin token merges on two checks, Append gate and Trusted base append gate. Branch protection on
codex/thesis-ledger-factsalso requires Arch checks, butenforce_adminsis off, so nothing stops the merge. I went through all 28 resolver append PRs (07-10 to 10-19):Since the August catalog fix, every one of these failures came from two curation tests:
test_identity_uuid_map_matches_reviewed_anchor.The anchor moves on every first observation that enriches a docket placeholder or mints an identity. It lived as a literal in the test, so only a hand-edited curation PR could move it (#363, #371). It also cannot move before the rows exist, because it pins the post-append digest.
What
tests/fixtures/series_catalog/identity_anchor.jsonholds the pin, unchanged atd5b88530…, and amovefield.move: nullmeans a curator pinned it, as before, with a dated entry in the test's comment history.by,run_url,from_sha256andevents. Each event is amintor anenrichwith itsplaceholder_geography.build_series_catalog.identity_anchor_problemsre-derivesfrom_sha256from the current catalog and the recorded events. It accepts only:_plan_enrichment).from_sha256, anything else is reported: a remint, supersede, retire, entity change on a full identity, unrecorded change or unsorted events.from_sha256itself is tied to the base. The test sees only the current catalog, so a self-consistent record with a false origin would pass it. A new Arch checks step, "Identity anchor move continues the base pin", runsidentity_anchor_continuity_problemsagainst the same comparison base as the registry append-only step. It requires a move that changes the pin to start from the base's pin, and refuses a mint whose UUID the base registry already holds (bringing a retired UUID back is a revive, a curator's call).Invariants (property-tested)
56bb47bc…→b06bf665…with the five DoD enrichments Fold the 2026-10-17 DoD first prints: review fy2026 strips, move the anchor #363 listed. Catalog 7adcc72→61475bf8 (Record 5 first-print observation(s) via resolve_pending.py #369) givesb06bf665…→d5b88530…with the five enrichments Fold the 2026-10-19 USAspending first prints: review fy2026 strips, move the anchor #371 listed.identity_anchor_problemsaccepts both.Review round 1 (in-session Opus)
Review round 2 (hard tier, served by Opus 5.5)
Review round 3 (hard tier, Opus 5.5)
Review rounds 4 and 5 (hard tier, Opus 5.5): APPROVE WITH NITS
The mint-reuse and mint-collision checks are marked defensive, since the uniqueness rule makes them unreachable. Round 5 confirmed this at ad7f54c, with no P1 or P2.
Verification
test_doctests_pass,test_committed_catalog_is_current_and_validand the fixture well-formedness test pass (7 passed). The full file runs in Arch checks on this PR.ruff: no new findings against the base.No ledger bytes change.
🤖 Generated with Claude Code