Skip to content

Freeze an authored snapshot: the repository commit root becomes a corpus manifest - #10560

Merged
briansrls merged 15 commits into
mainfrom
scm-commit-manifest-root
Sep 5, 2026
Merged

briansrls merged 15 commits into
mainfrom
scm-commit-manifest-root

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

gunbc.scm.merge was model-blocked, and #10522 settled the design. This is the first consequence of that ruling: a repository commit now freezes an authored snapshot rather than a semantic root.

Why the root had to move

#10522 §5 ruled that the authored snapshot is authoritative for what was authored, and structural interpretation is a derived view over it. A semantic root cannot hold that position:

  • A comment-only edit is invisible to it. §4c erases annotations from the semantic projection, so two authored snapshots differing only in a comment share one graph.
  • Malformed or not-yet-ingestible source has no representation at all — precisely the corpora a source-control system must still be able to freeze.

gunbc.scm.object_store had already said it outright: a corpus manifest "is the thing a repository commit freezes." The model anticipated this; only the commit carrier had not followed.

The refusals are re-aimed, not deleted

The wrong-kind population did not shrink when the subject moved — it swapped members. RepositoryCommitMintRootIsCorpusManifest becomes RepositoryCommitMintRootIsSemanticNode, and the authored-source arm keeps its meaning because a bare file is not a snapshot either. All three non-success arms of find_corpus_manifest_record stay distinct: folding a wrong-kind occupant into "missing" would report an occupied locator as empty.

The witness pair inverted rather than being renamed — env_a_commit_root_that_is_a_node_mints was correct while a commit froze a semantic root and is wrong now. It is env_a_commit_root_that_is_a_semantic_node_refuses, with a new positive control that a manifest root mints, so neither refusal is satisfied by a mint that refuses everything.

CorpusManifestTarget is new: the mint needs a requirement-side input before it can establish whether the store satisfies it. Publicly constructible (stating a requirement forges nothing), no target-to-reference conversion, and no Resolved | Unresolved state inside it — whether a store satisfies a requirement is an observation, and find_corpus_manifest_record is its sole authority.

Consumers moved with it

  • checkout_repository_at recovers the authored corpus instead of reconstructing a Node. Reconstructing a program would have required successful semantic ingestion of every file, making a repository with one malformed file uncheckoutable — the exact thing the manifest exists to prevent. The semantic checkout keeps its node-level contract untouched.
  • logged_commit_standing resolves manifests. Its success arm renders an empty suffix rather than claiming checkoutability, because holding the snapshot says nothing about holding the sources it names.
  • render imported two deleted log arms — production breakage the fixture census surfaced.

Three questions stay separate and each is answered where it is observed: snapshot designation (the mint), current recoverability (checkout), publication admission (the publishing verb, not yet built).

Versioning

Format v3 → v4, writer and reader renamed with it, because the member is still spelled root while its subject changed — a reader accepting both would resolve a v3 root against the manifest population and answer wrong-kind for a document that was never malformed.

The identity rule stays scm-object-identity-v2: hashing did not move. The semantic-closure format did not move either.

v3 is refused by name as retired, distinct from "unrecognized", with standing LoadUnsupportedProtocol and its own load specimen. There is deliberately no v3 reader: a v3 commit root designates a semantic node, and deriving a manifest from one would fabricate the authored bytes the projection discarded — comments, original placement, anything that did not survive ingestion. Existing v3 images become unreadable by this build, and that is stated rather than papered over.

Evidence

Envelope 69/69 · checkout 11/11 · status 7/7 · load 8/8 · cli 20/20 · render 11/11 · object_table 21/21 · commit_closure 30/30.

Two controls exist because review traced counterexamples through the committed assertions:

  • The recovered corpus is asserted by content. Every successful checkout previously bound corpus: _, so a mutation changing only the success arm to return corpus: [] would have left the suite green while every checkout returned nothing. The control asserts population, paths and contents, over a snapshot including source this build cannot ingest and a genuinely empty file — so an empty source and an empty corpus cannot read alike.
  • A partial snapshot survives representation. The prior encode control checked success and then inspected the input store, which an encoder that dropped the entry would satisfy unchanged. One partial snapshot now drives both consumers: encoding succeeds, decoding preserves the commit, both paths and the missing source's exact locator, checkout refuses for that source naming its path and locator, and supplying it recovers the corpus without moving the snapshot designation.

A manifest naming an absent source deliberately does not refuse at encode. A historical commit may legitimately identify a snapshot whose sources are partially unavailable; refusing there would broaden the codec's partial-corpus policy by accident. The deficit is reported where it is observed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

gunbc-ci-auto-heal and others added 6 commits September 5, 2026 11:02
Production side of the manifest-root cut, ruled in gunbc#10522 section 5 and
scoped by the designated SCM reviewer.

RepositoryCommit.root becomes CorpusManifestObjectRef. The mint takes a new
CorpusManifestTarget -- a requirement, publicly constructible, with no
target-to-reference conversion and no Resolved/Unresolved state inside it, since
whether a store satisfies a requirement is an observation and find_corpus_manifest_record
is its sole authority. The three refusals are RE-AIMED rather than deleted: a
semantic node occupying a commit root is now the wrong kind, and all three
non-success arms stay distinct so an occupied locator is never reported as empty.

Consumers move with it. logged_commit_standing resolves manifests, and its
success arm is renamed LoggedCommitManifestHeld and annotated to say it does NOT
establish that the corpus is recoverable. checkout_repository_at no longer
reconstructs a Node: a repository checkout now recovers the AUTHORED corpus, so a
repository holding a malformed or not-yet-ingestible file stays checkoutable,
which is the whole point of freezing a manifest. The semantic checkout keeps its
node-level contract untouched.

Format v3 -> v4 with the writer and reader renamed to match, because the member
is still spelled root while its subject changed. The identity rule stays
scm-object-identity-v2: hashing did not move. v3 is refused BY NAME as retired
rather than falling into unrecognized, and there is deliberately no v3 reader --
deriving a manifest from a semantic root would fabricate authored bytes the
projection discarded.

Fixtures not yet updated; that census is the next commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
render imported two log arms that no longer exist, which the fixture census
surfaced -- production breakage I had missed. Its held-row suffix now renders
empty rather than claiming checkoutability, because LoggedCommitManifestHeld
says the store holds the SNAPSHOT and not the sources the snapshot names.

The log fixture stores a real authored source and a real manifest naming it,
rather than branding a locator: the standing arms discriminate on what the store
actually holds, so a manifest over a dangling source would make the held arm
unreachable and the suite would pass without exercising it. Its collision arms
carry the identity the store reported instead of a fabricated zero.

Also renamed encode_repository_v3_over_table with its caller.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
Same fixture shape as the log witness: real authored bytes and a real manifest
naming them, so the checked-out commit designates something the store actually
holds. 7/7 passing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
…overability control

The verb's refusal set changed shape, so the fixture could not just be renamed.
CheckoutProgramUnreconstructable split into three snapshot-kind refusals plus
CheckoutCorpusUnrecoverable, because 'this commit does not name a snapshot' and
'this snapshot's sources are not all here' have different owners.

The new control is the one worth having: a commit naming a manifest the store
HOLDS, whose named source was never stored. Reporting it as a missing snapshot
would send the operator to repair the commit rather than fetch the source;
reporting success would hand back a corpus with a file silently absent. It
asserts the path, not merely the arm. 9/9 passing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
68/68 passing.

The wrong-kind pair INVERTED rather than being renamed, which is the change made
executable. env_a_commit_root_that_is_a_node_mints asserted that a node root
mints -- correct while a commit froze a semantic root, wrong now that it freezes
an authored snapshot. It is now env_a_commit_root_that_is_a_semantic_node_refuses,
naming the arm and the locator, with a new positive control that a manifest root
mints so neither refusal is satisfied by a mint that refuses everything.

The uncontained-target fixture changed shape for a measured reason, recorded in
place. Grafting a MANIFEST root without the sources it names produces a document
that ENCODES -- I measured this rather than assuming -- and that is correct: a
manifest legitimately names sources a store may not hold, and refusing there
would broaden the codec's partial-corpus policy by accident. Unrecoverability is
reported where it is observed, at checkout. So the fixture keeps the claim's real
subject, an uncontained semantic-node edge, by grafting a node whose children
were never copied while the commit root stays a held snapshot.

Also: the decode-cause helper gained the retired-format arm.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
The empty-repository fixture moves to v4 as the positive control, and a v3
document becomes its own specimen asserting RepositoryFormatRetired by name,
mirroring the frozen-v1 pattern already in this file. It asserts the FOUND tag
and the standing, not merely that something refused: a classifier answering
LoadUnsupportedProtocol for everything would satisfy a bare refusal claim, and
the malformed-document control beside it is what stops that reading.

