Skip to content

Ground fnv1a64 hash fork: unify v2.std.node.Hash with std ContentHash - #6686

Merged
briansrls merged 11 commits into
mainfrom
session/loyal-carp-400
Jul 15, 2026
Merged

briansrls merged 11 commits into
mainfrom
session/loyal-carp-400

Conversation

@briansrls

@briansrls briansrls commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Ground the DESIGN.md §3 fnv1a64 dual-surface convergence thread on the v2 carrier: v2.std.node.Hash = std.types.ContentHash, with content_hash / combine_hash / symbol_identity_digest routing through std.content_hash instead of raw builtins.
  • Switch v2.std.materialize to key on ContentHash directly — the same identity RealizationPlan.target carries — so materialize dedup and schedule planning share one hash authority.
  • Add a witness (node_content_hash_is_realization_plan_target) proving node content_hash is assignable to the ContentHash carrier; update DESIGN.md open thread.

Remaining (out of scope): ground v1.compiler.dag_collect_support fingerprint calls through std.content_hash when v1-stage v2 adoption clears.

Test plan

  • cargo run -p v1-compiler --bin claim_batch -- --source-root src/v2 --source-root dag --entry src/v2/test/claim/materialize/materialize_witness_test.dag --function <each> — 7/7 PASS
  • ctrl-build -- cargo test -p v1-compiler-tests b1_hash_primitive — 7/7 PASS
  • claim_batch compile check on src/v2/workflow/bootstrap.dag and src/v2/test/claim/parse/parse_table_content_key_test.dag (no type errors)

Dissolve the dual-surface fork between v2.std.node.Hash (materialize's
content_hash key) and std ContentHash (RealizationPlan.target): node
internals route through std.content_hash; materialize keys on ContentHash;
Hash remains a backward-compatible alias for existing importers.

Witness: materialize_witness_test proves node content_hash is assignable
to the RealizationPlan.target carrier. DESIGN.md §3 thread updated.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot
gunbai-bot Bot force-pushed the session/loyal-carp-400 branch from 103848d to 1953b21 Compare July 15, 2026 18:30
@gunbai-bot gunbai-bot Bot changed the title Ground the fnv1a64 dual-surface hash fork as ONE authority: v2.std.node.Hash (materialize's content_hash key, src/v2/std/materialize.dag:3,13) vs std ContentHash (dag/std/content_hash.dag; RealizationPlan.target). This is the pre-existing DESIGN.md §3 convergence thread (v1.compiler.dag_collect_supp Ground fnv1a64 hash fork: unify v2.std.node.Hash with std ContentHash Jul 15, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review July 15, 2026 18:30
Brian Searls and others added 3 commits July 15, 2026 18:36
…ndary.

hash_combine/atom_identity_hash return the v1 primitive Hash carrier;
explicit `as ContentHash` at the single authority prevents if-branch
Product(ContentHash) vs Primitive(Hash) mismatches in v2.std.node.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ize keys.

Replace tautological self-comparison with a discriminating witness: plan.target
must appear in materialize's distinct_hashes for the fixture root and must not
appear for a different-root fixture — exercising the RealizationPlan.target
carrier against materialize's ContentHash keys.

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@briansrls
briansrls merged commit 4a60303 into main Jul 15, 2026
3 checks passed
@briansrls
briansrls deleted the session/loyal-carp-400 branch July 15, 2026 23:46
gunbai-bot Bot pushed a commit that referenced this pull request Jul 16, 2026
…poisoning surface)

The floor's inert_carrier_no_unrostered_or_stale witness reds without it:
the LocalAlias fixture it rosters landed in #6641, not #6686 — the roster
line was a bundled orthogonal fix (same class as the kept cli_run.rs
backfill), not part of the hash-grounding surface. Receipt: local floor on
the revert tree, 300 PASS / 1 FAIL (this witness), FAIL clears with the
line restored.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Jul 16, 2026
…port x #6663 field wall)

Partial revert of 4a60303: src/v2/std/node.dag, materialize.dag,
materialize_witness_test.dag, inert_carrier.dag, and the DESIGN Sec-3-thread
note pair (carrier + generated doc together). Keeps #6686's orthogonal
cli_run.rs nfr-roster backfill (reverting it would re-red the falsifier lane).

