Repository navigation
Settle what a merge IS before the manifest hardens - #10522
Conversation
The merge lane has been blocked on model, not effort: gunbc.scm.merge is
roles/requirements/supersession and not two-commit merging. This records the
design ruling before any merge code exists, because section 5's question -- is
conflict structural or per-path -- decides the shape of CorpusManifestObject, and
building that authority first would be the section 3 replacement-migration trap.
The operator's goal is NOT "resemble git": the interface is a projection over the
existing git/mercurial/pijul realizations, and the workflow is squash-merge into
main, discard dev history, never rebase, optimize for simpler and faster merges.
Several rulings follow from that and differ from what a general two-parent merge
would need.
THE CENTRAL RULING: no two-parent ancestry arm. A squash result is single-parent,
so CommitAncestry = RootCommit | DescendsFrom { parent } is already right, and a
MergedFrom arm would have no producer -- which section 4b calls worse than absent.
The stronger reason is that it would be actively WRONG: ancestry_walk follows
parents, so a second parent would make the walk traverse the line the workflow
exists to discard, making "kill dev history" false at the layer that answers
questions about history. But discarding the line must not discard the FACT, so a
merge carries a MergeAbsorption RECEIPT naming what it absorbed. A parent is a
structural fact the walk follows; an absorption is a receipt the walk must not.
Base derivation inherits an obligation ancestry.dag states explicitly: it deleted
its own boolean ancestor predicate because false was answering for four different
facts, and it names merge-base as the consumer that must decide per arm. So all
four AncestryWalk arms get distinct merge meanings, and AlreadyAbsorbed and
NoCommonAncestor are each discriminated rather than collapsed into a conflict.
The manifest question is settled to the extent that unblocks it and no further:
the SUBJECT of a merge is the semantic node graph, not the path map, which makes
the manifest a projection for emission rather than the authority a merge reads.
The structural merge ALGORITHM is deliberately not designed here, and the risk is
recorded rather than hidden -- if it proves intractable the fallback is per-path,
which would change the manifest's shape, so tractability must be shown before the
manifest hardens.
Four questions are left open and marked open: the ref model's placement, the
fast-forward presentation, object retention for absorbed lines, and author and
timestamp -- the last blocked on a ruling this lane does not own, since there is
no modeled clock and no modeled process identity to observe them with.
No code. The evidence the implementation will owe is enumerated in section 9 so it
cannot later be declared done by typecheck.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
briansrls
left a comment
There was a problem hiding this comment.
DESIGN REVIEW — REQUEST_CHANGES at 465e0bb.
I inspected the complete one-file, 215-line addition and the exact-head ancestry, object_store, repository_envelope, supersession, scm_compatibility_shape and DESIGN contracts. This is a design disposition, not an implementation or execution review. No execution is credited or requested to close the findings below; documentation changes can close them. I have not merged anything.
ACCEPTED DIRECTION
I withdraw the proposed MergedFrom arm for this squash-only workflow. The integration result must have the observed target as its sole parent; the absorbed source is an evidence reference, not an ancestry edge. I also support a pure candidate-producing merge operation, explicit author-supplied resolution instead of an automatic ours/theirs escape, preservation of the walk's refusal causes, and reuse of the existing compatibility projection boundary without a vendor switch.
The receipt distinction is sound, but the current document does not consistently consume it. There are FIVE design findings, D1–D5.
D1 — §§2/4/9: AlreadyAbsorbed is decided by the relation that deliberately omits absorption.
Counterexample: B is the common ancestor, T is the target, S is the source. Produce M with parent T and an absorption receipt naming S and B. The parent chain from M contains T and B, not S. Retrying S therefore does not satisfy the ancestry-membership test in §4; it falls into another BaseDerived/merge. If S has been collected, the mandatory source walk instead returns StartNotInHistory before the surviving receipt can answer the question. Reading 'absorbing tip' as M rather than S does not fix this: the document still owes the receipt lookup that identifies M for the requested S.
Required design repair: distinguish source ancestry membership (AlreadyInTargetAncestry), exact-source absorption recorded on the current target lineage, and a new integration with an unchanged result. The absorption lookup must consume a committed, target-lineage-scoped receipt naming the exact source subject, not a repository-global flag or candidate metadata. State whether the promised historical query remains answerable after collection; if it does, do not require the collected source's ancestry as a precondition. Keep 'this source was integrated here' separate from 'all its effects are present now': a later revert or an author resolution can invalidate the latter without invalidating the historical receipt. Do not infer absorption of an arbitrary intermediate/extended tip from a receipt for S without a coverage rule.
Physical retention policy can stay open. The durable subject identity, non-reuse, and collected-versus-unavailable meaning needed to read the receipt cannot be left implicit. §9 needs the repeated exact-source request, later target commits, another target lineage, and retained/collected-source cases as future controls.
D2 — §4: fast-forward is not merely an open presentation choice under the fixed squash/discard contract.
Counterexample: target A; source line A -> B -> C. Advancing the target to C leaves its ancestry C -> B -> A. Deleting the branch name does not discard B or C from the target history. This violates the same property used to reject a second parent in §2.
Required design repair: distinguish the cheap content case (base equals target; source content can be selected without reconciling divergent content) from the history/publication case. For a new integration, produce M with parent A, the selected source result, and its absorption receipt. Do not publish C directly. Identical target/source and previously integrated requests remain separate no-op dispositions. The UI may describe the cheap case differently, but the ancestry consequence is not open under §0.
Also explicitly re-decide ancestry.dag's existing widening trigger, which currently says an operation taking two Commits causes a several-parents arm. Two inputs do not entail two retained ancestry parents. The design must name this superseded premise and the corresponding future annotation obligation; this review does not request code in this documentation-only PR.
D3 — §5 and introduction/§10: structural reconciliation does not make the authored-source manifest a derived emission-only projection.
This exact head already contains CorpusManifestObject, CorpusManifestEntry { path, source }, and the repository-v3 mixed-object codec. RepositoryCommit.root still takes SemanticNodeObjectRef. The pending consumer/root cut must therefore be identified precisely; this is not before the object kind exists.
More importantly, object_store's CorpusManifestEntry contract explicitly separates authored source from derived ingestion: the latter depends on corpus/import context and rule versions; malformed or not-yet-ingested source remains freezable; a comment-only edit changes source/manifest identity without changing the semantic root. §5 reverses that ownership without disposing of these requirements.
Counterexample: two snapshots have identical semantic graphs but different comments or authored placement. A merge that receives only those graphs cannot recover which source change occurred. Selecting a new merge algorithm cannot reconstruct information absent from its subject. Path/name collisions and source that cannot be ingested likewise need a named disposition, not disappearance.
Required design repair: retain a complete authored snapshot authority, and make structural interpretation/correspondence a derived merge view with exact source/context/rule binding; or explicitly propose and justify a lossless replacement carrying every required source/placement fact. Do not demote the existing manifest merely by declaring graph-native merge preferable. Storage/freeze identity and conflict granularity are independent choices: structural merging can consume source snapshots and produce a new source snapshot without changing the path-to-source record into a competing authority. A conservative path-based algorithm, considered as an explicit later design alternative rather than a runtime fallback, does not inherently require a different manifest shape.
Correct the Git comparison as part of this repair. 'Same path changed on both sides' is not Git's general conflict predicate: it performs content three-way merging and supports custom merge drivers. Git's own git-merge and gitattributes documentation establish that distinction. Different-function changes in one file are not by themselves a differentiating demonstration.
D4 — §5: 'the same semantic node diverged' leaves the essential correspondence contract undefined and overstates independence.
ObjectId is derived from node content, including children. Editing a function changes its identifier and ancestor hashes. Both branches therefore change the root even when editing distinct functions; conversely, hash-consed equal subtrees can occur in multiple logical locations. A global replacement keyed by an old content hash can change an occurrence the author did not edit. Content equality/reuse is not cross-revision logical-occurrence identity.
Different-node edits can also interact: one side removes a declaration while the other adds a caller, or two independent additions occupy the same declaration name. Structural non-overlap alone does not establish an admissible combined program, much less behavioral compatibility.
Required design repair: define the admitted correspondence evidence and the automatic-merge claim before selecting its implementation. A conservative bounded first domain is reasonable: exact base/target/source alignment, ordinary equal/unchanged three-way cases, recursive joins only over components whose composition is established, and explicit ambiguous-correspondence, unsupported-shape, delete/modify, ordering/placement, or binding failures. No guessed rename and no silent fallback. Full arbitrary structural merging need not be implemented or proven in this document; the document must stop promoting an unspecified identity relation into a settled capability.
The feasibility obligation should exercise different-function edits in one file, same-function competing edits, deletion versus new use, rename/move correspondence, and shared-subtree occurrence isolation. Its cost must include interpretation, matching/indexing, merge, source reconstruction, and admission. The inspected store uses List-backed lookup with declared quadratic cost debt; content addressing alone proves no speedup. Structured-merge implementations such as Spork establish that bounded useful structural merging is plausible, not that this substrate already has the needed identity or fidelity properties.
D5 — §§3/6/9: candidate-then-commit does not establish exact-target publication or safe source retirement by itself.
§6 names base, source and result but does not state the binding to the observed target identity/generation whose movement must invalidate publication. A candidate derived against T1 can otherwise be published after the target advances to T2. Similarly, deleting a source ref by name after it moves from S to S2 can discard unabsorbed work.
Required design repair: bind the candidate to the exact repository/target observation, source subject, derived-base evidence, interpretation/resolution inputs and result. Publication must conditionally advance the same observed target and install the commit/absorption fact coherently; stale or wrong-target input must not be silently retargeted. Source retirement must refer to the exact source generation absorbed, happen only after successful durable integration, and preserve a ref that has advanced. State the failure/retry outcomes without inventing a storage transaction implementation now. Extend §9 with target-moved, wrong-target, source-moved, failed-publication and receipt/publication coherence controls.
supersession is correctly treated as a precedent rather than a branch-ref authority. Its inspected contract binds the slot and observed generation; merely splitting computation from mutation does not reproduce that property.
RULINGS ON ORDERING AND THE REMAINING OPENS
Design before the merge consumer/commit-root cut is right. Blocking the neutral authored-source snapshot primitive on a complete structural solver is not established by DESIGN §3. Replacement migration applies when X and Y answer the same question and X is to disappear. Freezing authored source and deriving a merge interpretation answer different questions. Name the actual retiring root and its retained obligations; do not manufacture a replacement between complementary layers.
For refs, prefer explicit role-labelled immutable subjects to the pure merge operation and let a surface/controller resolve merge into them. Mutable names and their observations belong at the publication boundary. Target/source are semantic roles, not anonymous positions; user-visible branch names are not required merely to obtain identity. Preserve the existing empty/unborn state rather than requiring exactly one checked-out ref universally. Ephemeral does not imply no persistence requirement: a multi-command or resumable workflow has a lifetime to preserve even if its name is deleted on success.
GC scheduling and storage retention remain open within D1/D5's minimum identity, query and safety contracts. Author/timestamp acquisition remains outside this lane's authorization; do not fabricate it. Exact source/base/target/result binding gives a meaningful receipt even without those observations. The compatibility projection's own note explicitly says it is not a semantic, commit, execution or Applied receipt; §7's reuse must preserve that limit.
Finally, §9's first bullet currently asks every AncestryWalk arm to reach a distinct refusal, but AncestryTraced is the successful arm. Require the three refusal causes per side and the traced/traced relation outcomes, not a refusal for a successful trace.
Disposition: retain single-parent squash plus a non-ancestry absorption receipt; repair D1–D5 before treating this document as the settled design. This is not a request for a two-parent model, a full structural solver, a new clock, or execution evidence in this PR.
…is answerable
Section 5 recorded "I have not demonstrated a three-way structural merge is
tractable here" as an open risk, and flagged it as the thing to attack before the
manifest hardens. It is answerable from the model, and the answer is neither yes
nor no.
v2.std.node gives EdgeLabel = Named { name: Symbol } | Positional, and that
coproduct IS the partition.
NAMED edges are tractable by a known algorithm: children align by name exactly as
a tree merge aligns directory entries, and at each aligned child three digests
decide it with no heuristic -- ours==theirs take either, ours==base take theirs,
theirs==base take ours, all differ recurse. This is where section 5's
differentiating claim actually lives: two changes to differently-named children do
not conflict, whatever file they were written in.
POSITIONAL edges are not tractable today, and the reason is structural rather than
unfinished. Position is the only identity such a child has, so concurrent
insertions cannot be aligned, and both escapes are closed. Occurrence identity is
deliberately outside content identity -- gunbc.scm.checkout records that asserting
on provenance would assert the one property the model says must not matter -- so
it cannot track a moved positional child. And a sequence-alignment heuristic is
what section 4 rules out: in a closed grounded system a heuristic is never
necessary, and reaching for one LOCATES the anemic modeling rather than solving
it. A diff3-style alignment would be a confidence threshold selecting an arm.
So the ruling is a REFUSAL, not a fallback. A merge reaching a node whose
positional children diverged on both sides refuses, typed and located. It does not
align, does not take a side, and does not degrade to per-path merging for that
subtree. MergeConflict is therefore not one arm: a named conflict is a real
content conflict an author can resolve, a positional one is the model declining to
guess, and collapsing them would report a modeling limit as an authoring problem.
This BOUNDS section 5's risk rather than clearing it. The risk was that structural
merge proves intractable and the per-path fallback changes the manifest's shape.
Named carries the merge, positional refuses, and neither outcome needs the
manifest to be the merge subject -- so section 5 now stands on a narrower and
firmer base and the manifest may proceed as an emission projection.
What remains open is smaller and is a MEASUREMENT, not an argument: how much of a
real corpus sits under Positional edges. If most interesting structure is
positional then a merge that refuses on all of it is honest but useless, and the
lane needs a MODELED child identity -- its own capability with its own ruling,
never a heuristic. Counting Named versus Positional over the live corpus at
merge-descent grain is the next concrete step, and it is deliberately not
estimated here.
Section 11 corrected too: the finding is derived from the node model, not
demonstrated by a running merge, and must not be credited as the latter.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
D3 (the central one): section 5 forked an authority this repository already holds. gunbc.scm.object_store already rules that a manifest entry is path-to-authored-source and deliberately NOT path-to-semantic-root, naming the same comment-only-edit case used against me. The document also opened by claiming CorpusManifestObject was unbuilt and gated by this ruling; it exists today. Both corrections are recorded in place rather than rewritten away, and the withdrawn git conflict-predicate strawman goes with them. D1: the absorption receipt had no consumer, so it was data, not evidence. The query is now fixed before the producer -- exact-source and target-lineage scoped, holding the absorbed tip as a VALUE so it survives collection, and keeping ancestry membership, a committed receipt, and a fresh content comparison as three separate facts. Absorbed-then-reverted is the specimen. D2: the fast-forward case was left open, and open was a loophole -- advancing the head onto the source tip revives the dev history the workflow kills and writes no receipt. Ruled: reconciliation may be trivial, publication is uniform. ancestry.dag's superseded two-commit trigger is replaced, not deleted. D4: correspondence, not EdgeLabel, is the tractability boundary. Changed ancestors, shared subtrees, and renames bound the ObjectId claim. The performance claim is withdrawn for want of a denominator. D5: a candidate now carries the exact observed target generation, and publication and retirement name their exact subjects. Section 9 also had AncestryTraced listed as reaching a refusal; it is the success arm. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
briansrls
left a comment
There was a problem hiding this comment.
DESIGN RE-REVIEW — REQUEST_CHANGES at e4adbbc.
I read the complete 431-line document, the current PR body, the comparison with 465e0bb, and the relevant exact-head supersession, repository-save and generic durable-CAS contracts. The comparison is two descendant commits and remains documentation-only. This is not an implementation or execution verdict. No execution is credited or required to close this design review, and no merge has been performed.
DISPOSITION OF 5120053195
D3 is CLOSED. The revised source-authority census and separation are correct: authored snapshots remain authoritative; structural interpretation/correspondence are derived views, not a replacement for the manifest. The ordering consequence is ACCEPTED: this merge-solver dependency does not block the authored-snapshot primitive or add/commit. Removing that dependency is not proof that acquisition, the commit-root consumer cut, or safe publication is already implemented or admitted.
D4 is CLOSED at the stated design-obligation scope. The document now distinguishes content identity from logical occurrence/correspondence, names cross-component interactions, requires an explicit inability to decide when correspondence/composition is unavailable, and withdraws the speed claim. This credit establishes neither a running structural merge nor a demonstrated useful/tractable first domain. A conservative unsupported-positional case is permissible; it is not a theorem that no stronger positional correspondence can ever be modeled.
D2's substantive history repair is CREDITED: trivial reconciliation still creates M with the observed target as sole parent and a receipt naming S; directly installing S is forbidden. The replacement preserve-both-lines widening condition is appropriate as a future capability condition, not an unmet requirement of this squash workflow. One contradictory sentence survives in section 10: 'fast-forward presentation (section 4 open)'. Remove/reconcile it; the PR body's open-items list is already corrected.
D1 and D5 remain BLOCKING. These are the original consumer and publication obligations, not a request for a new scope of implementation.
D1 — THE NEW RECEIPT QUERY IS NOT YET CONNECTED TO THE MERGE DECISION.
Section 2's new D1 subsection is a genuine improvement: exact source, current target lineage, historical integration distinct from present effects, and lookup without dereferencing the collected source. But section 4 still starts by walking BOTH sides and still says:
'AlreadyAbsorbed — the absorbing tip is already in the target's chain. Nothing to do.'
Section 9 repeats AlreadyAbsorbed as one of the same four traced/traced outcomes. These are current governing statements, not superseded passages.
The original counterexample therefore survives at the specified merge consumer. After M(parent=T, receipt=S), S is not on M's parent chain. Re-requesting S reaches another base-derived merge rather than the new receipt decision. After S is collected, the mandatory source walk can refuse before that historical fact is read. Naming a separate correct query does not make the merge operation consume it.
Required documentation repair:
- State the orchestration: establish the target lineage; consult its committed exact-source absorption evidence without first requiring the source objects; only when fresh reconciliation is needed require the live source/history and derive a base. A historical integration answer is not evidence of present effects or permission to suppress an explicitly requested reapplication after a revert.
- Give source-in-target ancestry membership its own meaning (for example AlreadyInTargetAncestry), instead of continuing to call it absorption. Distinguish it from receipt-backed historical absorption and from a newly computed unchanged result. Do not preserve a four-item outcome count by merging those facts back together.
- Place SourceNotInRepository explicitly. It can refuse a new operation that requires a source not available in this repository; it must not veto an exact receipt lookup merely because the source was collected. A complete target walk with no matching receipt supports NoAbsorptionRecorded; an unwalkable target does not. Absence of a source record is not by itself evidence that the source was intentionally collected or never existed.
- State the durable source-subject scope and non-reuse rule. Keeping an ID value avoids dereference; it does not by itself establish that the same spelling cannot later designate another source. Physical GC scheduling may remain open.
Extend the promised section 9 evidence through the actual merge decision, not only the helper query: repeated exact-source request, later target commits, retained versus collected S, and another target lineage. Preserve the absorbed-then-reverted control, and distinguish a never-absorbed source whose proposed result happens to be unchanged. These are future implementation obligations, not tests required in this documentation-only PR.
D5 — THE NEW ROUTE CALLS A MALFORMED-DOCUMENT REPLACEMENT POLICY AS ORDINARY PUBLICATION.
Section 1 correctly states that supersession is a precedent, not a reusable commit-ref authority. The new D5 subsection and the PR body contradict it by directing publication to pass the observed HeadSlot generation and source tip to supersede_head_slot.
The exact-head signatures and policy do not support that route:
- observe_generation returns SupersessionEvidence, not a bare HeadSlot generation.
- supersede_head_slot takes (slot: HeadSlot, evidence: SupersessionEvidence, proposed_generation: ObjectId), not an absorbed RepositoryCommitRef.
- standing_permission_refusal admits only LoadDocumentMalformed. LoadComplete is explicitly StandingDoesNotPermit. Therefore an ordinary merge into a complete repository is refused by the proposed authority before its generation comparison can authorize anything.
- SupersessionApplied returns a new modeled slot and a warrant. This function does not persist a repository commit, atomically install an absorption receipt, or retire a source ref.
That is a contract mismatch, not an argument against CAS. Do not weaken malformed-document supersession's permission policy to make ordinary merges fit it. Specify normal merge-publication admission and its exact-target conditional-write obligation separately from that repair policy. Appropriate stable primitives can be reused once their subjects and guarantees are joined; this review requests no new .dag actuator or transaction implementation.
There is already a generic std.durable_compare_and_set shape, but it explicitly declares its observation-to-slot binding boundary; citing it would not by itself discharge wrong-target evidence either. Likewise save_repository is checked encoding followed by an unconditional filesystem write, not an existing exact-generation publication implementation. The design should name the missing binding/realization obligation honestly rather than claim a complete existing route.
The rest of the original D5 closure contract also needs to be explicit:
- Bind the candidate to the repository/target slot and exact observed target commit/state, source identity, derived-base evidence, interpretation/rule and author-resolution inputs, and the resulting authored snapshot. A generation value alone is not this relation, and section 6's unchanged opening still describes only a base, source and resolved graph.
- A successful durable publication must coherently expose the new commit, its absorption receipt and the target advance. A candidate or an uninstalled receipt cannot count as an integration. Name the success evidence that subsequent retirement consumes.
- The new source-generation rule is directionally correct, but retirement must CONDITION the deletion on that same source slot/incarnation still naming the absorbed generation at retirement time. A source can advance after successful publication and before deletion. Preserve that newer ref and report integration complete/retirement withheld rather than destroying S2 or pretending the integration did not happen. GC must also respect other live references; absorbing one line does not license deleting shared content.
- Restrict PublicationFailed's 'state unchanged; retry' promise to evidence that publication definitely did not apply. A realization that installs a state and then loses its acknowledgement cannot be classified that way without reconciliation. If the actual realization rules this case out, state that required guarantee; otherwise preserve an unestablished outcome. A fresh attempt remains subject to the same exact-target precondition, not blind replay.
Section 9 should therefore include a healthy-repository publication control, commit/receipt/target coherence, source movement AFTER publication but BEFORE retirement, and failed or unestablished publication leaving the source intact. The current test list only names the prepublication movement failures and failed-publication non-retirement.
IN-PLACE CONSISTENCY REPAIRS ALREADY REQUESTED
Section 3 is unchanged: it still derives 'does not need to persist' from eventual deletion and proposes 'exactly one ... checked out' without preserving the empty/unborn state. A multi-command/resumable line has a lifetime even if retired on success; source/target roles and existing commit identities can identify operands without requiring names. The ref layout can remain open, but these asserted deductions must not decide it by a false premise. This was part of the previous review, not a demand for a general Git branch model.
Reconcile section 10's stale fast-forward-open sentence with the accepted D2 ruling. Keep section 5a/10's feasibility language at obligation rather than result, and preserve the compatibility projection's existing limitation: it presents evidence and is not itself semantic admission, a commit, or a durable Applied receipt.
SUMMARY
The central source-authority correction is accepted, including removal of the false merge dependency from manifest/add/commit work. The single-parent squash decision and D4's bounded design obligations remain accepted. The remaining work here is to make the actual merge decision consume the receipt contract and to replace the incompatible publication route with an honest exact-subject publication/retirement contract, then reconcile the surviving old statements and evidence list. No two-parent arm, structural solver, new clock, or execution evidence is requested. No merge authorization at this head.
…tion through supersession
Two blockers from review 5120233720, both correct.
D1 was repaired at the query and not at the consumer. Section 4 still put base
derivation first, so a re-request for S after M was published fell through to
another base-derived merge, and once S was collected the mandatory source walk
refused before the surviving receipt was ever read -- the original
counterexample, alive one layer down from the fix. The ordering is now explicit:
establish the target lineage and consult its committed exact-source evidence
without requiring the source objects; only if fresh reconciliation is needed
does the operation require the live source. SourceNotInRepository may refuse a
new operation but never veto a historical lookup, and NoAbsorptionRecorded needs
a complete walk. AlreadyAbsorbed was holding two facts and is renamed
SourceOnTargetParentChain -- ancestry membership is not receipt-backed
absorption, and the four-outcome count must not be preserved by folding the
receipt answer back in. Identity non-reuse is stated as a requirement rather
than left to collection scheduling.
D5 was wrong at the contract, not the field list, and contradicted this
document's own section 1. supersession is a malformed-document replacement
policy: standing_permission_refusal answers none for LoadDocumentMalformed
ALONE. Ordinary merge into a healthy repository would have reached
StandingDoesNotPermit { standing: LoadComplete } -- refused in exactly the
normal case. The policy is not weakened to fit; supersession stays precedent for
the SHAPE, and merge publication owes its own admission contract. The candidate
now binds the whole derivation including the authored snapshot;
PublicationFailed must be ESTABLISHED not to have applied, with
PublicationUnestablished preserved otherwise; retirement checks the source at
retirement time and yields IntegrationCompletedRetirementWithheld when it moved.
Also: section 10 still listed fast-forward as open after D2 ruled it, and
section 3's "does not need to persist" and "exactly one checked out" premises
were quietly deciding the ref model -- the second drops the unborn repository
the current RepositoryCommitRef? already holds.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
briansrls
left a comment
There was a problem hiding this comment.
APPROVE — DESIGN-ONLY PR #10522 at exact head d45df93.
D1–D5 are closed at design-contract scope. There is no remaining blocking finding from reviews 5120053195 or 5120233720. This is approval to land this documentation-only design, not approval of an implemented merge capability, a demonstrated structural algorithm, or an existing durable publication actuator. No execution evidence is claimed, credited, or required to close these design findings. Repository-required protections remain independent; no merge operation has been performed.
REVIEW SUBJECT AND PRESERVATION
I read the complete current document and PR body, the intervening commit and its changed-file census, and the two prior review submissions. d45df93 is a direct child of the previously reviewed e4adbbc. The delta changes only docs/plans/scm-merge-design.md; the previously inspected source authorities are unchanged. The current PR still names the reviewed full SHA immediately before this submission.
D1 — CLOSED AT THE ACTUAL DECISION
Section 4 now requires the target-lineage/exact-source receipt lookup BEFORE any source-object requirement. A repeated request for S after M(parent=T, receipt=S) is answered from committed target-lineage evidence, rather than falling through to another merge merely because S is not a parent. Collection of S cannot veto that historical lookup. SourceNotInRepository is assigned to fresh work requiring the unavailable source; NoAbsorptionRecorded requires a completed target walk, and an unwalkable target is not a negative observation.
SourceOnTargetParentChain now names ancestry membership only. It is distinct from receipt-backed historical integration and from a newly computed unchanged result. The absorbed-then-reverted distinction is preserved, and an explicit request to reapply is not silently suppressed by either historical answer. Source identity continuity/non-reuse is now a stated requirement rather than an assumed consequence of retaining an ID value. This remains exact source-commit identity, not merely equality of program content or reuse of a branch spelling; the concrete identity/retention realization must satisfy that promise.
Section 9 now places the discriminators at the merge DECISION: repeated requests, collected sources, another target lineage, later target commits, and never-absorbed work whose fresh result is unchanged. Those are future evidence obligations, not claims that these specimens have executed.
D5 — CLOSED AS AN HONEST PUBLICATION/RETIREMENT CONTRACT
The document and PR body withdraw the supersede_head_slot route rather than modifying its malformed-document policy. Supersession remains a shape precedent. The generic durable-CAS shape and save_repository are explicitly nearby-but-insufficient, with their missing binding/unconditional-write limitations retained. The document no longer claims an existing ordinary-publication actuator through those names.
The candidate binds the repository/target slot, exact observed target commit/state, source identity, base evidence, interpretation/rule inputs, author resolution and resulting AUTHORED SNAPSHOT. Publication is conditional on the same observation; commit M, its receipt and target advancement must become coherently available. An uninstalled receipt cannot answer D1, and retirement consumes publication-success evidence rather than a candidate.
PublicationFailed now means established non-application. Install-then-lose-ack is PublicationUnestablished unless a realization proves that ambiguity excluded; it is reconciled, not blindly replayed. With no established success, there is no success evidence with which to authorize source retirement. A later attempt remains conditional on its exact target. This specifies the obligation; it does not claim a realization already provides it.
Source retirement is checked at retirement time, including movement AFTER successful publication. S -> S2 yields IntegrationCompletedRetirementWithheld and preserves S2 instead of destroying unabsorbed work or relabeling a successful integration as failed. Collection must respect other live references. The future evidence list now includes healthy-repository publication, installed commit/receipt/target coherence, uninstalled-receipt exclusion, post-publication source movement and failed-publication non-retirement. The full implementation contract also includes the explicitly preserved PublicationUnestablished case; a selected test list cannot narrow that contract.
PRESERVED CLOSURES
D2: single-parent squash remains mandatory for new integrations even when content reconciliation is trivial. The direct-install-S history shortcut remains forbidden, its discriminating future mutation is retained, and section 10 no longer calls fast-forward open. The preserve-both-lines condition is a possible future workflow change, not a current unmet requirement to add a multi-parent arm.
D3: the existing path-to-authored-source manifest remains authoritative for authored snapshots; structural interpretation/correspondence are derived views. Section 6 now carries that corrected output authority too. The false dependency blocking the authored-snapshot primitive and add/commit behind structural merge is removed. Acquisition, the commit-root/codec/consumer transition, and safe publication still owe their own work; this approval neither performs those cuts nor discharges them.
D4: correspondence/composition are explicitly required before automatic structural reconciliation; content IDs alone are not occurrence identity or evidence of independent edits. Unsupported correspondence remains a named inability to decide, not a guess or silent fallback. Feasibility, usefulness, and full-path performance are not established by this design and are not being credited.
NONBLOCKING TEXT RESIDUE / SCOPE
Section 3 now expressly withdraws 'eventual deletion implies no persistence' and 'exactly one checked out' as universal deductions, preserving the empty/unborn state. The older Proposal paragraph immediately below still literally repeats 'exactly one ... checked out' and the necessity-of-names argument. I do not credit those as approved invariants: the explicit withdrawal and still-open ref layout govern. Reconcile that proposal when resolving the open ref design; this editorial residue is not a reason for another blocking review round after the operative constraint has been withdrawn. Explicit target/source roles and commit identities remain an admissible operation interface; the UI may resolve names separately.
Similarly, section 6's 'Four outcomes' lead-in is not an exhaustive result schema: its own text now additionally requires PublicationUnestablished and names successful-publication/retirement outcomes. The case obligations, not that maintained count, govern the future carrier.
Compatibility projection remains presentation of native evidence, not semantic admission or a durable Applied receipt. Ref layout, physical retention scheduling, author/timestamp acquisition, the first demonstrated structural domain, and the concrete publication realization remain appropriately unimplemented/open within the stated constraints.
DISPOSITION
Approved to land this design-only head under the standing reviewer-approval rule, without waiving repository protections or authorizing another head. No new code, two-parent model, clock, execution run or further blocking document rewrite is requested here. The prior request-changes dispositions can be retired because their findings have been answered by content, not merely because the head advanced.
D1 and D5 are closed by the inspected design at d45df93, recorded in APPROVE review 5120257308. The merge decision now consumes target-lineage receipt evidence before requiring source objects; publication has its own exact-subject admission/coherence contract rather than the malformed-document supersession route; unestablished publication and post-publication source movement preserve their distinct outcomes. D2's stale open statement is removed, D3/D4 remain closed, and the explicit ref-premise withdrawal governs the remaining nonblocking proposal wording. Dismissed because the findings are answered by content, not merely because the head moved. Approval is limited to this exact design-only head, does not credit implementation or execution, and does not waive repository protections.
Nonblocking leftovers named in the approving review. Section 3's Proposal still said 'exactly one of which is checked out' after the paragraph above it withdrew that premise, and section 6 still said 'Four outcomes' while its own text requires PublicationUnestablished plus publication-success and retirement outcomes. Both are stale counts standing beside their own corrections, which is the same class as the fast-forward leftover in section 10. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
…aid so too review 60770 is correct and the finding is bigger than the paragraph it names. Section 8 claimed this repository has no modelled clock and no modelled process identity, and pointed the lane at acquiring them. Both exist on main: extdeps.clock declares Clock.Now, gunbc.clock_read clock_now_probed_at already consumes it and returns an OPTIONAL, probed_at_word renders the absent arm as a loud word, and gunbc.worker_lifecycle ProcessIdentityEvidence carries the observed/unobserved split. The observe-type-admit-or-refuse discipline section 8 was asking to have built is already built. gunbc.scm.ancestry carries the same stale claim, and the design note relayed it rather than checking it -- so the correction lands in both places rather than leaving the source to be relayed again. What is actually undecided is narrower and is an ADMISSION ruling about this subject: does a RepositoryCommit admit an unreadable clock or an unobserved identity, and what does such a commit mean. Merge sharpens that question, and is an argument for refusing rather than admitting. This is the fourth time in this lane's reporting that absence was claimed without grepping for the symbol first. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
|
Fixed at
Two changes rather than one:
Recording the pattern rather than just the fix: this is the fourth time in this lane's reporting that absence was claimed without grepping for the symbol first — the earlier three were a roster counted at 4 against an actual 17, an instrument deciding from 2 of 3 arms, and |
briansrls
left a comment
There was a problem hiding this comment.
DESIGN RE-REVIEW — REQUEST_CHANGES at 11d71b7 for one new design finding, D6, in the metadata prerequisite correction. D1–D5 remain closed. The ancestry annotation correction belongs in this PR; no split is requested.
I inspected the complete comparison from approved d45df93, the changed section and source annotation, the current PR body, and the exact-head extdeps.clock, gunbc.clock_read and gunbc.worker_lifecycle authorities. The comparison contains two descendant commits and two changed paths: docs/plans/scm-merge-design.md and dag/gunbc/scm/ancestry.dag. The .dag changes are ordinary // commentary; no imports, declarations, signatures or executable bodies changed. The prior ref-cardinality/outcome-count leftovers are repaired. I did not independently run the reported typecheck, and no execution evidence is required for this documentation/commentary finding.
CORRECTION TO MY OWN PRIOR DISPOSITION
The earlier repository-wide no-clock/no-process-identity-model premise was wrong. I repeated it in earlier review discussion and allowed it to stand in approval 5120257308 instead of independently checking the capability claim. The cited clock and process-evidence authorities already exist at this head and are unchanged from the approved head. The prior approval is therefore not evidence for that premise. This does not undo D1–D5's separate inspected closures.
ACCEPTED SCOPE AND CONTENT
Keep the ancestry annotation correction with the design correction. It repairs the source of the stale premise, rather than leaving it available for the next design to repeat. The prior restriction to one Markdown file was the inspected change census, not a rule that a related source-comment correction must be a different PR. This remains a design/rationale change, not a new runtime capability.
Clock.Now is genuinely a declared read-only operation in dag/extdeps/clock/clock.dag. clock_now_probed_at genuinely calls it, returns Absent for an empty timestamp and Present for a nonempty one. probed_at_word consumes that same optional reading and renders Absent as clock-unreadable. A new generic clock acquisition is not justified by the old premise.
ProcessIdentityEvidence also genuinely exists. However, what the inspected worker_lifecycle module supplies is a carrier for worker-process evidence and its projections. That is not equivalent to a demonstrated observation and attribution route for a RepositoryCommit.
D6 [P2] — 'THE OBSERVATION SIDE IS SOLVED' PROMOTES AN EVIDENCE CARRIER INTO A COMMIT-ATTRIBUTION CAPABILITY.
Locations: docs/plans/scm-merge-design.md section 8, especially 'The observation side is solved' and the observed-process carrier as 'the other half'; dag/gunbc/scm/ancestry.dag's new assertion that both capabilities already have the necessary discipline and admission is 'the only thing blocking these two fields'.
The new absence correction is right, but the stronger completion claim does not follow from the cited symbols:
-
ProcessIdentityEvidence = ProcessIdentityObserved { pid, started_at, owner } | ProcessIdentityUnobserved { reason } defines representable evidence states. In the cited module, process_identity_evidence_label matches those states; there is no operation there that reads the host and produces the observed triple. I also searched the default-branch index for the observed/unobserved names; that search did not establish a commit-attribution producer. That is NOT an exhaustive exact-head absence census, and I am not claiming no suitable producer exists elsewhere. The finding is that this cited type/renderer does not establish the positive capability claim.
-
Even a correctly observed worker-process triple answers a different question from authorship. Two changes authored by different principals can be submitted by the same worker process, with the same PID, start time and owner. Those identical inputs cannot identify which principal authored each change. 'owner is the author', 'the process is the committer', and 'this is executor audit evidence' would be distinct declared contracts, not consequences of the ProcessIdentityObserved constructor name. Similarly, process started_at is not automatically an authoring or publication timestamp.
-
The clock wrapper provides an optional NONEMPTY STRING, not by itself a subject-bound commit timestamp. It checks empty versus nonempty text. Its renderer intentionally produces another NonEmptyStr for the absent case. Therefore neither the return type nor accepting a rendered nonempty value proves that an instant was observed. Keep the optional observation separate from display text, retain the Clock.Now operation's own failure contract, and state which event/reading the eventual commit field will denote. This is not a demand to redesign the existing clock helper or build a second time model.
The document's last sentence already recognizes binding as pending; keep that honest limit throughout rather than pairing it with 'observation solved' and the annotation's 'only admission remains'.
REQUIRED DESIGN REPAIR — NO PRODUCER IMPLEMENTATION REQUIRED HERE
Replace the solved-observation/only-admission claims with the bounded census: an existing clock operation and adapter are reusable; a process-identity evidence vocabulary exists; the applicable observed producer, the relation of that observation to this commit and its actor/author role, timestamp event meaning, and subject-specific admission remain to be established. Reuse any existing producer whose inspected contract actually supplies those facts. If no applicable producer has been established, say that; do not convert that limitation into either a repository-wide absence claim or an instruction to reinvent the generic clock/identity shapes.
It is sufficient for this PR to leave those specific binding/meaning questions open, with their missing-evidence outcomes explicit. It need not implement an observer, add author/timestamp fields, choose the ultimate admission policy, or prove a new execution result. The author-versus-executor distinction must not be silently answered by copying owner into an author field.
Apply the correction to both new passages. Also reconcile ancestry's retained closing sentence, 'So modelling them here would mean inventing two facts to fill fields': absence of an admitted subject binding is a reason not to fabricate a value, not a proof that modeling fields using existing observation carriers inherently fabricates facts.
PR-BODY CONSISTENCY
The current PR body still says, under 'Left open, and marked open', 'since there is no modeled clock and no modeled process identity to observe them with'. I rechecked it immediately before this review. That is the exact false prerequisite being corrected, still in the current landing description. Replace it with the narrower open contract as well. This is not a request to rewrite historical commits or another reviewer's receipt.
ADMISSION RULING BOUNDARY
Refusing publication when evidence REQUIRED BY ITS DECLARED METADATA CONTRACT is unavailable is a defensible policy. That does not follow merely from the word merge or from calling a receipt weak: the exact source/base/target/result relation already conveys a meaningful integration fact. Decide what attribution and instant the fields claim before deciding which missing observations prevent that kind of publication. A less-attested snapshot can legitimately preserve explicit absence if the chosen contract admits it; it must not present absence as observed data. Neither policy is implemented or authorized by this review. Any chosen prepublication evidence requirement must compose with D5's applied/failed/unestablished publication distinction rather than retrospectively treating an applied write as never applied.
PRESERVATION AND DISPOSITION
D1's receipt-first decision, D2's single-parent squash policy, D3's authored-snapshot authority and removal of the false merge dependency, D4's bounded correspondence obligations, and D5's exact-subject publication/retirement contract are preserved by the inspected delta. No request for a two-parent arm, new clock, structural solver, seed-growth row, split PR or execution run is made here.
D6 is a new overclaim in the correction, not a reopening of those repaired contracts. Keep the source-comment correction; narrow what its citations establish and synchronize section 8, ancestry's note and the current PR description. No merge authorization at this head.
Withdrawing approval after independently verifying that its retained author/timestamp prerequisite rested on a false repository-wide absence claim: the existing clock operation/adapter and worker process-evidence vocabulary were already present. This is a substantive correction to my prior disposition, not dismissal solely for head movement. D1-D5 remain closed by inspected content. Exact-head review 5120366090 at 11d71b7 records new D6: the repair now overstates a worker evidence carrier as a solved commit-observation/attribution capability, and the current PR body still repeats the old absence claim. No merge authorization at that head; no split or execution run is requested.
D6. My clock correction swung past the truth: I wrote that the observation side is solved and only admission remains. That is the same defect one level up -- finding an evidence type is not a solved observation capability. The tell is in the helper I cited as proof: probed_at_word returns a NonEmptyStr on BOTH arms, rendering absence as "clock-unreadable", so accepting a rendered nonempty value would not establish that an instant was observed. Display text is not admission input, and a clock read is not automatically a timestamp bound to this commit. Section 8 now states the bounded contract -- clock and identity carriers are reusable, and commit metadata still needs an applicable observation producer, a binding to this commit and its declared attribution role, a defined timestamp event, and only then an admission policy -- and records both errors, because the pair is more instructive than either. The four pieces are ordered: admission comes last because it cannot be decided before the field's subject and applicable evidence are. The earlier lean toward refusing is withdrawn. Source/base/target/result already expresses a meaningful integration fact; attribution and time support additional claims, and which missing observation blocks publication depends on what those claims are. The constraint that survives either policy is that absence is never rendered as observed evidence. One composition obligation with D5: a metadata check must refuse before a write, since a miss found after one does not make an applied publication established never to have applied. The ancestry annotation's retained conclusion is corrected with it. "Modelling them here would mean inventing two facts" needed the missing qualifier: with no producer and no binding established. An unverified binding is a reason not to fabricate a value, not proof that modelling over existing carriers fabricates anything. The PR body still carried the original false prerequisite; corrected there too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
briansrls
left a comment
There was a problem hiding this comment.
APPROVE — PR #10522 at exact head b4e2008, at design/rationale scope (Markdown plus ordinary source comments).
D6 from review 5120366090 is CLOSED by the inspected content. D1–D5 remain closed. No blocking finding remains from my review. This approval authorizes landing this exact design/commentary head under the standing reviewer-approval rule; it does not waive repository protections, establish an implemented merge capability, or credit a metadata observer/publication actuator as built. No merge operation has been performed.
SUBJECT AND PRESERVATION
I inspected the complete intervening commit patch and changed-file census, the current section 8 and ancestry annotation with their surrounding text, the current PR body, and the exact-head clock_read and worker_lifecycle contracts. The Git commit record identifies b4e2008 as a direct child of reviewed 11d71b7. Only docs/plans/scm-merge-design.md and dag/gunbc/scm/ancestry.dag changed; the latter delta is ordinary // commentary only. There are no changed imports, declarations, signatures or executable bodies. The cited clock helper and process-evidence carrier retain their previously inspected blob identities. I checked that the live PR still named the full reviewed SHA immediately before this approval.
D6 — THE POSITIVE CLAIM IS NOW BOUNDED TO WHAT THE SOURCES ESTABLISH
Section 8 records both errors without leaving either as the governing conclusion: repository-wide absence was wrong, and finding an existing evidence type did not establish a complete commit-attribution observation path. Its governing statement now distinguishes reusable clock operations/adapters and process-evidence vocabulary from the applicable producer, binding to this commit and its declared attribution role, timestamp event meaning, and admission for unavailable evidence. The complete path is explicitly not established here; the document neither declares it absent everywhere nor directs reinvention of a generic clock or identity schema.
The original counterexamples now meet explicit constraints:
- A ProcessIdentityObserved value is not promoted merely by its constructor name into authorship of this commit. The applicable producer and the declared attribution relation remain obligations. Process owner, executor, committer and author are not made equivalent by this approval.
- probed_at_word returns NonEmptyStr for both Present and Absent. Its clock-unreadable rendering is therefore not positive observation evidence. Section 8 and the source note now require retaining the observation's failure contract rather than admitting its rendered text. This is a limit on the consumer, not a request to redesign the renderer or invent another clock.
- The timestamp event remains explicit and unresolved. Process start, authoring, integration and publication do not acquire the same meaning merely because their values can be rendered as timestamp text.
The admission ordering is accepted as a dependency: decide the field's claimed subject, applicable evidence and binding before deciding which missing evidence bars that publication. This is not an instruction to perform admission after a write, nor a requirement to implement the first listed observer before establishing what it must observe.
The earlier blanket refusal lean is withdrawn. The source/base/target/result relation already has an integration meaning; additional attribution and time claims determine their own evidence requirements. An explicitly less-attested contract and a contract requiring an identified integrating actor are different choices. Neither may present absence as an observed fact. This review does not select or implement the final policy.
D5 COMPOSITION IS PRESERVED
The new paragraph correctly places required missing-metadata checks before an effect they are meant to prevent. A later missing observation cannot reclassify an applied write as established non-application. PublicationFailed, PublicationUnestablished, coherent committed evidence and retirement's dependency on publication success retain their prior meanings. No claim is made here that the eventual realization can observe an exact publication instant in advance; timestamp event meaning and the realization remain to be established.
ANCESTRY AND LANDING DESCRIPTION
The source annotation now states the producer/binding/event/admission obligations and qualifies its former conclusion about inventing field values. Lack of an established producer or binding is a reason not to fabricate a value; it is not a prohibition on modeling fields over reusable carriers. The annotation's earlier language about existing capabilities is credited only at that explicitly bounded clock/evidence-vocabulary scope, not as certification of a complete SCM attribution path. Its new, specific outstanding obligations govern that applicability.
Keeping this correction in the same PR remains appropriate: it repairs the source of the false prerequisite as well as the design that repeated it. No split or seed-growth row is requested.
The current PR body's open-items section is also corrected. It no longer presents the no-clock/no-process-identity premise as the current prerequisite, and explicitly names the same bounded metadata contract and display-versus-evidence distinction. This closes the landing-description consistency item as well as the two changed passages.
PRESERVED DESIGN CLOSURES AND EVIDENCE LIMIT
The delta leaves the receipt-first merge decision, single-parent squash/no direct-install-S policy, authored-snapshot authority, bounded correspondence obligations, and exact-subject publication/retirement contract unchanged. The earlier ref-cardinality and outcome-count corrections also remain unchanged. The false structural-merge dependency on manifest/add/commit work remains removed; acquisition, commit-root/codec/consumer work and safe publication still owe their own implementation evidence.
No clock read, typecheck, witness run, or durable publication has been independently executed or credited in this review. None is required to close this design/commentary finding. Repository-required checks remain an independent condition of landing. Metadata binding, the applicable producer, timestamp subject and admission policy remain open requirements, not failed conditions of this documentation PR.
The earlier approval's false absence premise is not retroactively validated by this repair; its correction stands. The new approval is based on this head's bounded claims and preserved contracts. Review 5120366090 may be dismissed because D6 is answered by content, not merely because a push made it older.
DISPOSITION: Approved to land this exact head. No further blocking document rewrite, producer implementation, new generic clock, structural solver, split PR or execution run is requested here.
D6 is closed by inspected content at b4e2008, recorded in exact-head APPROVE review 5120395198. Section 8, ancestry's comment and the current PR body now distinguish reusable clock/evidence vocabulary from the still-required producer, commit/role binding, timestamp event and admission policy; display text is not observation evidence, and missing metadata cannot retroactively turn an applied write into non-application. D1–D5 remain preserved. Dismissal is for the repaired finding, not head movement. Approval is design/commentary only, does not credit an implemented observation or publication route, and does not waive repository protections.
…mmit cut (#10555) * Correct the rebuild plan's manifest shape before it steers the next consumer The paragraph that existed to stop the next reader following a dead recipe had itself become one. It said add and commit are blocked on building a CorpusManifestObject shaped path -> semantic_root -> authored_source_identity. Both halves are false: the object exists in gunbc.scm.object_store and is coded by object_table_json, and its entry is { path, source } -- path to authored source, deliberately not to a semantic root, because fusing them makes a manifest unauthorable for malformed or not-yet-ingested source. #10522 section 5 ruled the same separation. A second passage further down repeated the same wrong shape and is corrected with it. DESIGN section 3 names this exactly: while a superseded structure stands, every nearby question gets answered in its vocabulary. This one was positioned to decide the add/commit cut. The corrected boundary states what is actually pending -- a workspace-scoped authored-source snapshot shared by add, status and commit -- and records three obligations the old text did not: status moves with this cut rather than rendering "nothing staged" while source changes are staged; staging carries the same conditional-write obligation as publication, which save_repository does not supply since it writes unconditionally; and an established unchanged candidate is not an unreadable stage. No code changes. The staging carrier itself waits on the commit-root ruling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9 * Withdraw the recipe and the outcome sketch this PR had re-endorsed review 5120884296, both findings confirmed at source. R2 is the sharper one. The corrected paragraph said ScmWriteOutcome is still the right shape, which positively certified a sketch that is unsound: RepositorySave carries three failure arms, so ScmWritePersisted { save: RepositoryFileUnwritable } is constructible and a renderer selecting the outer Persisted arm announces persistence while its payload says the file was unwritable. ScmWriteRefusedByMint accepts RepositoryCommitMinted symmetrically. The outer classification and the inner payload can disagree. Replaced with the governing requirement -- a success outcome carries established success evidence for that exact operation -- and the sketch is kept visible as the instructive half rather than deleted. R1: two adjacent sections still instructed the reader to do the opposite of the corrected boundary. "The design step" prescribed store_node plus save_repository, neither of which supplies the staging contract, and "add has no staging authority" called immediate object-store insertion the honest reading of add. That section's premise stands and its conclusion is withdrawn: it picked the branch cheapest to build, and insertion cannot say which paths are selected, nor be revised or cleared. A maintainer following those sections still reached the implementation this PR exists to prevent. Also narrowed "add is not blocked" to the dependency actually removed. Host acquisition, path admission, durable selection and conditional update remain work; a removed dependency is not a finished verb. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9 --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
The merge lane has been blocked on model, not effort.
gunbc.scm.mergeis roles/requirements/supersession — it is not two-commit merging, despite the name. This records the design ruling before any merge code exists.It is written first because a merge and publication consumer, once cut, fixes the vocabulary every nearby question is then answered in — and cutting it against an unproven correspondence contract is the §3 replacement-migration trap.
Correction: the earlier revision of this PR reasoned from a false census
The first cut opened by saying §5's question decides the shape of
CorpusManifestObject, and ruled that the manifest is "a projection for emission, not the authority a merge reads". Both were wrong.CorpusManifestObject,CorpusManifestEntry { path, source }andCorpusManifestRecordalready exist ingunbc.scm.object_store, andgunbc.scm.object_table_jsonalready encodes and decodes them.What has not changed is
RepositoryCommit.root, stillSemanticNodeObjectRef. So the pending boundary is a consumer / commit-root cut, not a missing object kind — materially smaller than "build the keystone", and it means the manifest is not blocked behind merge, soadd/commitare nearer than this lane previously reported. Both corrections are recorded in place in the document rather than rewritten away.The central ruling: no two-parent arm
A squash result is single-parent, so
CommitAncestry = RootCommit | DescendsFrom { parent }is already correct and must not gainMergedFrom. An arm with no producer is what §4b calls worse than absent.The stronger reason is that it would be actively wrong:
ancestry_walkfollows parents, so a second parent would make the walk traverse the line the workflow exists to discard — "kill dev history" would be false at exactly the layer that answers questions about history.What this revision repairs
NoAbsorptionRecordedfor work that was integrated. Ruled: reconciliation may be trivial; publication is uniform — always a new commit withDescendsFrom { parent: A }plus a receipt naming S.ancestry.dag's two-commit next-rung trigger is superseded (the consumer arrived and does not want the arm) and is replaced, not deleted — a trigger removed with nothing in its place is an untracked stall.EdgeLabel, is the tractability boundary.ObjectIdrecognizes unchanged content; it does not identify one logical declaration across an edit. Changed ancestors, shared subtrees and renames bound the claim, and structural disjointness does not establish independence. The first capability owes three answers: what evidence establishes correspondence, what the automatic arm guarantees, and what it returns when either is unavailable — a named inability to decide, never a guess.object_storerecords its own list-backed lookup as quadratic. Fewer reported conflicts is also not evidence of improvement.observe_generation/supersede_head_slot, contradicting this document's own §1. Verified at source:standing_permission_refusalanswersnoneforLoadDocumentMalformedalone, so an ordinary merge into a healthy repository would reachStandingDoesNotPermit { standing: LoadComplete }— refused in exactly the normal case. The policy is not weakened to fit;supersessionstays precedent for the shape. The candidate now binds the whole derivation including the authored snapshot;PublicationFailedmust be established not to have applied, withPublicationUnestablishedpreserved otherwise; retirement checks the source at retirement time and yieldsIntegrationCompletedRetirementWithheldwhen it moved.AlreadyAbsorbedwas holding two facts and is nowSourceOnTargetParentChain.AncestryTracedlisted as reaching a refusal. It is the success arm; it owes the four traced/traced outcomes instead. D1, D2, D4 and D5 controls are added — including the mutation that advances the head onto S's tip, which must go red because that mutation is the loophole.Left open, and marked open
The ref model's placement and object retention for absorbed lines. The fast-forward question is no longer open; it is ruled.
Author/timestamp is a bounded metadata contract (§8), and this PR body previously carried the false prerequisite too. Clock operations and a process-identity evidence vocabulary already exist and are reusable —
extdeps.clockClock.Now,gunbc.clock_read,gunbc.worker_lifecycleProcessIdentityEvidence. What commit metadata still needs is an applicable observation producer, a binding to this commit and its declared attribution role, a defined timestamp event, and only then an admission policy for unavailable evidence. This document does not establish that the complete commit-attribution path exists, and does not direct creating another generic clock or identity schema. Note the trap it turns on:probed_at_wordreturns aNonEmptyStron both arms, so a rendered nonempty value does not establish that an instant was observed — display text is not admission input.Evidence
No code, so no execution evidence is claimed. §9 enumerates what the implementation will owe so it cannot later be declared done by typecheck.
🤖 Generated with Claude Code
https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9