8/8 passing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SCOPED DRAFT RULING at 9944259 — partial authored corpus encoding. COMMENT only, not approval or a completed source/census review. The live PR remains draft. I have not merged, modified source, executed witnesses, repeated the author's measurement, or audited the remaining Rust/generated bindings or CI.

RULING: KEEP THE ENCODER'S EXISTING PARTIAL-CORPUS POLICY.

I agree with the reported manifest-with-unavailable-sources result. A held manifest with a genuinely absent AuthoredSourceTarget may remain representable in the repository codec. That is not a claim that its sources are currently recoverable, and not admission for the ordinary local commit/publication command to discard source bytes. Requiring all manifest sources here merely to preserve a specimen whose root changed kind would introduce a new codec restriction rather than repair the root transition.

I inspected encode_repository_checked and its root classifier, the repository-envelope patch, the new repository checkout/recovery functions, the current checkout witness module, the relevant envelope witnesses, and the log standing/render change. The encoder still derives separate semantic-edge and manifest-source censuses. It refuses semantic edges at either wrong kind and absent semantic targets; it separately refuses manifest sources occupied by a node or manifest. It does not treat the manifest-source absent population as a codec refusal. Commit roots themselves still must resolve to a held manifest: absence of that root is not covered by permission for absent source entries.

The distinction remains:

  • manifest root missing: no held snapshot to designate;
  • manifest root held, source missing: exact designation can be encoded, but complete corpus recovery is unavailable;
  • manifest source at the wrong kind: occupied locator, not a fetchable absence;
  • all sources held: recoverable authored content regardless of semantic ingestibility.

CHECKOUT CONSUMES THE RIGHT RELATION.

checkout_repository_at first resolves the requested commit, then its manifest, then every required authored-source entry. CorpusEntrySourceMissing/IsSemanticNode/IsCorpusManifest retain path and locator and reach CheckoutCorpusUnrecoverable with the requested commit reference. recover_corpus returns a refusal when its accumulator has a refusal; the accumulated prefix is not exposed as CorpusRecovered. RepositoryCheckedOut and the new selection are constructed only after CorpusRecovered. No ingestion is required on this route, and this operation remains a pure returned value, not filesystem materialization or durable publication.

LoggedCommitManifestHeld is correspondingly only a manifest-presence observation. Its empty render suffix is not evidence that sources are present; any consumer of commit_log_is_fully_held must preserve that same limited meaning. Do not promote this helper to local publication admission merely because its name contains fully_held.

THE REWRITTEN UNCONTAINED-TARGET FIXTURE HAS THE RIGHT SUBJECT.

scm_env_an_uncontained_target_refuses_to_encode_and_names_it now keeps a held authored snapshot as the commit root and separately grafts a semantic node without its children. It still drives the repository's semantic-edge completeness refusal and checks that the returned target belongs to that missing-target population. The node need not be the commit root: the existing repository guard covers the stored semantic population. I am not requesting that this fixture again refuse a partial authored corpus.

TWO EVIDENCE GAPS TO ADDRESS WHILE THE PR IS STILL DRAFT.

E1 — The existing partial-source encode control does not observe the encoded population. scm_env_a_manifest_source_this_store_lacks_is_not_a_refusal checks only the encode cause tag and then calls find_corpus_manifest_record on fixture.store, the original input. It constructs no repository commit and never decodes the returned value. An encoder that reports success while losing the uncontained source entry can therefore satisfy this particular control. This is a source-traced counterexample to that control, not an executed mutation or a claim that the entire suite would pass it.

Extend the evidence through the actual boundary: construct an exact source and a manifest naming it, with the source omitted from the published store; retain a commit naming that manifest; encode through the checked writer, decode those returned bytes/value, and inspect the recovered commit/manifest/path/source locator. Checkout of that decoded repository must refuse with the missing source's path AND exact locator, not a missing manifest or a successful smaller corpus. Supplying that same source should then recover the exact content without changing the snapshot designation. This both retains the measured non-refusal as executing evidence and proves it did not erase its subject.

E2 — The current checkout witnesses do not assert the successful corpus payload. Every successful RepositoryCheckedOut match in scm_checkout_verb_witness_test.dag binds corpus to _. The existing absent-source specimen is useful and checks its refusal class, path and reference, but changing ONLY the successful checkout payload from corpus: files to corpus: [] would leave this module's inspected assertions unchanged. Source recovery itself could also return wrong text under the correct paths without these success assertions noticing. This is another unexecuted, source-derived counterexample, confined to the inspected module rather than a claim about all repository evidence.

Add an exact authored-result assertion through checkout_repository_at. A populated multi-entry snapshot should compare paths, contents and population, with an empty-source case distinguished from an empty corpus and a malformed/not-yet-ingestible text case demonstrating that semantic reconstruction is not the prerequisite. Retain positive and negative controls; do not replace them with an arm-only healthy check. The mixed held/missing round-trip specimen can also ensure an already-recovered prefix never becomes a successful partial corpus. Reuse the production path rather than building a second recovery implementation in tests.

INSTRUMENT HONESTY.

The author's report withdraws the earlier zero-error census: a missing claim_batch function did not reach resolution, and grep for ': error:' did not cover parser failures. I have not independently inspected or rerun those commands, so neither that failed census nor the later numerical fixture totals are credited as a complete execution receipt here. A future clean census must identify the intended subjects, establish that the real parse/resolve/check route was entered, and account for their terminal outcomes. Missing entry selection or missing completion evidence must not become zero errors. Parse failure, resolution failure, witness failure, and not attempted remain distinct facts. A known valid entry and controlled failures through the actual invocation route are the relevant instrument controls, not merely a different grep expression.

DISPOSITION.

The partial-corpus encoding decision and the semantic-edge fixture's re-scoping are accepted. No new blanket source-completeness gate is requested in the codec. Local stage/commit publication still needs its own exact-snapshot availability and conditional-publication admission; codec success is not that evidence. E1/E2 identify concrete evidence work visible before the full review. This scoped COMMENT does not declare the draft ready, verify the reported 68/68, 9/9 or 7/7 runs, complete the affected-consumer census, transfer prior approvals to this head, or authorize merge.

Two evidence gaps from review 5121314288, both real and both source-traced.

E2 was the sharper one. Every successful RepositoryCheckedOut in the checkout
witness bound corpus: _, so a mutation changing ONLY the success arm to return
corpus: [] -- leaving every recovery decision and refusal branch intact -- would
have left the suite green while every checkout returned nothing. I built the
recovery and never asserted the value it exists to produce. The new control
asserts the complete population, the paths, and the contents, over a snapshot
that deliberately includes source this build cannot ingest (recovery must not
require semantic ingestion, which is the point of freezing authored bytes) and a
genuinely empty file, so an empty SOURCE and an empty CORPUS cannot read alike.

E1: the partial-source encode control checked encode success and then inspected
the INPUT store, so an encoder reporting success while dropping the uncontained
entry would satisfy it unchanged. The new control decodes the emitted value and
asserts the commit, both paths, and the missing source's exact locator survive.
Its other half lives in the checkout witness and drives ONE partial snapshot
through both consumers: the deficit is reported where it is observed, supplying
the source repairs it, and the snapshot designation does not move when it does --
which is what separates 'the source arrived' from 'a new snapshot was frozen'.

The absent-source specimen now asserts the locator too, since 'right path, wrong
missing object' is a misleading diagnostic a path-only claim admits.

11/11 checkout, 69/69 envelope.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 5, 2026 13:20
@gunbai-bot gunbai-bot Bot changed the title SCM MVP-N Freeze an authored snapshot: the repository commit root becomes a corpus manifest Sep 5, 2026

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

REQUEST_CHANGES at exact head 4ea60f3. E2 is closed by inspected assertions. E1 remains open, and R1 below formalizes an unmigrated production consumer. This is not approval or merge authorization, and not a completed Rust/generated-binding census. The PR moved from draft to ready during inspection without a head change; that metadata transition does not change this disposition.

R1 — StatusCheckout still advertises a semantic-node root while its producer supplies a manifest reference.

In dag/gunbc/scm/status.dag, StatusCheckout.CheckedOutCommit.root remains SemanticNodeObjectRef, and the module still imports that type. status_checkout_of resolves the selected RepositoryCommit and constructs CheckedOutCommit { root: c.root, message: c.message }. At this head RepositoryCommit.root is CorpusManifestObjectRef. object_store declares these as separate sole_constructor kind brands, not two names for an interchangeable record.

The ordinary selected manifest-root repository therefore reaches a producer whose supplied value and advertised result field denote different kinds. This is an incomplete production root transition, not just a stale comment. Change the status carrier/import to the manifest reference it now reports, and reconcile the nearby node-root description. Do not introduce a brand conversion or reconstruct a semantic root to satisfy the old carrier; do not defer this repair to the later staging rewrite. Exercise the status projection with the selected manifest root, not only its message: a_resolvable_checkout_carries_its_commit_message currently discards root, as do the other inspected status matches.

I have not executed a compiler failure, and do not infer a particular checker/interpreter defect from the reported 7/7. The source-contract mismatch is independently visible. Also, my prior progress message mentioned this carrier but my formal E1/E2 disposition failed to carry it forward. That reporting omission was mine; I am not treating this as an E1/E2 repair you were clearly assigned and ignored.

E1 — The new evidence still breaks the value/subject chain at the boundaries it claims to establish.

(a) scm_env_a_partial_snapshot_survives_encoding_with_its_missing_locator_intact checks the tag of encode_repository_checked(repo), then decodes encode_repository(repo), a separate UNCHECKED encoding. RepositoryEncoded has a value: JsonValue payload, and that payload is never consumed by the new control.

Concrete source-derived counterexample: change only the checked encoder's successful value to the encoding of an empty or different repository, while retaining RepositoryEncoded and leaving encode_repository unchanged. This particular control still sees "encoded" and then examines the good unchecked image. I have not executed this mutation and am not claiming the whole suite would pass it. The repair must decode the actual value bound from RepositoryEncoded, not re-run a neighboring encoder.

(b) The checkout control does not continue from that decoded image. scm_ck_a_partial_snapshot_refuses_then_recovers_once_its_source_arrives never encodes or decodes. Its missing locator comes from store_authored_source("module never_stored"), whereas scm_env_partial_snapshot_repository uses the locator of scm_env_program_two, a semantic node constructed in another store and omitted here. That absent requirement is legitimate for an encoder-only specimen; it is not the same missing authored-source specimen subsequently repaired by the checkout test.

(c) The checkout control calls scm_ck_partial_repository separately before and after supplying the source. That helper creates an empty commit list and fresh allocator, then mints a commit each time. The successful checkout binds repository: _, and the envelope control asserts one commit, not equality of the original commit reference and manifest root. Reusing snapshot.identity as an INPUT and reminting two fresh ordinal-zero commits is not an assertion that the originally decoded commit/snapshot designation survived the repair.

These are one remaining E1 obligation, not three new programs to build. Use one exact authored source's locator while omitting that source from a mixed snapshot store; mint the commit once; checked-encode; bind RepositoryEncoded.value; decode that exact value; assert the retained commit reference/root and manifest requirements; checkout that decoded envelope and check reference, missing-source arm, path, and locator. Then insert that same source into the decoded store while retaining its commits, allocator, and selection, without reminting a commit or manifest. Checkout the repaired envelope, assert the full returned corpus and preserved commit/root designation. Put a held entry before the missing entry in the actual recovery order so the refusal also exercises the already-accumulated-prefix case rather than failing at the first entry.

No new codec restriction, parallel recovery implementation, test framework, or staging implementation is requested. The comments saying the same snapshot passes through both consumers and that unchanged designation is asserted, and the current PR body's corresponding Evidence paragraph, must describe the actual connected evidence rather than the two disconnected specimens.

E2 — CLOSED BY INSPECTED CONTENT.

scm_ck_mixed_snapshot constructs real authored sources for "module ok", "module { ) unparseable <<<", and the empty file, then a manifest and repository commit. scm_ck_a_successful_checkout_recovers_every_authored_file_by_content calls checkout_repository_at and compares the complete ordered path population [blank.dag, broken.dag, ok.dag] and corresponding contents [empty, malformed text, module ok]. Refusal arms return false. The previous mutation changing only successful corpus to [] no longer satisfies this assertion. The absent-source specimen also now checks the exact locator as well as path and requested reference. I have not independently executed these witnesses or credited the reported suite totals as an execution receipt.

UNCHANGED POLICY AND REMAINING EVIDENCE.

Keep the accepted separation between codec representability, authored recovery, and local publication admission. A genuinely absent manifest source is not a new blanket encode refusal, and the semantic checkout is not being replaced by repository recovery. E1 requires preservation and consumer evidence, not an encoder policy change.

The exact-SHA Actions query without an event filter returned witnesses run 33967998481, attempt 1; a later direct read still reports pending with no conclusion. No terminal full-CI result is credited. I inspected the exact-head source-tree layout but did not complete the Rust seed binding census: fetching the large cli_run.rs content was refused by the connector as too large or unsupported. No zero-reference or binding-clean claim follows from that. No source edits, witness executions, compilation, filesystem publication, merge, or draft-state change were performed by me.

Disposition: E2 closed; E1 and R1 require changes at this head. CI and the completed affected-consumer/binding census remain separate. Under the lane's standing operator rule, this review does not authorize landing.

review 5121404775. Three findings, all confirmed at source.

R1: gunbc.scm.status StatusCheckout still declared root as SemanticNodeObjectRef
while its producer constructed from c.root, now a CorpusManifestObjectRef. The
declaration and the value it advertised named different kinds, and NOTHING
REFUSED -- both are sole_constructor single-field records over ObjectId, and the
route that resolves this module produced no diagnostic. Recorded in place as a
rung-honesty fact about the brand: sole_constructor demonstrably walls off
construction from other modules, and did not stop these two being mutually
assignable. I have not established the checker's rule and do not claim to.

The status witness bound root as a wildcard and asserted only the message, so the
field was invisible to the evidence. It now asserts the selected manifest locator.

E1, both halves. The envelope control compared the CHECKED encoder's tag and then
decoded a SEPARATE unchecked encoding, so corrupting only the checked encoder's
payload would still have seen "encoded" and examined the good image. It now
matches RepositoryEncoded and decodes the value that call actually produced.

And the checkout half built its own fixture, so it established behaviour on a
repository that had never been through the codec. It now encodes, decodes, and
checks out THE DECODED ENVELOPE, with the same authored source the envelope
document omits -- one subject rather than two absences that rhyme. The snapshot
designation is asserted unchanged across the repair, which separates "the source
arrived" from "a different snapshot was frozen".

Also removed two fabricated zero-valued ObjectId locators from failure arms; the
designation reader is an Optional rather than a defaulted identity.

11/11 checkout, 69/69 envelope, 7/7 status.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

REQUEST_CHANGES at exact head 142b4b5. R1's production carrier repair is closed by inspected content; E2 remains closed. E1 is substantially repaired but retains the output-designation and nonempty-prefix gaps described below. R2 is a narrow correction to the newly added safety annotation, not a request to implement a compiler fix in this PR. No merge authorization.

Scope: I inspected the complete direct-parent delta from 4ea60f3 (status.dag and the checkout/envelope/status witness modules), the affected full source sections, current object-store canonicalization and checkout recovery, the current PR body, review history, and exact-head workflow metadata. I did not compile, execute witnesses or mutations, or complete the Rust/generated-binding census.

R1 — CLOSED: STATUS CARRIER AND OUTPUT LOCATOR.

StatusCheckout.CheckedOutCommit.root and the object_store import now name CorpusManifestObjectRef, agreeing with status_checkout_of's c.root. There is no brand conversion or semantic reconstruction inserted to satisfy the old carrier. a_resolvable_checkout_carries_its_commit_message now binds root and compares its locator against the fixture's manifest locator, in addition to its prior message/count/standing assertions. This repairs the actual producer/carrier mismatch I raised. A later rendering comment still calls this a 'root node reference'; reconcile that nonblocking stale description while editing the nearby text, but it is not an unclosed production carrier finding.

E1 — CREDIT THE REPAIRED CHAIN, BUT THE DESIGNATION ASSERTION STILL OBSERVES THE WRONG VALUES.

The envelope test now matches RepositoryEncoded { value: wire } and decodes wire. scm_ck_decoded does the same, and the checkout test consumes the envelope it returns. Both fixtures now use the authored source 'module never_stored' for their missing locator. The checkout test mints once, inserts the supplied source into decoded.store, and constructs repaired with decoded.commits, decoded.commit_allocator, and decoded.checked_out. The previous separate-unchecked-image and reminted-repository defects are repaired. No new shared fixture framework or cross-test invocation coupling is requested; the checkout witness itself now contains a connected codec-to-consumer chain.