Root cause (proven by execution): #6663's new MissingField presence check
resolves a literal's expected type by unqualified name through the flat module
type env; #6686's 'import std.types { ContentHash }' in v2.std.node pulls
dag-root std.algebra into the typecheck closure of every v2 module importing
v2.std.node (704 files), so dag-root Monoid/Semigroup/BooleanAlgebra/
OrderedRing/CommutativeMonoid/CommutativeSemiring/AbelianGroup shadow the
v2.std.algebra declarations at 28 literal sites in
src/v2/std/{diagnostic,logic,nat,integer}.dag -> ci_floor_plan resolve fails
-> every main push red. Neither PR alone was red: zero file overlap, merged
31 minutes apart, and the squash union tree was never CI'd (the PR's only CI
run began 8 minutes before #6686 landed).

Receipt: on the 60286e0 tree with the same seed binary, reverting exactly
this .dag surface takes the plan resolve from 28 missing-required-field errors
to green with the floor executing witnesses (control: #6678/#6685 left in
tree).

Re-land trigger (dissolution): the wall's presence leg consults the resolver's
binding (or fails closed on ambiguous names) instead of the flat-env name
lookup; the follow-up re-lands these files with that fix, using this exact
28-error tree as the RED control.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Jul 16, 2026
…poisoning surface)

