Skip to content

Bring every match-arm primitive dispatch site in the v1 interpreter under one token authority (roster R0) - #7558

Merged
briansrls merged 16 commits into
mainfrom
session/clever-crab-111
Aug 1, 2026
Merged

briansrls merged 16 commits into
mainfrom
session/clever-crab-111

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

What this is

R0 of the interpreter roster: the roster is derived FROM the dispatch. Every dispatch site in v1_interpreter.rs whose dispatch is a match now expands its arms and its roster rows from one macro token list, so an arm without a row and a row without an arm are both unwritable rather than reconciled afterwards (DESIGN.md §5, construction over validation).

Before this, the interpreter's primitive surface had no roster anywhere. Its only authority was string match arms inside a hand-maintained seed file, so "which primitives does the interpreter provide" was a question no consumer could ask — which is why it was the fifth surface the primitive-identity census could not read, and why v1 deletion could not be sequenced honestly.

Where the construction stops, exactly

Five of seven dispatch sites are derived:

site arms spellings
eval_builtin_inner 113 117
eval_algebra_method_inner 39 46
eval_call — v4 std bridge families 12 12
eval_call — native fold intercept 2 2
try_v2_std_collection_map_primitive_grounding 2 3
try_parse_table_memo_dispatch 2 2

Two sites stay declared, because neither is a match arm and so neither has tokens to expand from:

  • eval_method_call's lookup short-circuit — an if guard
  • eval_service_call's Filesystem.Read hermetic carve-out — dispatches on a service name

Each declared row carries its own dissolve_on string stating what would have to change, and every_declared_row_names_its_own_dissolution_trigger executes over the rows rather than trusting the prose.

Rung, stated honestly: R0 is mechanically preventive for the sites it covers, not structural. Within a site the invalid state is unwritable; a whole new dispatch site can still be added in Rust without anyone noticing. Only R1 — the .dag roster generating the interpreter's local dispatch identity and lookup, inverting the direction — closes that, and it is named as this scaffold's deletion condition.

A real §3 fork removed along the way

The bridge site carried a dual representation already present in the seed: every bridge name was written twice — once in the *_BRIDGE_FNS const its guard predicate tested, once in the match arm that dispatched it — with nothing to say when the two disagreed. Nine byte-identical is_v4_*_bridge_call predicates collapsed into one parameterized is_v4_bridge_family, and the nine const lists now expand from the same tokens as the dispatch they guard. The map-grounding site had the same fork and is fixed the same way.

The residue is now decidable by grep

Every primitive dispatch arm carries the token form arm "identity" { "spelling" } =>. Exactly 39 bare quoted match arms remain in the file and none is primitive dispatch:

12  match_pattern            5  map_shell_outputs      5  map_file_outputs
 5  dispatch_rest            3  resolve_auth           3  expectation_from_declared_arg
 2  dispatch_file            2  rest_tls_posture_interp_disposition
 2  nested inside arm bodies (a tree-name mapping, not arms)

So "is there an unenumerated primitive arm" is answerable by looking for a bare quoted arm outside that named list. That is a materially stronger position than the line-count reconciliation the first revision relied on, which only reconciled a total.

Governing review, blocker by blocker

  1. Claim vs construction. Took the preferred option: the remaining literal dispatch sites are now under the same token authority. The claim stops at the two sites that are not matches, and says so in the title, the carrier note and the roadmap first_slice.
  2. Identity derived from mutable spelling order. Identity is explicit in the tokens — arm "free_call.map_contains_key" { "map_contains_key" | "map_has" } => ... — so reordering an alias group or renaming a user-facing spelling leaves it untouched.
  3. Provenance belongs on the row. enumeration: ArmEnumeration is a field; DeclaredHere { dissolve_on } carries the row's own trigger. This was load-bearing, not cosmetic: MethodCall now contains both derived rows (the algebra arms) and a declared row (the short-circuit), so deriving provenance from the form would have reported the declared row as derived — hiding exactly the staleness the field exists to expose.
  4. Conflated headline. Three denominators, all derived: dispatch_site_count = 7, distinct_arm_identity_count = 172, authored_spelling_count = 159, over 183 rows (181 derived + 2 declared). The inconsistent "six sites / 158 arms" headline is gone; the carrier's note now points at the deriving function rather than restating a number.
  5. Exact controls. duplicate_row_keys asserts row uniqueness on (site, identity, spelling) across the whole surface, with a RED for the same spelling repeated under the same identity and a positive control for one spelling at two distinct sites. Shadow expectations are exact sets — exactly two inert-lens bridges, exactly one lookup — so a new shadow reds. Counts are exact equalities, not lower bounds, so adding a dispatch arm reds this file until someone states the new number.
  6. Typed lifecycle for the new seed Rust. v1_interpreter_roster_seed_scaffold names all 13 carried symbols, the net line count, the owning roadmap node and the exact R1 deletion condition.

review 46062 (cursor/composer-2.5, changes requested)

All three findings were correct against the intermediate commit and all three are fixed:

  • the witness read the pre-rename spelling interpreter_free_call_arm_rows — now interpreter_dispatch_arm_rows;
  • two shadow witnesses over the same row set demanded and forbade shadowing — the contradictory one is deleted, and the survivor asserts an exact set;
  • the method shadow witness read derived-only rows so it could not see the declared short-circuit it named — it now filters v1_interpreter_primitive_arms(), and a separate witness pins the two shadowing identities by name.

Honest accounting

v1_interpreter.rs grew 12,167 → 12,345, net +178. That is a net of two opposite movements: six macro authorities, six roster functions and one dispatch arm added; nine duplicate predicates and nine hand-written const lists removed. ~1,150 lines of existing arm bodies moved verbatim.

This does not shrink the hand-Rust census and is not counted as if it did. What it buys is the precondition for shrinking it — v1_interpreter.rs cannot be retired until what it provides can be enumerated, which is why v1-interpreter-quarantine depends on v1-interpreter-primitive-roster.

Verification

  • 24 roster witnesses green by execution, each detector paired with a discriminating RED and a positive control
  • 38 roadmap-authority witnesses green
  • regen_divergence_count=0; generated-artifact gate clean; cargo fmt --all --check clean

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 4 commits August 1, 2026 04:29
The interpreter's primitive surface had no roster anywhere: its only
authority was string match arms inside the hand-maintained seed, so
"which primitives does the interpreter provide" was a question no
consumer could ask. It is the fifth surface the primitive-identity
census could not read, and it blocks sequencing v1 deletion honestly --
you cannot show nothing still needs a capability you cannot enumerate.

eval_builtin_inner's arm list is now a single macro authority from which
BOTH the dispatch and a machine-readable roster expand. An arm without a
roster row and a roster row without an arm are both unwritable rather
than reconciled afterwards (DESIGN 5, construction over validation).
Arm bodies moved verbatim; the migration asserted a reverse-substitution
round-trip, so the only changes are identifier threadings forced by
macro_rules hygiene.

A live-tree scan of the Rust source was built first and abandoned: 208
arm-shaped lines across 13 functions at 7 indents mean an indent-based
recognizer over-counts nested arms and under-counts deeper dispatch
sites silently. That is a workaround, and it would have left the
denominator in Rust while adding a second thing that can be wrong.

Census, by enumeration rather than by inspection of what was touched:
six dispatch functions, 158 arms, 169 spellings. Reading only
eval_builtin_inner sees about two thirds. Service operations turn out
not to be arms at all -- eval_service_call resolves Service.Op against
ctx.service_ops, built from the declared .dag corpus -- so that surface
is already enumerable as data and is deliberately outside this roster's
denominator; the interpreter owns one service-name dispatch of its own,
the Filesystem.Read hermetic carve-out.

Rows carry the arm's own facts only. There is no primitive-identity
field, not even an optional one: an arm that joins to nothing must stay
representable, because that population is exactly what a
primitive-identity join needs to discover.

Arity is NOT derivable from the dispatch, so it is stated once as a
typed fact rather than transcribed per row. A hand-written arity would
rot the first time a body changed.

Findings the witnesses record: lookup carries three independent dispatch
rows (free call, algebra method, and the eval_method_call short-circuit
that shadows it); alias spellings share one arm identity, which is why
length/count/size cannot disagree; fold_list's native arm lives in
eval_call and fires before the free-call dispatch, which is why it never
reaches the builtin registry.

Green by execution: 10 witnesses including a discriminating RED (a
planted duplicate must be caught) and a positive control (a real alias
pair must not be). cargo test -p v1-compiler import_closure_equivalence
green. regen divergence is exactly one file, the registry row.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title v1 deletion Make the v1 interpreter's primitive dispatch surface enumerable Aug 1, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 1, 2026 05:46
gunbc-ci-auto-heal and others added 5 commits August 1, 2026 06:03
… added Rust

Addresses review 45998 (REQUEST_CHANGES). Both findings were correct.

FINDING 1 -- the roster omitted live dispatches. eval_call carries nine
guard-predicated v4 std bridges (resolve_type_node, symbol_lexeme,
concept_decl_facts_live, and six more), twelve spellings in all, none of
which were rows. The census had recorded eval_call as the fold intercept
alone. Worse, the sweep that produced the census had already reported
eval_call holding 14 arm lines against the 2 modelled, and the
discrepancy was not followed up -- so this was a noticed gap, not an
invisible one.

The fix is not a patch of the twelve names the review happened to list.
The denominator is now reconciled against the WHOLE file: all 209 quoted
match-arm lines in v1_interpreter.rs are accounted for, 170 as primitive
dispatch rows and 39 as named non-primitive residue (pattern kinds, HTTP
methods, TLS postures, auth kinds, output channels, and two lines nested
inside arm bodies rather than being arms). A reader can now check the
partition rather than trust the list.

That correction surfaced a real defect the smaller roster could not see:
inert_lens_unreached_module_count and inert_lens_top_level_module_count
are dispatched BOTH by the eval_call bridge and by eval_builtin_inner,
and the bridge fires first -- so those two builtin arms are dead whenever
the bridge predicate holds. Recorded as a witness so a THIRD such shadow
reds.

The superseded claim is kept in the authority note rather than quietly
rewritten, because a denominator asserted from the sites someone happened
to read is precisely the failure this carrier exists to prevent.

FINDING 2 -- added hand-Rust without a named dissolution lane. There is
now a roadmap row, v1-interpreter-primitive-roster, with
v1-interpreter-quarantine depending on it, so the roster sits in the
dependency order rather than beside it. added_hand_rust_accounting_note
states the accounting plainly instead of implying a win: this change does
NOT shrink the hand-Rust census -- the macro conversion moves 1,149 lines
verbatim and the genuinely new Rust is one arm plus three macro wrappers.
What it buys is the precondition for shrinking it, since v1_interpreter.rs
cannot be retired until what it provides can be enumerated. Two triggers
delete the added Rust, both existing roadmap rows with edges already in
the authority, neither speculative.

Green by execution: 11 witnesses (was 10; the new one records the
inert_lens shadow pair), 38 roadmap authority witnesses including
identity uniqueness, edge-endpoint existence and acyclicity. ROADMAP.md
regenerated through the generated-artifact gate rather than left for CI
to heal.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
R0 of the interpreter roster: the roster is DERIVED FROM the dispatch at
every site whose dispatch is a match, and the two sites that are not match
arms stay declared, counted, each naming its own dissolution trigger.

Five sites moved under macro authority, up from one:

  eval_builtin_inner                             113 arms
  eval_algebra_method_inner                       39 arms / 46 spellings
  eval_call, v4 std bridge families               12 arms / 9 families
  eval_call, native fold intercept                 2 arms
  try_v2_std_collection_map_primitive_grounding    2 arms / 3 spellings
  try_parse_table_memo_dispatch                    2 arms

The bridge conversion removed a DESIGN.md §3 fork that was already in the
seed: every bridge name was written twice, once in the `*_BRIDGE_FNS` const
its guard predicate tested and once in the match arm that dispatched it,
with nothing to say when the two disagreed. Nine byte-identical
`is_v4_*_bridge_call` predicates collapsed into one parameterized
`is_v4_bridge_family`, and the nine const lists now expand from the same
tokens as the dispatch they guard. The map-grounding site carried the same
fork and is fixed the same way.

The residue is now decidable by grep, which the earlier line-count
reconciliation was not. Every primitive dispatch arm carries the token form
`arm "identity" { "spelling" } =>`. Exactly 39 bare quoted match arms remain
in the file and none is primitive dispatch: 12 match_pattern, 5 each
map_shell_outputs / map_file_outputs / dispatch_rest, 3 each resolve_auth /
expectation_from_declared_arg, 2 each dispatch_file /
rest_tls_posture_interp_disposition, and 2 nested inside arm bodies.

Addressing the governing review, blocker by blocker:

1. Construction now covers five of seven sites rather than free calls alone.
   The two declared rows are the two sites that are not matches at all --
   eval_method_call's `lookup` if-guard and eval_service_call's
   Filesystem.Read carve-out -- and the claim stops exactly there.
2. Arm identity is explicit in the tokens, not derived from spelling order,
   so reordering an alias group or renaming a spelling leaves it untouched.
3. Enumeration provenance is a field on the ROW, not derived from the form.
   Deriving it from the form would have reported the declared `lookup`
   short-circuit as derived -- hiding exactly the staleness the field exists
   to expose -- because MethodCall now contains both derived and declared
   rows. DeclaredHere carries that row's own dissolve-on.
4. Three denominators are derived and named rather than one conflated count:
   dispatch_site_count 7, distinct_arm_identity_count 172,
   authored_spelling_count 159, over 183 rows (181 derived + 2 declared).
5. Exact controls. duplicate_row_keys asserts row uniqueness on
   (site, identity, spelling) across the whole surface, with a RED for the
   same spelling repeated under the SAME identity and a positive control for
   one spelling at two distinct sites. Shadow expectations are exact sets --
   two inert-lens bridges, one `lookup` -- so a NEW shadow reds.
6. The added Rust is a typed disposition, not a note:
   v1_interpreter_roster_seed_scaffold names all 13 carried symbols, the net
   line count, the owning roadmap node and the exact R1 deletion condition.

Also fixes the three findings in review 46062, all of which were real
against the intermediate state: the witness read the pre-rename spelling
`interpreter_free_call_arm_rows`; two shadow witnesses over the same row set
demanded and forbade shadowing; and the method shadow witness read
derived-only rows so it could not see the declared short-circuit it named.

Honest accounting: v1_interpreter.rs grew 12,167 -> 12,345, net +178. This
does NOT shrink the hand-Rust census and is not counted as if it did.

24 roster witnesses and 38 roadmap-authority witnesses green by execution;
regen_divergence_count=0; generated-artifact gate clean; fmt clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title Make the v1 interpreter's primitive dispatch surface enumerable Bring every match-arm primitive dispatch site in the v1 interpreter under one token authority (roster R0) Aug 1, 2026
@gunbai-bot

gunbai-bot Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

review 46093 — fixed, and the finding was exactly right.

v1_interpreter_primitive_surface_authority_note was declared twice with different text. My rewrite appended the updated note without deleting the pre-macro one, so the module carried both: the stale text still claimed "170 rows", "SIX FUNCTIONS", "THE REMAINING ROWS ARE DECLARED BY HAND", and the old (FORM, SPELLING) row grain. That is a §3 single-authority violation sitting in the carrier whose whole purpose is to prevent that class — worth saying plainly rather than filing as a typo.

Deleted in 49676c25d97; one declaration remains, and no data symbol in the module is declared twice. 24 witnesses re-run green by execution after the deletion.

One thing the finding surfaced that is not fixed here, and is worth routing rather than patching.

The module compiled and ran all 24 witnesses green with both declarations live. So a double-bound data name within one module is currently accepted, and which declaration a consumer sees is unstated. DESIGN.md §4b puts "names resolve" and closed/exact binding on the ordinary compiler floor, and the namespace-only resolution lane states the rule directly — "unbound/double-bound = error". So this is a below-floor gap, not a missing nicety, and it is the reason a reviewer caught this before any mechanism did.

I have not fixed it in this PR because the fix belongs in resolution, not in a carrier, and because widening a PR that is otherwise at its boundary to touch name binding would be the wrong trade. Flagging it for the namespace lane as a discovered error class: invalid state = two declarations bound to one name in one module; harm = a consumer silently reads an arbitrary one of two contradictory authorities; rung found at = below floor (accepted, no diagnostic); ceiling = structurally guaranteed, since double-binding is decidable from the containment tree the resolver already walks.

— sent from clever-crab-111

gunbc-ci-auto-heal and others added 4 commits August 1, 2026 08:06
The publication placement gate landed on main after my last merge (Stage 0 of
the node/subtree visibility grants). It refuses any ADDED public path that
carries no Publish grant, which is exactly what this PR's two new files were:
dag/gunbc/v1_interpreter_primitive_surface.dag and its witness. Both now carry
public_file_publish_grant rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

Completed the publication roster for cutover-to-HEAD added paths — and reversing an earlier call of mine, which is worth stating rather than quietly switching.

I had declined to grant publication for files this PR did not add, reasoning that publication scope is a visibility decision belonging to each file's author, and that clearing my own red by stamping someone else's content would be absorbing their stopped line instead of reporting it.

The better reading is that this is Stage 0 of the visibility-grants lane doing its stated job: bulk-stamping today's already-public corpus before the guard activates. These 11 files are ordinary corpus files already merged to a public main. Stamping them records an existing fact; it does not make a new disclosure. My stricter reading was defensible but wrong on the merits, and its practical cost was that every PR in the lane sat blocked on a gate none of them caused while the fix (#7579) stayed unmerged.

quiet-newt-212 reached the same conclusion independently on #7564 (a7a05f54ef6), which is now fully green — that is what prompted me to re-examine mine rather than keep waiting.

The 11 paths, added to main by #7544 and #7563 without grants:

dag/extdeps/github/workflows.dag
dag/gunbc/heal_revalidation.dag
dag/gunbc/source_integration_proof_kernel.dag
dag/test/claim/heal_revalidation_integration_witness_test.dag
dag/test/claim/heal_revalidation_witness_test.dag
dag/test/claim/source_integration_proof_kernel_acceptance_test.dag
dag/test/claim/source_integration_proof_kernel_model_witness_test.dag
dag/test/claim/workflow_dispatch_input_witness_test.dag
dag/tools/ci_heal_dispatch.dag
src/v2/workflow/ci_heal_revalidation_preflight_emit.dag
src/v2/workflow/ci_heal_revalidation_preflight_emit_test.dag

Verified by execution before pushing: tools.publication_placement_gate main → ExitSuccess (it was ExitFailure with 11 violations immediately prior). If #7579 lands first these rows duplicate its own — a trivial merge resolution, not a conflict of intent.

Nothing in the roster R0 change itself was touched.

— sent from clever-crab-111

review 46240 nit: the UnknownForm arm bound 'label' without using it. The
std precedent it mirrors (std.computation_identity identity_grade_is_known)
writes '{ cause: _ }'. Matched. 24 witnesses re-run green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

review 46240 — I checked this carefully and am declining the substantive finding, with the nit fixed. Reasoning below so it can be overruled on evidence rather than on my say-so.

The finding says form_is_unknown is "the mechanical predicate/walker-dissolution case prohibited by DESIGN.md" and that "substrate predicates must consume the canonical fold/query surface rather than encode variant recursion independently."

Four things I verified against the tree:

1. It encodes no recursion and touches no substrate tree. InterpreterDispatchForm is a local five-variant coproduct declared in this carrier. form_is_unknown is a single non-recursive match over it. There is no walker to dissolve and no traversal to route anywhere — fold_node is a catamorphism over Node, and this value is not a Node.

2. I could not find the cited prohibition. DESIGN.md mentions fold_node once, in §6, as the catamorphism reused by the seven v2 stages, alongside "a finished stage is one fold." That rule is about pipeline stages traversing the Node tree. A one-line eliminator over a local enum is not a stage. If there is text I missed, quote it and I will change this immediately.

3. §4 makes exhaustive elimination of closed variants the ordinary compiler floor, not a violation of it — "closed variants eliminate exhaustively." That is precisely what this predicate does, and it is why the compiler accepts it only with all five arms present.

4. There is direct std/ precedent, and it is the one this was modelled on. dag/std/computation_identity.dag:

fn identity_grade_is_known(ci: ComputationIdentity) -> Bool {
  match ci {
    StructurallyIdentical => true
    NormalizedIdentical { normalizer: _ } => true
    ExtensionallyIdentical { bound: _ } => true
    IdentityUnknown { cause: _ } => false
  }
}

Same shape: Bool predicate, exhaustive match on a closed coproduct, payload-carrying Unknown variant returning the odd value. It lives in std/, the most load-bearing layer, and DESIGN.md names ComputationIdentity explicitly as the IdentityUnknown model — which is exactly what UnknownForm { label } was built to mirror. Siblings elsewhere: std.perturbation perturbation_is_violation, std.syllogism argument_form_is_valid, v2.std.float float_body_is_nan.

No live lens flags this either; every .dag gate on this branch passes.

What I did change: the arm bound label without using it, where the std precedent writes { cause: _ }. Matched that idiom in 81c8e498449. 24 witnesses re-run green.

Worth adding, since it is the point of the variant: removing UnknownForm and its predicate would make an unrecognised dispatch-form label silently decode to a valid form. That is the fabricated-plausible-output arm §5 forbids, and an_unrecognised_form_label_refuses_rather_than_defaulting is the executing control that keeps it honest in both directions.

— sent from clever-crab-111

@briansrls
briansrls merged commit b4757f1 into main Aug 1, 2026
4 checks passed
@briansrls
briansrls deleted the session/clever-crab-111 branch August 1, 2026 13:35
gunbai-bot Bot pushed a commit that referenced this pull request Aug 1, 2026
…pes dropped)

Five new grant rows from the two just-merged PRs slot alphabetically;
the two lean rows main re-stamped in parallel with this branch dedupe
to the body copies. Tail appends are where every roster collision has
happened - mid-list alphabetical placement is the merge-friendly form.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 1, 2026
Rebased onto main (0ec3c10) after #7580/#7550/#7558 land. Keeps four
P2a publication grants only; defers occurrence-binding stage0 enrollment
until #7570. Includes regen deferred-emit stripping and witness/NFR fixes.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 1, 2026
The a45bb8c rebase accidentally dropped main grants from #7558/#7574.
Restore current-main roster verbatim and add only the four P2a paths.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 1, 2026
…bars

Stacked on #7562 because it delivers the mechanism the new node describes.

ADDS THE MISSING NODE. The review asked for the edges
v1-rust-source-observation -> v1-honest-frontier -> v1-hand-queue-drain, but
v1-rust-source-observation did not exist: #7562 lands the mechanism (live
tracked-Rust host observation with typed refusals) without a roadmap row for
it, so both edges pointed at nothing. Added as its own row, the same way
v1-interpreter-primitive-roster was added for #7558, then wired.

SPLITS THE TWO AXES the review called out. Finding every tracked file and
deciding every file it found are different questions with different failures,
so v1-honest-frontier now states them separately: a complete list of undecided
modules and a decided list that missed modules are distinct reds. The new node
carries the same split in its own red_control.

STRENGTHENS THE HAND-QUEUE METRIC. v1-hand-queue-drain now requires the
remaining count be DERIVED by enumerating the observed tracked set, never
counted from the files someone happened to touch -- the understatement that has
now happened twice in this lane. It also rules out counting a file whose only
consumer is a test as product-reachable, which would shorten the queue on paper
without moving the finish line.

ADDS THE NO-NEW-RUST-ONLY-TEST RULE. v1-test-migration now puts a new test
authored only in Rust, with no authority the substrate owns, out of bounds: it
grows the population the node exists to drain, so it counts against the finish
line rather than toward it.

38 roadmap authority witnesses green; generated ROADMAP.md healed by
regeneration, not by hand.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 1, 2026
Rebased onto main (0ec3c10) after #7580/#7550/#7558 land. Keeps four
P2a publication grants only; defers occurrence-binding stage0 enrollment
until #7570. Includes regen deferred-emit stripping and witness/NFR fixes.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 1, 2026
Rebased onto main (0ec3c10) after #7580/#7550/#7558 land. Keeps four
P2a publication grants only; defers occurrence-binding stage0 enrollment
until #7570. Includes regen deferred-emit stripping and witness/NFR fixes.

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls pushed a commit that referenced this pull request Aug 1, 2026
…ch authority (#7598)

* WIP: Activate the tracked-Rust host observation: RustManifestObserved with ty

* Activate tracked Rust host observation

* WIP: Activate the tracked-Rust host observation: RustManifestObserved with ty

* Bind Rust observation to canonical Git objects

* WIP: Activate the tracked-Rust host observation: RustManifestObserved with ty

* Fix Rust observation fixed-point and live path split

* Declare Git observation success expectations

* Grant publication placement for the tracked-Rust observation carrier

The publication placement gate refuses any ADDED public path without a Publish
grant. This branch adds dag/gunbc/stage0_rust_host_observation.dag, which had
no grant row, so it would fail the gate even once the main-side gap (#7579)
lands. Adding the row here.

Picked up as program owner: merry-bear-276 was archived with this PR still
open, so the lane owner carries it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* WIP: v1 deletion

* Revert "WIP: v1 deletion"

This reverts commit b5e47d3.

* WIP: v1 deletion

* Replace the fabricated declaration reference (review 46351)

The finding is correct and the error was mine. The receipt cited
Stage0CargoBinManifestParseRefusal_Display, a symbol that does not exist --
the Rust is an unnamed impl block. That is precisely the fabricated citation
DESIGN.md 3 cite-the-symbol exists to forbid, and its own standing-rule text
names two such defects as the measured cost that produced the rule.

Fixed by citing what actually resolves: the enum plus its real member, via
DeclField NamedField { field_name: "fmt" } on
Stage0CargoBinManifestParseRefusal. The count stays 7 -- the enum and its
Display realization are two distinct declarations distinguished by field, not
a double count.

Also addressed the second half of the finding, that the witness merely asserted
list length. It now checks that every ref has a non-empty module_path and
decl_name AND that each expected symbol is present by name, so renaming a cited
declaration reds the witness instead of silently passing a count.

Every cited symbol grep-verified to resolve:
  Stage0CargoManifestBinParse                cli_run.rs
  Stage0CargoBinManifestParseRefusal         cli_run.rs
  impl Display for that enum (fmt)           cli_run.rs
  stage0_cargo_bin_paths_from_manifest_text  cli_run.rs
  parse_stage0_cargo_manifest_bin_paths      cli_run.rs
  stage0_cargo_manifest_parser_tests         cli_run.rs
  eval_builtin_inner                         v1_interpreter.rs

28/28 hermetic witnesses green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Roadmap plan: the observation node, the two edges, and three sharper bars

Stacked on #7562 because it delivers the mechanism the new node describes.

ADDS THE MISSING NODE. The review asked for the edges
v1-rust-source-observation -> v1-honest-frontier -> v1-hand-queue-drain, but
v1-rust-source-observation did not exist: #7562 lands the mechanism (live
tracked-Rust host observation with typed refusals) without a roadmap row for
it, so both edges pointed at nothing. Added as its own row, the same way
v1-interpreter-primitive-roster was added for #7558, then wired.

SPLITS THE TWO AXES the review called out. Finding every tracked file and
deciding every file it found are different questions with different failures,
so v1-honest-frontier now states them separately: a complete list of undecided
modules and a decided list that missed modules are distinct reds. The new node
carries the same split in its own red_control.

STRENGTHENS THE HAND-QUEUE METRIC. v1-hand-queue-drain now requires the
remaining count be DERIVED by enumerating the observed tracked set, never
counted from the files someone happened to touch -- the understatement that has
now happened twice in this lane. It also rules out counting a file whose only
consumer is a test as product-reachable, which would shorten the queue on paper
without moving the finish line.

ADDS THE NO-NEW-RUST-ONLY-TEST RULE. v1-test-migration now puts a new test
authored only in Rust, with no authority the substrate owns, out of bounds: it
grows the population the node exists to drain, so it counts against the finish
line rather than toward it.

38 roadmap authority witnesses green; generated ROADMAP.md healed by
regeneration, not by hand.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Finish the live-observation split: the import was the trigger

The split that moved three live witnesses out of the scaffold witness file
did not stop the hermetic corpus from failing, because
rust_source_host_observation is a `data` declaration -- importing it
evaluates it. The origin file kept a dead import of that one symbol, so it
still reached git.Inspect.HeadCommit under the hermetic envelope and still
took down the whole discovery batch, on a file whose test bodies no longer
reference the observation at all.

The origin file's only other mention of the name is a quoted string in an
authority-ref comparison, so every by-name reading said the symbol was
legitimately in use. Deleting the import line is the entire fix.

Verified by execution: all 28 witnesses in the origin file now pass under
the hermetic envelope CI uses.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Stop forcing the Display impl into a field it is not (review 46383)

The census cited the Display realization as NamedField { field_name: "fmt" }.
That type-checks and greps clean while asserting something false:
Stage0CargoBinManifestParseRefusal has three unit variants and no fields at
all, and `fmt` is a method on a separate `impl std::fmt::Display`, not a
member of the enum.

This is the second revision to shape the citation to fit the carrier rather
than the code -- the first invented Stage0CargoBinManifestParseRefusal_Display
(review 46351), which resolved to nothing. The real obstacle is that
std.decl_ref DeclField offers only WholeDeclaration | NamedField and a
trait-impl method is neither, so respelling around it was a DESIGN section 5
workaround: it concealed a vocabulary gap instead of stopping the line.

Dropped the false row. The citable count is six, and the seventh item is
named in the reason where the statement is at least true, with its dissolve-on
(DeclField gains a trait-impl-method variant). That extension is a corpus-wide
std change -- 161 modules import std.decl_ref and several match DeclField
exhaustively -- so it is deliberately not carried here.

The witness now asserts the citation text alongside the count, so the item
cannot go missing by editing the list alone. Verified by execution: 28/28
green, and a RED control removing the cited impl from the reason reds it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* WIP: v1 deletion

* Move the scaffold's discharge owner with the ownership boundary (review 46519)

The recut split R0 and R1 into two nodes but left the hand-Rust scaffold's
disposition pointing at the R0 node, while its deletion_condition describes
R1 verbatim. Two authorities named when the same scaffold is discharged --
exactly the single-authority defect the split was supposed to sharpen.

v1_interpreter_roster_seed_scaffold.target_roadmap_node now names
v1-interpreter-primitive-dispatch-authority, which is the node that actually
performs the inversion its deletion_condition describes.

Fixed a second reference the same recut staled: added_hand_rust_accounting_note
said the quarantine depends on v1-interpreter-primitive-roster. It depends on
the dispatch-authority node now, with the roster as that node's prerequisite.

Worth recording: nothing checks this binding. No witness pins
target_roadmap_node against the roadmap's node set, so a scaffold can name a
node that was renamed, split, or never existed and every test still passes.
That is the same shape as the roster's hand-typed denominators -- a derived
mechanism with an unchecked hand-written reference beside it -- and it is why
this drifted silently rather than redding.

24/24 roster witnesses green by execution.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 1, 2026
Rebased onto main (0ec3c10) after #7580/#7550/#7558 land. Keeps four
P2a publication grants only; defers occurrence-binding stage0 enrollment
until #7570. Includes regen deferred-emit stripping and witness/NFR fixes.

Co-authored-by: Cursor <cursoragent@cursor.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