Remaining E1 designation gap: the successful checkout still matches RepositoryCheckedOut { repository: _, corpus: corpus }, then calls scm_ck_same_root(a: repaired, b: decoded). repaired.commits was assigned decoded.commits verbatim immediately above. Comparing their roots establishes no independent fact about the returned RepositoryCheckedOut.repository. It also does not compare the decoded designation back to the original minted commit/manifest. The two paths/content assertions are real; they do not observe the returned repository's commit/root/selection.

Concrete source-derived counterexample to this control: leave recovery and the corpus payload correct, but replace only the successful returned repository's commits with []. RepositoryEnvelope is authorable with an empty commit list. This control still discards that returned repository, checks the correct corpus, and compares the unchanged input commit list to itself. It passes while the returned repository no longer contains the requested commit. This is unexecuted and limited to this assertion; I do not claim the whole suite passes it.

The repair's direct copying of the decoded commit list is itself the correct construction choice, and is credited. I am not asking for a test that re-proves immutable field copying. Move the observation to the outputs under test: retain the original envelope/reference and snapshot locator, check the decoded commit under that exact reference, bind RepositoryCheckedOut.repository, and resolve that same reference in the returned repository. Compare its root with the original manifest and check the returned selection equals the requested reference. Absence must be false, not a default. Use existing commit_at_reference rather than the new last-row fold: scm_ck_root_locator_of overwrites its accumulator for each row, so it observes the last commit, not the named commit. Optional fixes missingness, not subject selection.

Remaining E1 prefix gap: scm_ck_partial_snapshot writes held.dag before gone.dag, but store_corpus_manifest calls canonical_manifest_entries, which sorts by path. Actual recovery order is therefore gone.dag, held.dag, exactly the order asserted in the success case. The missing source is encountered with an empty accumulator, so this specimen still does not exercise refusal after recovering a prefix.

Counterexample: alter recover_corpus so a recorded refusal with nonempty accumulated files returns CorpusRecovered { files }, while an empty accumulator still returns CorpusRecoveryRefused. This partial specimen still refuses at its first entry, and the all-present E2 specimen is unchanged; neither distinguishes that mutation. This is a source-traced, unexecuted assertion-boundary counterexample, not a whole-repository mutation result. Make the held path sort before the missing path (for example a-held.dag and z-gone.dag), assert the decoded order, and retain the exact refusal and post-supply full-corpus assertions. Reordering insertion alone cannot establish the needed precondition. These are the remaining pieces of E1 already specified in review 5121404775, not a new recovery feature or codec policy.

R2 — NARROW THE NEW ANNOTATION; THE REPORTED OBSERVATION DOES NOT ESTABLISH MUTUAL ASSIGNABILITY.

The added paragraph in gunbc.scm.status says that the two sole_constructor brands 'remained mutually assignable here', while disclaiming a full account of the checker's rule. The reported concrete observation is a manifest-reference value passed into a field declared as a semantic-node reference without a diagnostic on the exercised route. That does not establish the reverse assignment, nor that the relevant field-compatibility decision was actually reached and admitted it. A 'rule not established' disclaimer does not narrow the categorical claim immediately preceding it.

Replace that sentence with the bounded observation: the selected witness invocation completed without diagnosing this manifest-to-node field mismatch; whether the field assignment was checked, and what the compatibility rule does, remain unestablished. Keep the reported direct-construction refusals at #9891 separate from assignment preservation; constructor access and compatibility are different obligations. This correction, not completion of a compiler investigation, is requested for this PR.

Yes, a separately owned, bounded failure-mode investigation is warranted. Record the undiagnosed mismatch and the unsupported promotion from construction confinement to assignment separation, not 'structural interchangeability' as an established mechanism. Before making a checker claim, bind the subject source, executable and invocation, establish the actual checking boundary, and discriminate same-brand assignment, each cross-brand direction, a plainly incompatible field such as Int, and unauthorized direct construction through that boundary. Reuse an existing matching failure-mode authority if one exists rather than minting a duplicate row. This review does not claim to have filed that investigation or reproduced its observations.

The reported Int control deserves one further precision: no diagnostic disqualifies that invocation as evidence for this check. By itself it does not distinguish 'never typechecks' from 'reached checking but skipped/failed this obligation'. Likewise, resolving a module is not a receipt that its field compatibility was checked. I have not independently inspected or rerun the reported probe commands, so I do not select one causal explanation.

E2 — REMAINS CLOSED.

The complete ordered paths and contents for blank.dag, broken.dag and ok.dag remain asserted through checkout_repository_at, with refusals false. The malformed/empty-source distinction and absent-source locator assertion remain. The two removed 0 as ObjectId fallback values are confirmed removed in the delta; that cleanup does not establish the meaning of the new last-row designation reader.

CI AND DISPOSITION.

I verified old-head witnesses run 33967998481, attempt 1, now completed/success at 4ea60f3. The exact-SHA, no-event-filter query for this head returned witnesses run 33970321643, attempt 1, in_progress with no conclusion at inspection. Old-head workflow success is credited as that fact, not as proof that every .dag field assignment was checked or that the new head is green. In particular the old head is the one carrying the undiagnosed carrier mismatch.

No new binding-census receipt is established here. The large seed-file retrieval remains unavailable; neither missing diagnostics nor unavailable source becomes a zero-reference result. I have not dismissed review 5121404775: its E1 lineage remains open, although its R1 finding is now closed by the repair above.

Keep the accepted partial-source codec policy and the separation of representation, authored recovery, and conditional publication. No compiler patch, new required CI phase, staging implementation, source-completeness restriction, or brand-conversion workaround is requested in this PR. Remaining changes are E1's exact output/designation and prefix observation, plus R2's bounded annotation. Exact-head CI and the affected-consumer/binding census remain separate conditions. No approval or merge authorization.

gunbc-ci-auto-heal and others added 2 commits September 5, 2026 14:13
… the assignment note

Three more from the same review, all correct.

The designation comparison read the INPUT repository rather than the one
checkout returned, so it established nothing about the value the verb produces.
It now compares the returned repository against the decoded one.

The accumulated-prefix case was uncovered, and the existing specimen could not
reach it: its missing entry sorts FIRST, so the fold refuses before accumulating
anything and a recovery that leaked its prefix would answer an empty corpus
there, indistinguishable from a correct refusal. The new specimen puts two
resolvable entries before the gap. A leak would hand back a two-file corpus and
call it a successful checkout -- well formed, smaller than the snapshot it names,
carrying nothing that says so.

That control is verified DISCRIMINATING rather than assumed: mutating
recover_corpus to return CorpusRecovered on its refusal arm turns it RED while
the by-content success control stays green. I ran the mutation because a passing
test proves nothing until it can fail, and three of my instruments this session
reported clean while never having looked.

The assignment note OVERSTATED WHAT WAS OBSERVED. It said the two brands are
"mutually assignable", which asserts a direction never measured. What was
observed is one: a CorpusManifestObjectRef flowing into a field declared
SemanticNodeObjectRef, with no diagnostic. Whether sole_constructor separates
them as assignment subjects is exactly what the instance leaves open, and the
note now says so instead of answering it.

12/12 checkout, 7/7 status.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
review 5121511990, and the helper defect it names is the real content of this
commit.

scm_ck_root_locator_of overwrote its accumulator on every row, so it answered the
LAST commit's root rather than the root of the commit anyone asked about. On the
single-commit fixture those coincide, which is precisely why it established
nothing: it would have kept agreeing while naming a different subject. Optional
fixed missingness; it did not fix SUBJECT SELECTION. Replaced with a lookup
through commit_at_reference, the same resolution the verbs use, so the
observation cannot drift from theirs.

And the designation comparison held two copies of the same commit list, one
constructed three lines above the other, so it verified no property of the value
checkout returned. It now resolves the requested reference IN THE RETURNED
REPOSITORY and compares that commit's root against the manifest the fixture
froze before any encoding -- so the snapshot is asserted to survive mint, encode,
decode, repair and checkout as one identity. The returned selection is asserted
to name the requested reference too, which is the other half of what checkout is
for.

Verified discriminating rather than assumed: mutating the success arm to return
commits: [] turns this control RED while the by-content control stays green. That
is the mutation the reviewer named as passing the previous form.

Also reconciled a stale rendering comment that still called the status field a
root node reference.

12/12 checkout, 7/7 status.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

FINDING CLOSURE at exact head 63265b0. E1 and R2 are closed by inspected content; R1 and E2 remain closed. COMMENT only: this is not final approval or merge authorization. Exact-head CI and the previously open affected-consumer/Rust seed binding census remain separate.

I inspected the complete two-commit delta from 142b4b5 through cfc7325 to this head, the affected checkout witness and status sections, the current PR body, and live review/Actions metadata. That delta changes only status.dag annotations and scm_checkout_verb_witness_test.dag; it does not change the codec, recovery implementation, or the previously repaired status witness. This review does not claim independent witness/mutation execution, a whole-PR consumer census, or a compiler investigation.

E1 — CLOSED: OBSERVATION AT THE RETURNED SUBJECT.

scm_ck_a_partial_snapshot_refuses_then_recovers_once_its_source_arrives still drives the actual RepositoryEncoded.value through decode_repository, checks out that decoded envelope, and checks the missing source's reference/path/locator. It supplies the exact authored source into decoded.store while retaining decoded commits, allocator and selection, without reminting a commit or manifest.

The success arm now binds RepositoryCheckedOut.repository as returned. scm_ck_root_locator_at resolves the requested reference through commit_at_reference IN THAT RETURNED REPOSITORY, with absence yielding none and then false. The returned root is compared with snapshot.identity, obtained before mint/encoding, not with a copied post-decode commit list. scm_ck_selection_is independently checks that the returned selection names the requested reference. Exact paths and contents remain asserted. The old last-row root fold and scm_ck_same_root comparison are removed.

This answers the commits: [] counterexample: an empty returned commit list makes the requested-reference lookup absent and the claim false even if corpus contents remain correct. The author reports executing that mutation, obtaining red on this claim and green on the by-content control; I have verified the assertion boundary, not independently executed or audited the local mutation run. The expected original manifest locator provides the external-to-output comparison; reusing the existing reference resolver removes a parallel selection rule, not a proof of the resolver's universal correctness.

E1 — CLOSED: REFUSAL AFTER A NONEMPTY RECOVERED PREFIX.

scm_ck_trailing_gap_snapshot stores real sources for a.dag and b.dag, then constructs a manifest also requiring the missing source at z_gone.dag. With the existing canonical path order, the two held sources precede the gap. scm_ck_a_gap_after_recoverable_entries_refuses_rather_than_returning_the_prefix requires CheckoutCorpusUnrecoverable and the exact requested reference, CorpusEntrySourceMissing arm, z_gone.dag path, and missing locator. RepositoryCheckedOut of any corpus returns false.

This separate witness covers the nonempty-prefix refusal boundary; the existing partial witness covers the connected checked-codec-to-checkout-and-repair chain. They need not be fused merely to match the layout of my earlier suggested specimen. The source-traced conditional mutation that leaks files only for nonempty accumulated prefixes is no longer admitted by the new assertion. The author's reported unconditional refusal-arm mutation is useful reported evidence but is not represented here as my independent execution or as that exact conditional mutation.

R2 — CLOSED: THE ASSIGNABILITY CLAIM IS WITHDRAWN.

The status annotation explicitly withdraws 'mutually assignable', states only the observed manifest-reference-to-node-declared-field direction without a diagnostic on the exercised route, and leaves assignment separation and the checker's rule open. The rendering annotation now says snapshot reference. R1's CorpusManifestObjectRef carrier repair and E2's complete malformed/empty-source corpus observation remain intact.

The brand incident continues to warrant a separately owned investigation, not an established structural-assignability mechanism. Closure of this annotation does not close that investigation or upgrade constructor-access observations into assignment guarantees. I have not filed or assigned a compiler investigation or reproduced those observations in this review.

NONBLOCKING EXPLANATION CORRECTION.

The new trailing-gap preamble says that returning an empty corpus on the earlier first-gap specimen would 'look identical to a correct refusal'. Its existing assertion already rejects RepositoryCheckedOut, including corpus: []; the two outcomes are not observationally identical there. The actual previously unexercised behavior is a leak conditional on a NONEMPTY accumulated prefix. Correct that explanatory sentence without changing the tests. This is not an additional blocking finding: the new fixture and assertion correctly cover the missing case. The PR body's checkout 11/11 figure also predates the newly added twelfth claim; reconcile the report with the appropriate run/head rather than treating the old number as a fresh receipt.

CI AND PROCESS.

I verified witnesses run 33970321643, attempt 1, completed/success at 142b4b5. The exact-SHA query without an event filter for this head returned run 33971917055, attempt 1, pending with no conclusion at inspection. Old-head success does not transfer. The already-open affected-consumer/Rust seed binding census is not established by this focused re-review; I did not repeat or complete it here.

All findings in my REQUEST_CHANGES reviews 5121404775 and 5121511990 are now answered by inspected content. Those reviews can be dismissed for substantive repair, not merely head age; the original scoped COMMENT 5121314288 remains historical. No further blocking E1/E2/R1/R2 rewrite is requested at this head. Keep the partial-source codec policy and the distinction between representation, authored recovery, and conditional publication. No new codec restriction, compiler patch, required CI phase, staging implementation, or test framework is requested. COMMENT closure and dismissal of repaired reviews do not constitute the lane's required exact-head approval, and do not authorize merging.

@briansrls
briansrls dismissed stale reviews from themself September 5, 2026 14:32

Findings substantively repaired at 63265b0, as recorded in COMMENT review 5121593809: R1's status carrier/locator, E1's actual checked payload and connected recovery, returned exact-reference designation/selection, and nonempty-prefix refusal are established by inspected content; E2 remains closed. Dismissal is for repaired findings, not head age. This is not approval or merge authorization; exact-head CI and the remaining affected-consumer/Rust seed census are separate.

gunbc-ci-auto-heal and others added 2 commits September 5, 2026 14:42
Nonblocking finding from review 5121593809, fixed because an inaccurate
annotation is worse than an absent one.

The note said a leaked prefix on the first-gap specimen would "look identical to
a correct refusal". That is false: that claim rejects every RepositoryCheckedOut
including one carrying an empty corpus, so an UNCONDITIONAL leak is caught there.
The real gap is narrower -- an implementation that refuses correctly when its
accumulator is empty and leaks a NONEMPTY prefix as success. With nothing ever
accumulated on that specimen, the behaviour is unreachable and so unobserved.

The mutation I had run was unconditional and therefore did not test that
boundary. Ran the conditional one this time -- refuse when the accumulator is
empty, return CorpusRecovered when it is not. It goes RED on the trailing-gap
specimen ALONE, while both first-gap claims stay green. That is the reviewer's
point demonstrated rather than restated, and it establishes the new specimen as
necessary rather than a second copy of an existing one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
docs/plans/scm-corpus-manifest-design.md states the three tags that shipped with
the manifest cut, and the repository one moved to v4 in this branch. A reader
consults that sentence for the current tags, which is the stale-authority
pattern this lane keeps repairing -- so the supersession lands beside it rather
than rewriting the historical record, and points at the module that owns the
tags instead of restating them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SUBSTANTIVE RULING at exact head 0a7cc43: the authored-manifest root replacement and the deliberate v3 retirement are accepted in principle, but this head is NOT authorized to merge. One newly inspected consumer gap, R3 below, prevents the promised named retirement from reaching the operator. E1/E2/R1/R2 remain closed; the substantive dismissals of reviews 5121404775 and 5121511990 remain appropriate. This is not reopening those findings.

THE CUT'S SUBJECT IS RIGHT.

The accepted scope is a repository commit freezing the authored corpus, not certification of an ingestible semantic program. RepositoryCommit.root carries the corpus manifest reference; the requirement-side mint resolves the actual store and keeps absence and the two wrong-kind occupants distinct. Authored recovery stays separate from semantic checkout, and the repaired assertions observe complete source content, missing-source requirements, the returned requested commit/root/selection, and refusal after a nonempty recovered prefix. Holding a manifest is not promoted to recoverability or conditional publication. This is the consumer/root cut identified by #10522 and the governing sentence of docs/plans/scm-corpus-manifest-design.md, not a request to build another object kind or implement staging/merge here.

The two commits since 63265b0 are documentation/annotation changes. The conditional-prefix explanation is now about the actual unexercised trigger, rather than claiming that successful empty recovery was indistinguishable from refusal. The version-note supersession separates the repository-format transition from the semantic-closure and hashing axes. The author's exact conditional mutation report is relevant reported evidence, not an independently executed mutation in this review.

EXPLICIT V3 RULING.

I accept a breaking repository-format transition rather than pretending a semantic root supplies the original authored bytes and paths. A semantic projection alone is insufficient to reconstruct its exact authored input. Do not introduce a target-to-reference conversion, relabel a v3 document as v4, synthesize authored files from the semantic tree, or retain a permanent legacy arm in RepositoryCommit to hide that loss.

The inspected dispatch recognizes the former tag, emits RepositoryFormatRetired with the found v3 tag, and maps it to LoadUnsupportedProtocol. That is the correct category, not malformedness or wrong-kind corruption under the new schema. Through standing_permission_refusal, LoadUnsupportedProtocol does not permit generation supersession. load_repository performs reads and retains the typed refusal; init's present-file path also still refuses creation. I found no automatic overwrite caused by this refusal in those paths.

This does not establish that every v3 image is unrecoverable or that no honest versioned migration could exist. A historical reader or migration supplied with actual authored-source and association evidence is a different, potentially honest operation. The proposed general semantic-root-to-authored-snapshot inverse is what lacks the necessary information. The old image must remain available to an appropriate reader; this PR need not implement that reader. No absence-of-durable-v3-population claim is credited.

R3 — THE LIVE READ AND INIT CONSUMERS RECLASSIFY KNOWN RETIREMENT AS NON-REPOSITORY CONTENT.

The counterexample is already in this PR: dag/test/fixture/scm_repository_load/retired_repository_v3.json. Its blob is 9440d90d9eb242b938e8ee172018971a9619ba35, exactly the same blob as empty_repository.json at the PR base 4a47d80. This is not an invented unknown-format example.

Read path:

  • gunbc.scm.repository_envelope decode_repository returns RepositoryDecodeRefused { cause: RepositoryFormatRetired { found: v3 } }.
  • gunbc.scm.repository_load load_repository retains that cause in RepositoryDocumentRefused, with the path.
  • gunbc.scm.read_command scm_read_log / scm_read_status carry it into ScmReadRepositoryUnavailable.
  • gunbc.scm.render scm_log_document / scm_status_document call repository_load_refusal_lines.
  • That function matches RepositoryDocumentRefused { path: path, cause: _ } and returns only 'not a repository document: '.

Thus the structured cause is known and retained until the final text projection deliberately discards it. scm_read_exit gives a nonzero failure with the generic reason 'repository unavailable'; it does not restore the retired tag. The CLI entry consumes those projections. The holder sees neither v3 nor retirement, and is told that the former repository is not a repository document. The new named load witness stops before this rendering boundary, so its correct tag/standing assertion does not establish the operator-visible claim.

Init path:

  • gunbc.scm.init init_present_refusal parses those same bytes and calls decode_repository.
  • Every RepositoryDecodeRefused { cause: _ } becomes ScmInitForeignFilePresent.
  • gunbc.scm.render scm_init_refusal_lines says 'a file is already there that is not a repository, and init would destroy it'; scm_init_refusal_exit calls it a non-repository file.

This remains write-refusing, so I am NOT alleging an overwrite. It is nevertheless a false classification precisely when a previously supported repository becomes unsupported by this build. 'This reader no longer supports the declared repository format' and 'these are foreign/non-repository bytes' have different meanings and remedies. Knowing the tag is retired also does not certify the entire document as valid under v3, since the v3 schema is intentionally not read. Preserve that distinction rather than replacing this with an unearned v3-validity claim.

These consumer functions predate the PR. Their generic loss already affects other unsupported inputs, but this transition routes the actual former accepted repository population into it. Their unchanged source is not evidence that the consumers moved with the new refusal. This is the remaining source-traced consumer migration finding, not an argument against retirement itself.

BOUNDED REPAIR REQUIRED.

Carry the decoder-owned protocol/retirement distinction through read output and init's present-file refusal. The operator-visible result must retain the path and the declared retired format and say that this build does not read it, without classifying it as absent, corrupt, or foreign merely because decoding is unsupported. Keep init refusing the occupied path, and keep the unsupported standing non-permitting for supersession. The format owner should supply any format-specific classification/rendering needed; do not duplicate a tag table in the CLI or invent a general compatibility fallback.

Extend the existing v3 specimen through the actual read-response rendering and init decision/rendering consumers, asserting the resulting text/format/path and non-success/non-creation disposition. Pair it with the current v4 healthy control and a genuinely non-repository/parse-failure control, so 'everything is retired' is not sufficient. Reuse the production decoder and the existing pure response/decision seams rather than constructing the expected verdict and testing its printout. This does not require filesystem mutation, a new test framework, a new required CI phase, a v3 decoder, or completion of the next staging cut.

BRAND INCIDENT.

The brand-boundary investigation remains separate and is not an established structural-assignability mechanism. I do not require its failure-mode row or a compiler repair to land before this PR. Constructor confinement, assignment compatibility, and whether the exercised route reached the checking obligation remain different questions. Nothing about R3 changes the prior annotation closure.

SCOPE / PROCESS.

I inspected the exact-head version authority, repository decoder/standing, loader, read-command composition, CLI entry, renderer, init decision, supersession permission, the v3 load witness, the identical base/head specimens, and the two-commit delta since finding closure. I also recovered the previously oversized cli_run.rs via its exact blob rather than treating an empty content response as an empty file. That does not establish a completed whole-Rust or whole-repository binding census, and no such clearance is claimed. No compilation, witness execution, mutation execution, filesystem write, source edit, or merge was performed by me.

The exact-SHA Actions query without an event filter returned witnesses run 33973096530, attempt 1, in_progress with no conclusion at inspection. This review does not transfer a prior run's success or promote dashboard approvals into source evidence. Regardless of its eventual CI result, R3 must be repaired before my approval. No merge authorization at 0a7cc43.

gunbc-ci-auto-heal and others added 2 commits September 5, 2026 15:25
CI floor refused with 8 parse errors: source annotations sitting inside a
declaration body. DESIGN section 4c models annotations at MODULE-ITEM grain only --
standalone leading blocks above a declaration -- and I put explanatory comments
in the middle of a match expression.

The rationale is unchanged and now sits above the declaration it describes,
which is where a reader looking for why the observation moved to the returned
repository would look for it anyway.

Two things worth recording. My local instrument accepted this file; the parse
phase that refuses it runs in CI, so the local green was again an observation
about a smaller question than the one I needed answered. And this is a hazard I
had already written down for myself earlier in this session and then walked into
regardless.

Swept the whole SCM tree for indented comment lines rather than fixing only the
eight the log named; there are none left.

12/12 checkout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
R3, and it is the same defect this branch exists to repair, one layer further
out. The decoder named the retirement, the loader kept it, the read command
carried it, and the TEXT PROJECTION discarded it: every RepositoryDocumentRefused
rendered as "not a repository document: <path>". So the one population that most
needs the distinction -- someone holding a repository this build has retired --
was told their repository is not a repository. init was worse in kind: it mapped
every decode refusal to ScmInitForeignFilePresent, which says "a file is already
there that is not a repository, and init would destroy it". Every clause of that
is false for a retired repository except the refusal, and the refusal was never
in doubt. Both still refuse the write; what differs is the remedy, and a remedy
the operator cannot infer is not delivered.

The classification is projected by the FORMAT OWNER, repository_envelope, not by
a renderer or the CLI: a tag table in a surface would be a second authority for
the fact, and it would drift on the next version move -- which is precisely the
event that makes anyone need it. RepositoryDocumentProtocol is deliberately NOT
LoadStanding: standing answers what a consumer MAY DO, and LoadUnsupportedProtocol
correctly covers both an unheard-of tag and a retired one. It cannot answer what
to SAY, because "a format this build never knew" and "your format, whose reader
was withdrawn" have different remedies. Its third arm keeps it from absorbing:
a refusal that is not about the format says so.

init gains ScmInitRetiredRepositoryPresent carrying the found tag, still refusing
and still non-permitting for supersession.

Evidence through the actual seams rather than around them: the retired fixture
driven through repository_load_refusal_lines asserting the format, the path, and
the ABSENCE of the old wording; a healthy v4 control rendering no refusal at all;
a damaged-document control that must not borrow the retirement wording; and an
unrecognized-format control, since unrecognized and retired are different
remedies. init is driven through init_present_refusal over real fixture bytes,
with a genuinely-foreign control so the new arm cannot be reached by everything,
and a rendering claim asserting the format appears, the refusal holds, and the
foreign wording does not.

load 12/12, cli 23/23, render 11/11, read_command 6/6, status 7/7.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

R3 RE-REVIEW at exact head dea357e — REQUEST_CHANGES. The format-owner projection is a valid direction and the old loss of the retired tag is repaired, but R3 is not closed. The new messages infer document validity from a recognized tag, unsupported inputs still reach the foreign/non-repository fallback, and the added evidence stops short of the actual decision-to-output composition requested in review 5121829994. E1/E2/R1/R2 remain closed. No approval or merge authorization.

I inspected the two-commit delta from 0a7cc43 through bae90e1, the exact-head decoder/protocol projection, loader, init decision, renderer, new witness assertions and their existing pure seams, LoadStanding's contract, the current PR head/body, and exact-SHA Actions metadata. No compilation, witness/mutation execution, source edit, filesystem write, or merge was performed.

CREDIT / DESIGN ANSWER.

Yes: keep diagnostic format detail separate from LoadStanding. repository_envelope_load_standing maps retired format, unrecognized format, and unrecognized identity rule to LoadUnsupportedProtocol. That many-to-one projection carries neither the distinction nor the found tag needed by these diagnostics; no later function of that standing can recover them. load_standing explicitly keeps format-shaped cause payloads with their owner, while the actual permission relation belongs to supersession. The new projection derives from the existing decoder refusal instead of adding a tag table in the renderer or CLI, and it has real consumers. That part is accepted. It is not necessary to claim that standing can never be rendered; it is insufficient for this particular rendering.

The third arm can correctly mean 'neither of the two format-tag refusal cases'. It cannot mean 'this is foreign content', 'not an unsupported protocol', or 'document validity has been decided'. Its implementation is a wildcard over all other causes; the existence of a third arm does not establish that these stronger consumer inferences are safe.

R3(a) — RECOGNIZED RETIREMENT DOES NOT ESTABLISH AN INTACT REPOSITORY.

repository_load_refusal_lines now emits 'the document is intact; this reader was retired, and no reader for that format ships here'. The init path creates ScmInitRetiredRepositoryPresent from that same tag-only decision, and scm_init_refusal_lines/exit assert that a repository is already present and refer to its whole history.

Concrete source-traced input, not an executed probe:
{"format":"gunbc-scm-repository-v3"}

This is valid JSON, but supplies none of identity_rule, objects, commits, allocator, or selection. decode_repository reads the format member and returns RepositoryFormatRetired before any v3 schema/body validation. The protocol projection therefore gives this input exactly the same retirement classification as the valid historical fixture. The read projection calls it intact; init claims an existing repository/history. Recognizing the declared format establishes neither. Deleting a required body member or replacing commits with a wrong-shaped value while preserving valid JSON has the same issue.

This was an explicit limit of the prior R3 ruling: do not replace the false non-repository diagnosis with an unearned v3-validity claim. The correct shared observation is 'an existing document declares retired repository format T; this build has no reader for T, so its repository contents were not validated'. It is appropriate to refuse replacement of the existing bytes regardless. Do not repair this by adding a v3 reader or partial v3 schema checker. Narrow the typed init arm's contract/name and both text/exit projections to the declared-format observation; remove the unsupported intact/history assertions. The ordinary successfully decoded v4 case can continue to assert repository presence.

The new damaged-document control only drives a JSON parse failure. It does not exercise parseable input carrying a recognized retired tag but lacking a valid repository body. Add that tag-only or wrong-shaped-body specimen through the same decoder and public output. It must still report the declared retired format without certifying validity or diagnosing corruption under an unread schema.

R3(b) — THE NEW FALLBACK STILL PROMOTES UNSUPPORTED/UNESTABLISHED INTO FOREIGN.

init_present_refusal explicitly maps RepositoryProtocolUnrecognized { found: _ } to ScmInitForeignFilePresent, discarding the tag. An unrecognized format may be a repository written by a different/newer build; 'unrecognized here' does not establish foreign content or that these bytes were never ours. The projection's new explanatory paragraph makes exactly that unsupported provenance inference ('one is someone else's document'). Retired versus unrecognized is knowledge about this build's support, not ownership of the file.

There is also a concrete existing cause in the third arm: RepositoryIdentityRuleUnrecognized. The format owner classifies it as LoadUnsupportedProtocol, but repository_document_protocol returns RepositoryProtocolNotTheRefusal; the loader then says 'not a repository document', and init says foreign. This demonstrates why 'not one of the two format-tag refusals' cannot serve as a content-validity classification.

Keep the narrow projection if useful, but stop these consumers from deriving foreignness or malformedness from its complement. Preserve the unrecognized declared-format information in init, and use an unsupported/unestablished or neutral decode-refusal result for causes whose content kind has not been established. A general neutral fallback can avoid false claims without requiring a full per-cause renderer in this PR. No new tag table, fallback decoder, compatibility migration, or policy relaxation is requested.

R3(c) — OBSERVE THE ACTUAL COMPOSITION, NOT ONLY ITS SEPARATE PARTS.

The load tests now do load_repository -> repository_load_refusal_lines. That is a real improvement. However scm_rl_says checks presence of selected lines and absence of the old exact line; it ignores the additional 'document is intact' line. The committed bad message already satisfies these assertions. The tests also do not pass the result through the log/status response composition or inspect its exit.

On init, init_names_a_retired_repository_rather_than_calling_it_foreign genuinely calls init_present_refusal on literal specimen bytes. But a_retired_repository_renders_its_format_and_still_refuses_to_initialize constructs ScmInitRetiredRepositoryPresent by hand, wraps it in ScmInitRefused, and renders it. It does not consume the former function's result or the actual scm_init_decision, and it asserts the newly overclaimed 'a repository is already there' text. Its non-success assertion concerns that constructed response, not the actual decision for these bytes.

Concrete unexecuted counterexample to the added init assertions: leave init_present_refusal and the renderer correct; alter only scm_init_decision's FilesystemFileRead branch to turn a returned retired-format refusal back into ScmInitForeignFilePresent while relaying every other cause unchanged. The new direct-helper and hand-constructed-rendering tests still pass, yet the live init route again calls the retired document foreign. I am not claiming that every repository witness passes this mutation.

Use the existing observe/scm_init_decision seam with present-file observations carrying the specimen bytes, require ScmInitDecided rather than ScmInitMayCreate, and feed that returned cause into the actual init response. For reads, carry the real loaded/decoded refusal through the log/status response seams rather than stopping at the line helper. Assert the full final message/path/tag and non-success exit. Full output equality, or an equally discriminating structured assertion, must reject added claims of intactness/validated repository identity. Retain the supported v4 and unrelated/parse-failure controls, and cover the unrecognized-format branch separately. These can be pure composition/read-only fixture tests; no filesystem mutation or new test framework is needed.

SCOPE AND SMALL REPORTING CORRECTIONS.

The intended v3 retirement, no fabricated source reconstruction, and unchanged supersession policy remain accepted. Both current init branches still refuse creation: this review alleges false classification and insufficient consumer evidence, not an observed overwrite. The new claim that 'every clause' of the old init warning was false is too broad: a file really was present, and replacing it really would discard its bytes; the unsupported non-repository classification was the defect. Narrow that annotation along with the consumer repair.

The bae90e1 delta relocates the eight checkout annotations without changing the repaired assertion expressions. No old finding is reopened by that relocation. The brand-boundary investigation remains separate and is not required to land before this PR. This review does not establish completion of the still-open affected-consumer/Rust seed binding census.

CI / DISPOSITION.

The exact-SHA queries without an event filter returned witnesses run 33974768309, attempt 1, completed/success at bae90e1, and run 33977010728, attempt 1, in_progress with no conclusion at dea357e. The former is not evidence of the R3 repair at the latter. Reported local suite totals are not independently reproduced here.

R3 remains the blocking lineage; I have not dismissed review 5121829994. The bounded completion is: declared-format observations without validity/ownership invention, no unsupported-to-foreign fallback, and connected decision-to-output evidence. A v3 reader, compiler repair, staging implementation, and new required CI phase remain out of scope. No merge authorization at this head.

…ing unsupported foreign

R3(a) and R3(b), both correct, and (a) is an overclaim I introduced while
repairing the previous one.

R3(a). The read path said "the document is intact" and init said "a repository
is already there ... its whole history". Both were derived from RECOGNIZING A
TAG, not from reading anything. decode_repository returns on the format member
before validating any body, so a document that is nothing but
{"format": "gunbc-scm-repository-v3"} -- no identity rule, no objects, no
commits -- reaches the same answer as a complete historical repository. The
output now says which protocol was DECLARED and that the contents were NOT
VALIDATED, and claims nothing else. Init's refusal is justified by bytes being
present, which needs no claim about their validity. No v3 reader and no partial
v3 schema checker was added.

R3(b). Unrecognized-format was still routed to ScmInitForeignFilePresent, which
discards the tag and asserts provenance: "not recognized by this build" is a fact
about THIS BUILD's knowledge, not about who wrote the file, and a newer build's
repository is not foreign content. Worse, RepositoryIdentityRuleUnrecognized --
a document whose FORMAT this build reads, declaring an identity rule it does not
-- fell through the wildcard and rendered as "not a repository document". The
identity rule is versioned on its own axis precisely so it can move without the
format moving, and the projection now covers the whole protocol family:
retired format, unrecognized format, unrecognized identity rule, and a wildcard
that means only "not one of those" -- explicitly not foreign, not validated.

init carries the protocol value rather than enumerating tags, and one shared
sentence renders the protocol fact so init and the read path cannot drift into
describing one observation two ways.

Evidence: a new tag-only fixture -- parseable JSON with the retired tag and no
body -- asserting the protocol IS named and the intactness wording is ABSENT.
load 13/13, cli 23/23, render 11/11, read_command 6/6.

Unrelated to the diff: the previous head's CI refused with
MemoryStallRefusedPageThrash on the runner (258859 major faults/minute at 4% CPU
share, remedy stated as a larger runner). The subject was never evaluated, so
that is a rerun rather than a defect.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SUBSTANTIVE MERGE RULING at exact head b266ff0 — REQUEST_CHANGES. The authored-manifest root replacement is the correct cut against the governing design, but this candidate does not yet complete its diagnostic/evidence obligations. R3(a)'s production overclaim is repaired; the two named unsupported cases in R3(b) are repaired; R3(b)'s complement misuse and R3(c)'s disconnected consumer evidence remain. E1/E2/R1/R2 remain closed. This is not a tally-based hold and is not merge authorization.

THE MERGE QUESTION, ANSWERED SEPARATELY.

Yes to the substantive replacement. docs/plans/scm-corpus-manifest-design.md makes an authored corpus manifest the repository commit's subject and keeps semantic interpretation a separately bound projection. RepositoryCommit.root, the requirement-side mint, the repository codec, authored checkout, and log/status are moving to that subject rather than adding an alternative legacy arm. The mint resolves the actual manifest population and retains absence and both wrong-kind distinctions. Authored checkout does not require semantic ingestion, and the repaired assertions inspect complete returned content, exact missing-source requirements, the returned requested commit/root/selection, and a gap after a nonempty recovered prefix. A held manifest is not promoted into recoverability or publication permission. The deliberately breaking v4 transition/no fabricated v3 inverse remains accepted. No staging implementation, compiler repair, v3 reader, compatibility fallback, or new required CI phase is requested.

No to landing this exact candidate as complete. DESIGN section 3 requires one authority and a replacement preserving its required distinctions; section 5 forbids plausible output about facts that were not established. The remaining issues below concern those obligations, not whether an approval or test count has been reached.

R3(a) — PRODUCTION VALIDITY OVERCLAIM CLOSED.

The retired-format read output now reports the declared tag and that the contents were not validated. init carries ScmInitUnsupportedDocumentPresent rather than asserting a validated historical repository, and its text and failure reason no longer infer intactness/history from the retired tag. The ordinary RepositoryDecoded case may still say a repository is present. Existing bytes still lead to refusal, not creation. The tag-only load assertion is a useful additional discriminator, but does not close the separate composition requirement in R3(c).

R3(b) — THE NAMED CASES ARE FIXED, BUT THE COMPLEMENT STILL BECOMES FOREIGN.

repository_document_protocol correctly maps RepositoryFormatRetired, RepositoryFormatUnrecognized and RepositoryIdentityRuleUnrecognized into three distinct protocol observations. init now retains the protocol value for all three. Credit those repairs.

However, init_present_refusal still contains:
RepositoryProtocolNotAProtocolRefusal => ScmInitForeignFilePresent { path: path }

repository_load_refusal_lines still contains:
RepositoryProtocolNotAProtocolRefusal => [concat("not a repository document: ", path)]

The projection's own new contract explicitly says its complement means neither foreign nor non-repository nor validated. Those two consumers still make exactly those inferences. Changing the complement's documentation did not change its consumers.

This is a present-day subject, not only a hypothetical future enum extension. A source-traced input is a document declaring this build's v4 format and current identity rule but missing next_commit_ordinal. decode_repository_v4 enters decode_repository_body; the missing member becomes RepositoryMemberReadRefused; the protocol projection returns its complement; init calls the bytes foreign. Removing that member from this build's own repository image establishes a schema defect, not that the content is unrelated or has foreign provenance. I have not executed this probe. The broader complement also includes object-table causes delegated by the standing classifier; it is not an authority for document ownership.

Bounded repair: retain the three protocol cases, but route other unclassified decode refusals through a neutral present-document/decode-refusal result, with neutral text and exit reason, rather than asserting foreignness. No complete per-cause printer is necessary. Do not merely pass the complement into an arm/exit which asserts an unsupported protocol: that would replace one unsupported inference with another. A refusal to replace present bytes needs neither a validity nor a provenance claim.

The newly added projection annotation also still says unrecognized format is "someone else's document" and retired format is "your own repository", immediately before the later paragraph withdrawing that inference. Remove that contradiction; support knowledge does not establish ownership.

THE CLAIMED SHARED SENTENCE IS NOT SHARED YET.

render.unsupported_document_line is consumed by scm_init_refusal_lines. repository_load.repository_load_refusal_lines does not consume it: it has its own match and separately authored versions of the same three protocol sentences. The strings currently agree, but that is not one derivation authority, and neither the commit report nor the new annotation may claim they cannot drift through shared production. Put the protocol wording at its owner or another common lower seam and make both consumers actually use it, without introducing a load/render import cycle or a second tag table. Their surrounding operation/path text can remain different.

R3(c) — THE PREVIOUSLY REQUESTED DECISION-TO-OUTPUT COMPOSITION REMAINS UNOBSERVED.

In scm_cli_witness_test.dag, init_names_a_retired_repository_rather_than_calling_it_foreign still calls init_present_refusal directly. a_retired_repository_renders_its_format_and_still_refuses_to_initialize still constructs ScmInitUnsupportedDocumentPresent by hand, wraps it in ScmInitRefused, and renders it. Neither carries the actual scm_init_decision result for the specimen bytes into scm_init_response.

The same previously supplied source-derived mutation remains a discriminator for the gap: leave the helper and renderer correct, but alter only scm_init_decision's FilesystemFileRead branch to reclassify its returned retired-format refusal as ScmInitForeignFilePresent. These added helper/constructed-response assertions do not observe that branch, while the live init response would again be false. This is not an executed mutation or a claim about every repository witness.

On the read side, scm_rl_refusal_text still stops at load_repository -> repository_load_refusal_lines. The added assertions do not reach the actual log/status response or inspect its exit. The tag-only assertion excludes one exact old intactness sentence; it does not reject an additional, differently worded validity claim. Its selected required lines could remain present alongside that extra false claim.

Use the existing observation/scm_init_decision seam with present-file observations carrying the fixture bytes, require ScmInitDecided rather than ScmInitMayCreate, and pass that returned cause into the actual init response. Carry real loaded/decoded results through the log/status response seams too. Assert complete final output (or equally discriminating structure), path/tag and failure exit. Keep the supported v4 and unrelated/parse-failure controls; cover the retired tag-only input and the independently versioned unknown-format/unknown-identity-rule inputs through the relevant consumers. This joins the existing evidence, rather than asking for another framework or filesystem mutation.

CI / SCOPE / DISPOSITION.

The exact-SHA query without an event filter found witnesses run 33979443647, attempt 1. It was in progress initially; my final direct read reports completed/success at this exact head. That is credited as the workflow's reported successful result, not as independent execution of the local suite totals or proof that these unobserved distinctions are covered. The earlier page-thrash explanation remains the author's report, not an independently reproduced diagnosis here.

I inspected the governing DESIGN and corpus-manifest plan, the root/mint/codec/checkout changes and repaired assertions, log/protocol/init/read/render paths, the new diagnostic assertions, and live PR/Actions metadata. I did not compile, execute witnesses or mutations, modify source, publish repository bytes, or merge. This does not establish a completed whole-Rust/generated-binding census. The concrete R3 findings independently prevent approval; an uncompleted census is not being substituted for them.

Disposition: retain the accepted root cut and prior E1/E2/R1/R2 closures; close R3(a)'s production overclaim; keep R3(b)/R3(c) open, including the unshared-rendering correction above. Reviews 5121829994 and 5121996260 are not dismissed as substantively repaired. No merge authorization at b266ff0, despite this head's successful CI.

@briansrls
briansrls merged commit dcc56d3 into main Sep 5, 2026
4 checks passed
@briansrls
briansrls deleted the scm-commit-manifest-root branch September 5, 2026 18:35
@briansrls
briansrls restored the scm-commit-manifest-root branch September 5, 2026 18:41
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