The floor's inert_carrier_no_unrostered_or_stale witness reds without it:
the LocalAlias fixture it rosters landed in #6641, not #6686 — the roster
line was a bundled orthogonal fix (same class as the kept cli_run.rs
backfill), not part of the hash-grounding surface. Receipt: local floor on
the revert tree, 300 PASS / 1 FAIL (this witness), FAIL clears with the
line restored.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Jul 16, 2026
…main-red root fix) + fmt-immune crate-layout emitter (#6701)

* Unbreak main: revert #6686's v2 hash-grounding surface (cross-root import x #6663 field wall)

Partial revert of 4a60303: src/v2/std/node.dag, materialize.dag,
materialize_witness_test.dag, inert_carrier.dag, and the DESIGN Sec-3-thread
note pair (carrier + generated doc together). Keeps #6686's orthogonal
cli_run.rs nfr-roster backfill (reverting it would re-red the falsifier lane).

Root cause (proven by execution): #6663's new MissingField presence check
resolves a literal's expected type by unqualified name through the flat module
type env; #6686's 'import std.types { ContentHash }' in v2.std.node pulls
dag-root std.algebra into the typecheck closure of every v2 module importing
v2.std.node (704 files), so dag-root Monoid/Semigroup/BooleanAlgebra/
OrderedRing/CommutativeMonoid/CommutativeSemiring/AbelianGroup shadow the
v2.std.algebra declarations at 28 literal sites in
src/v2/std/{diagnostic,logic,nat,integer}.dag -> ci_floor_plan resolve fails
-> every main push red. Neither PR alone was red: zero file overlap, merged
31 minutes apart, and the squash union tree was never CI'd (the PR's only CI
run began 8 minutes before #6686 landed).

Receipt: on the 60286e0 tree with the same seed binary, reverting exactly
this .dag surface takes the plan resolve from 28 missing-required-field errors
to green with the floor executing witnesses (control: #6678/#6685 left in
tree).

Re-land trigger (dissolution): the wall's presence leg consults the resolver's
binding (or fails closed on ambiguous names) instead of the flat-env name
lookup; the follow-up re-lands these files with that fix, using this exact
28-error tree as the RED control.

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

* Keep #6686's LocalAlias inert-carrier roster line (orthogonal to the poisoning surface)

The floor's inert_carrier_no_unrostered_or_stale witness reds without it:
the LocalAlias fixture it rosters landed in #6641, not #6686 — the roster
line was a bundled orthogonal fix (same class as the kept cli_run.rs
backfill), not part of the hash-grounding surface. Receipt: local floor on
the revert tree, 300 PASS / 1 FAIL (this witness), FAIL clears with the
line restored.

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

* WIP: field-wall env precedence fix (scratch)

* WIP2: kernel/container guard + final regen

* Fix generated_artifact_drift_gate: make the crate-layout emitter fmt-immune (rustfmt::skip)

Batch-4 generated_artifact_drift_gate_passes red on this PR is the first run
of that gate since main broke at 60286e0 -- #6677 landed its derived
crate-layout artifact during the red window, so no tree ever executed batch 4
against it. Two writers disagreed on one artifact: the wet leg
(stage0_crate_layout_emit.dag) emits plain multi-line arrays, while the
committed bytes were rustfmt'd (trailing comma, collapsed one-liner). Committed
bytes: fmt-clean, drift-red; emitter bytes: drift-clean, fmt-red -- no tree
could satisfy both gates.

Fix: the emitter stamps #[rustfmt::skip] on both consts, so its output is the
fixed point of cargo fmt; artifact regenerated via main_wet. Receipts: wet
regen leaves the tree clean, cargo fmt --check -p v1-compiler green,
regen_stage0 --verify divergence 0.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jul 16, 2026
…ipline (#6698)

* Unbreak main: revert #6686's v2 hash-grounding surface (cross-root import x #6663 field wall)

Partial revert of 4a60303: src/v2/std/node.dag, materialize.dag,
materialize_witness_test.dag, inert_carrier.dag, and the DESIGN Sec-3-thread
note pair (carrier + generated doc together). Keeps #6686's orthogonal
cli_run.rs nfr-roster backfill (reverting it would re-red the falsifier lane).

Root cause (proven by execution): #6663's new MissingField presence check
resolves a literal's expected type by unqualified name through the flat module
type env; #6686's 'import std.types { ContentHash }' in v2.std.node pulls
dag-root std.algebra into the typecheck closure of every v2 module importing
v2.std.node (704 files), so dag-root Monoid/Semigroup/BooleanAlgebra/
OrderedRing/CommutativeMonoid/CommutativeSemiring/AbelianGroup shadow the
v2.std.algebra declarations at 28 literal sites in
src/v2/std/{diagnostic,logic,nat,integer}.dag -> ci_floor_plan resolve fails
-> every main push red. Neither PR alone was red: zero file overlap, merged
31 minutes apart, and the squash union tree was never CI'd (the PR's only CI
run began 8 minutes before #6686 landed).

Receipt: on the 60286e0 tree with the same seed binary, reverting exactly
this .dag surface takes the plan resolve from 28 missing-required-field errors
to green with the floor executing witnesses (control: #6678/#6685 left in
tree).

Re-land trigger (dissolution): the wall's presence leg consults the resolver's
binding (or fails closed on ambiguous names) instead of the flat-env name
lookup; the follow-up re-lands these files with that fix, using this exact
28-error tree as the RED control.

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

* Keep #6686's LocalAlias inert-carrier roster line (orthogonal to the poisoning surface)

The floor's inert_carrier_no_unrostered_or_stale witness reds without it:
the LocalAlias fixture it rosters landed in #6641, not #6686 — the roster
line was a bundled orthogonal fix (same class as the kept cli_run.rs
backfill), not part of the hash-grounding surface. Receipt: local floor on
the revert tree, 300 PASS / 1 FAIL (this witness), FAIL clears with the
line restored.

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

* WIP: field-wall env precedence fix (scratch)

* WIP2: kernel/container guard + final regen

* Fix generated_artifact_drift_gate: make the crate-layout emitter fmt-immune (rustfmt::skip)

Batch-4 generated_artifact_drift_gate_passes red on this PR is the first run
of that gate since main broke at 60286e0 -- #6677 landed its derived
crate-layout artifact during the red window, so no tree ever executed batch 4
against it. Two writers disagreed on one artifact: the wet leg
(stage0_crate_layout_emit.dag) emits plain multi-line arrays, while the
committed bytes were rustfmt'd (trailing comma, collapsed one-liner). Committed
bytes: fmt-clean, drift-red; emitter bytes: drift-clean, fmt-red -- no tree
could satisfy both gates.

Fix: the emitter stamps #[rustfmt::skip] on both consts, so its output is the
fixed point of cargo fmt; artifact regenerated via main_wet. Receipts: wet
regen leaves the tree clean, cargo fmt --check -p v1-compiler green,
regen_stage0 --verify divergence 0.

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

* MachineShape construction wall: compile gate + witnesses only.

Rebuilt from origin/main per operator recovery: three-file scope only
(lens, compile enrollment, claim witnesses). Stacked on #6687 for
std.machine_shape / extdeps.gpu.machine_shape subjects — no Phase 1
content copied. Removed unused std.algebra import that poisoned CI resolve.

Co-authored-by: Cursor <cursoragent@cursor.com>

* machine_shape gate: fail-closed Cons/Empty match (determinism precedent)

Replace is_empty + list_head/HeadAbsent absorb arm with Cons/Empty fold
match — HeadAbsent silently accepted on invariant violation (§5).

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls pushed a commit that referenced this pull request Jul 16, 2026
…haustive theorem

gunbc.merge_lifecycle (new): lifecycle dynamics over the existing
gunbc.merge_admission authority — the merge step consumes policy_admits,
never restates it. Squash lands the PR onto CURRENT main
(squash_result_tree); receipts mint through mint_merge_admission_receipt;
latest-receipt-per-PR matches GitHub required-check semantics; the
unverified-tip latch fires only where main advances.

test.claim.merge_lifecycle_interleaving_witness (new, floor-discovered):
the 2026-07-16 #6663 x #6686 main-red as the permanent RED fixture
(admitted under the live PerPrGateOnly policy, refused under KeyedReceipt,
remedy path lands verified), plus bounded-exhaustive enumeration of all
625 length-4 event interleavings: KeyedReceipt admits zero unverified
tips; PerPrGateOnly admits violations (enumerator-teeth control);
RequireUpToDateBase (GitHub's strict boolean) still misses the roster
axis. Quantifies gunbc.plans.branch_merge_admission_model section 4 over
every interleaving instead of two authored scenarios.

Additive checkpoint-1 extension: no enforcement flip
(merge_freshness_gating_status stays GatingComputedDeferred), no settings
change, no seed .rs touched. All 7 claims green by execution via
gunbc run --claim-run; whole-tree compile-clean 0 diagnostics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Jul 16, 2026
…ncyView edges

Today the scheduler collapses every DependencyKind (including DataDependsOn)
to a bare Bool via DependencyKindClassifier<Bool>, so shared-operand
structure — N consumers of one produced value — is invisible to batch
formation. This adds v2.workflow.operand_flow, a total derivation over
DependencyView edges producing OperandFlow | OperandFlowRefused rows:

- operand identity = the producer's content_hash (the same ContentHash
  identity v2.std.materialize keys Share on), derived via a
  DependencyKindClassifier<Bool> (only DataDependsOn carries an operand,
  matching the codebase's existing kind-dispatch idiom rather than a
  per-callsite match)
- footprint binds to the single node_keyed_graph_transitive_bytes authority
  in v2.workflow.realization_runner — no parallel size walk
- every non-applicable edge or unsettled/missing footprint yields a typed,
  located OperandFlowRefused row rather than being silently dropped, so
  refusals stay countable (DESIGN §5)

Scope: per docs/plans/machine-shape-orthogonal-scheduling.md §4, updated
today by PR #6687's allocation-as-contract redirect (footprint is plain
ByteSize, not Quantified<ByteSize>). The hash-authority precondition (§9)
is already resolved on main (#6686). Wiring CostAccount.space's
DerivedFrom fill into the live CI floor scheduler is explicitly out of
scope here — that's owned by a separate lane
(bounded_input_cost_envelope_scheduling.md P1) touching the load-bearing
ci_floor_plan.dag, and would be scope creep into another owned lane.

Witness: src/v2/test/claim/operand_flow_witness_test.dag — a fixture with
one shared operand and two DataDependsOn consumer edges asserts both
derive the same ContentHash with equal footprints; RED fixtures assert a
non-DataDependsOn edge and a missing-row footprint each refuse with a
typed cause. Verified green locally via claim_batch built from this
worktree (the earlier attempt with a sibling worktree's prebuilt binary
gave a stale false-negative on an unrelated existing witness too,
confirming it was a stale-binary artifact, not a real regression).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jul 16, 2026
…ncyView edges (#6729)

* Machine-shape Phase 2: OperandFlow — derived operand facts on DependencyView edges

Today the scheduler collapses every DependencyKind (including DataDependsOn)
to a bare Bool via DependencyKindClassifier<Bool>, so shared-operand
structure — N consumers of one produced value — is invisible to batch
formation. This adds v2.workflow.operand_flow, a total derivation over
DependencyView edges producing OperandFlow | OperandFlowRefused rows:

- operand identity = the producer's content_hash (the same ContentHash
  identity v2.std.materialize keys Share on), derived via a
  DependencyKindClassifier<Bool> (only DataDependsOn carries an operand,
  matching the codebase's existing kind-dispatch idiom rather than a
  per-callsite match)
- footprint binds to the single node_keyed_graph_transitive_bytes authority
  in v2.workflow.realization_runner — no parallel size walk
- every non-applicable edge or unsettled/missing footprint yields a typed,
  located OperandFlowRefused row rather than being silently dropped, so
  refusals stay countable (DESIGN §5)

Scope: per docs/plans/machine-shape-orthogonal-scheduling.md §4, updated
today by PR #6687's allocation-as-contract redirect (footprint is plain
ByteSize, not Quantified<ByteSize>). The hash-authority precondition (§9)
is already resolved on main (#6686). Wiring CostAccount.space's
DerivedFrom fill into the live CI floor scheduler is explicitly out of
scope here — that's owned by a separate lane
(bounded_input_cost_envelope_scheduling.md P1) touching the load-bearing
ci_floor_plan.dag, and would be scope creep into another owned lane.

Witness: src/v2/test/claim/operand_flow_witness_test.dag — a fixture with
one shared operand and two DataDependsOn consumer edges asserts both
derive the same ContentHash with equal footprints; RED fixtures assert a
non-DataDependsOn edge and a missing-row footprint each refuse with a
typed cause. Verified green locally via claim_batch built from this
worktree (the earlier attempt with a sibling worktree's prebuilt binary
gave a stale false-negative on an unrelated existing witness too,
confirming it was a stale-binary artifact, not a real regression).

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

* operand_flow: drop unused OperandFlowFootprintUnsettled import from witness

Flagged in review 38759. Not adding a witness for it — see PR reply for
why node_keyed_graph_transitive_bytes's Unsettled arm is a documented
unreachable fail-closed backstop, not a constructible RED, matching
existing precedent in realization_runner_witness_test.dag (which also
never exercises it). The import was dead weight left over from having
the type in scope; removing it.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jul 16, 2026
…haustive theorem (#6725)

* Unbreak main: revert #6686's v2 hash-grounding surface (cross-root import x #6663 field wall)

Partial revert of 4a60303: src/v2/std/node.dag, materialize.dag,
materialize_witness_test.dag, inert_carrier.dag, and the DESIGN Sec-3-thread
note pair (carrier + generated doc together). Keeps #6686's orthogonal
cli_run.rs nfr-roster backfill (reverting it would re-red the falsifier lane).

Root cause (proven by execution): #6663's new MissingField presence check
resolves a literal's expected type by unqualified name through the flat module
type env; #6686's 'import std.types { ContentHash }' in v2.std.node pulls
dag-root std.algebra into the typecheck closure of every v2 module importing
v2.std.node (704 files), so dag-root Monoid/Semigroup/BooleanAlgebra/
OrderedRing/CommutativeMonoid/CommutativeSemiring/AbelianGroup shadow the
v2.std.algebra declarations at 28 literal sites in
src/v2/std/{diagnostic,logic,nat,integer}.dag -> ci_floor_plan resolve fails
-> every main push red. Neither PR alone was red: zero file overlap, merged
31 minutes apart, and the squash union tree was never CI'd (the PR's only CI
run began 8 minutes before #6686 landed).

Receipt: on the 60286e0 tree with the same seed binary, reverting exactly
this .dag surface takes the plan resolve from 28 missing-required-field errors
to green with the floor executing witnesses (control: #6678/#6685 left in
tree).

Re-land trigger (dissolution): the wall's presence leg consults the resolver's
binding (or fails closed on ambiguous names) instead of the flat-env name
lookup; the follow-up re-lands these files with that fix, using this exact
28-error tree as the RED control.

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

* Keep #6686's LocalAlias inert-carrier roster line (orthogonal to the poisoning surface)

The floor's inert_carrier_no_unrostered_or_stale witness reds without it:
the LocalAlias fixture it rosters landed in #6641, not #6686 — the roster
line was a bundled orthogonal fix (same class as the kept cli_run.rs
backfill), not part of the hash-grounding surface. Receipt: local floor on
the revert tree, 300 PASS / 1 FAIL (this witness), FAIL clears with the
line restored.

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

* WIP: field-wall env precedence fix (scratch)

* WIP2: kernel/container guard + final regen

* Fix generated_artifact_drift_gate: make the crate-layout emitter fmt-immune (rustfmt::skip)

Batch-4 generated_artifact_drift_gate_passes red on this PR is the first run
of that gate since main broke at 60286e0 -- #6677 landed its derived
crate-layout artifact during the red window, so no tree ever executed batch 4
against it. Two writers disagreed on one artifact: the wet leg
(stage0_crate_layout_emit.dag) emits plain multi-line arrays, while the
committed bytes were rustfmt'd (trailing comma, collapsed one-liner). Committed
bytes: fmt-clean, drift-red; emitter bytes: drift-clean, fmt-red -- no tree
could satisfy both gates.

Fix: the emitter stamps #[rustfmt::skip] on both consts, so its output is the
fixed point of cargo fmt; artifact regenerated via main_wet. Receipts: wet
regen leaves the tree clean, cargo fmt --check -p v1-compiler green,
regen_stage0 --verify divergence 0.

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

* Merge-lifecycle interleaving witness: the squash race as a bounded-exhaustive theorem

gunbc.merge_lifecycle (new): lifecycle dynamics over the existing
gunbc.merge_admission authority — the merge step consumes policy_admits,
never restates it. Squash lands the PR onto CURRENT main
(squash_result_tree); receipts mint through mint_merge_admission_receipt;
latest-receipt-per-PR matches GitHub required-check semantics; the
unverified-tip latch fires only where main advances.

test.claim.merge_lifecycle_interleaving_witness (new, floor-discovered):
the 2026-07-16 #6663 x #6686 main-red as the permanent RED fixture
(admitted under the live PerPrGateOnly policy, refused under KeyedReceipt,
remedy path lands verified), plus bounded-exhaustive enumeration of all
625 length-4 event interleavings: KeyedReceipt admits zero unverified
tips; PerPrGateOnly admits violations (enumerator-teeth control);
RequireUpToDateBase (GitHub's strict boolean) still misses the roster
axis. Quantifies gunbc.plans.branch_merge_admission_model section 4 over
every interleaving instead of two authored scenarios.

Additive checkpoint-1 extension: no enforcement flip
(merge_freshness_gating_status stays GatingComputedDeferred), no settings
change, no seed .rs touched. All 7 claims green by execution via
gunbc run --claim-run; whole-tree compile-clean 0 diagnostics.

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

* Wire the merge queue: merge_group trigger, typed end to end

extdeps.github.actions gains the MergeGroup WorkflowTrigger variant
(cited; nullary — checks_requested is the only documented activity and
GitHub's default, so a one-inhabitant types parameter carries no
information per the phantom-parameter collapse ruling). The yaml
serializer answers it; gunbc.ci_workflow enrolls it in the ci on: list;
ci.yml regenerated via generated_artifact_gate main_wet — the artifact
diff is exactly one line (merge_group:).

Queue runs are already absorbed by the existing seams, noted on the
carrier: deploy's main-push guard skips them, the concurrency group
falls through pull_request.number to run_id, the merge-admission stamp
takes its non-PR arm, and an unresolvable merge-base diff on a queue ref
falls through to the full floor (fail-closed, never widening).

The trigger is inert until the operator adds the merge_queue rule to the
main ruleset (Rulesets write needs the admin grant this integration
lacks). Land this FIRST, flip the rule SECOND — the queue realizes
gunbc.merge_admission KeyedReceipt on the tree axis, the policy
test.claim.merge_lifecycle_interleaving_witness proves total.

Whole-tree compile-clean: 0 diagnostics.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant