Skip to content

The eval driver's verb surface becomes a plan, the way the CLI driver's already is - #11952

Merged
gunbai-bot[bot] merged 15 commits into
mainfrom
feat/native-driver-plan-spine
Sep 21, 2026
Merged

gunbai-bot[bot] merged 15 commits into
mainfrom
feat/native-driver-plan-spine

Conversation

@briansrls

Copy link
Copy Markdown
Contributor

What was in the rendered main

It decided the verb itself — read argv, compared the first word against three literals, dispatched, and refused inline at three points with its own message and its own status:

let mode = match args.next() { Some(m) => m, None => { eprintln!("REFUSED: no mode given …"); exit(2) } };
if mode == "census" { … }
if mode == "census-resolve" { … }
if mode == "adjudicate" { … }
eprintln!("REFUSED: unknown mode {mode} …"); exit(2);

Every one of those is a decision taken in emitted Rust, where no .dag consumer can read it, no witness can exercise it, and no refusal vocabulary owns it. gunbc.source_root_eval_driver_seed_growth names the capability that retires its row — the rendered main becomes one call into that fold. This is the first part of that: the verb surface.

The shape is not invented

v2.cli.compile_cli already renders a thin main for the other driver, as five calls:

let plan  = v2_cli_parse(argv);
let roots = v2_cli_plan_source_roots(plan);
let reads = read_ingest(&roots);
let outcome = v2_cli_run(plan, reads);
match v2_cli_exit(outcome) { … }

This mirrors it, with the one addition the eval driver needs: adjudicate reads a host-facts file whose path comes from argv, so the plan names that too via native_driver_plan_facts_path. The split exists for the same reason it does there — the host cannot know which roots to walk or which file to read until argv is parsed, and this module cannot read a directory.

Behaviour is preserved exactly, including where that looks like an omission

  • census with no roots is planned, not refused. The rendered main collected an empty vector and let the run fold answer. A parse-time refusal here would be a new wall wearing a refactor's clothes — so there's an arm asserting it stays planned.
  • The three refusal messages are carried verbatim.
  • Exit 2 is exit_code_misuse, the cited code the rendered main used for all three.

Evidence

Ten arms in v2.test.claim.native_driver_plan — every verb, every refusal, both accessors, and the preserved empty-roots case. 10 PASS.

Mutation-verified, both in the direction that matters:

mutation reds
adjudicate treats its facts path as a source root adjudicate_takes_its_facts_path_before_the_roots
a later word repairs a refused parse an_unknown_verb_refuses_and_names_the_word, a_later_word_cannot_repair_an_unknown_verb

The refusal arms assert the exact message. That's deliberate and it isn't a change detector: these strings are the program's command-line contract, this change is a move rather than a redesign, and an arm accepting any refusal text would pass while the contract silently changed.

What this does NOT do

The rendered main still dispatches on the verb and still carries run_census, run_census_resolve and run_adjudication — 628 lines holding the cost accounting, the Instant timing, the /proc reads and the JSON rows. Those are the next parts and each is separable.

Worth stating for whoever takes the next one: timing and /proc reads are genuine host observations and cannot become pure folds. They belong in the same category as reading argv and walking a directory — supplied back as values, with the decisions they feed living here.

Not verified natively: no native binary can currently be built at main (#11915). This is interpreted evidence, which is the honest level for a pure fold over argv.

🤖 Generated with Claude Code

…'s already is

The rendered main decided the verb itself: it read argv, compared the first word
against three literals, and refused inline at three points with its own message
and its own status. Each of those is a DECISION taken in emitted Rust, where no
.dag consumer can read it, no witness can exercise it, and no refusal vocabulary
owns it. gunbc.source_root_eval_driver_seed_growth names the capability that
retires its row -- the rendered main becomes one call into a fold -- and this is
the first part of that: the verb surface.

The shape is not invented. v2.cli.compile_cli already renders a thin main for the
other driver as five calls: parse, plan_source_roots, run, outcome_text, exit.
This mirrors it, with one addition the eval driver needs -- adjudicate reads a
host-facts file whose path comes from argv, so the plan names that too. The split
exists for the same reason there: the host cannot know which roots to walk or
which file to read until argv is parsed, and this module cannot read a directory.

BEHAVIOUR IS PRESERVED EXACTLY, including where that looks like an omission.
`census` with no roots is PLANNED rather than refused, because the rendered main
collected an empty vector and let the run fold answer; a parse-time refusal would
be a new wall wearing a refactor's clothes. The three refusal messages are
carried verbatim. Exit 2 is the cited misuse code the rendered main used for all
three.

Evidence: ten arms in v2.test.claim.native_driver_plan -- every verb, every
refusal, both accessors, and the preserved empty-roots case. 10 PASS.
Mutation-verified: making adjudicate treat its facts path as a root reds the
facts-path arm; letting a later word repair a refused parse reds the two
unknown-verb arms.

What this does NOT do: the rendered main still dispatches on the verb and still
carries run_census, run_census_resolve and run_adjudication, which hold the cost
accounting, the timing and the JSON rows. Those are the next parts, and each is
separable from this one.

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

chatgpt-codex-connector Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-21T10:04:34.998208Z 22f252b PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

briansrls pushed a commit that referenced this pull request Sep 21, 2026
#11959)

dcd1552 introduced 7 blocking parse errors, and they blocked the floor for
every lane: a parse FAIL lends no declaration index, so the floor refuses at
ArmSetConsumerPlanningUnavailable and never prepares a subject.

  mtcollins1_boot_authorization.dag:188-191  annotation names no subject (trailing
    block at EOF with no declaration after it) -- moved onto MtCollins1BootSubject,
    the declaration it is about, since the block's subject IS that type's gate.
  deepseek_v4_1_flash_authority_witness_test.dag:239,250-251  in-body annotations --
    hoisted onto the enclosing test fn, after the block already attached there, in
    source order.

Prose byte-identical in both; no semantic line touched. This is the fourth landing
of this class today, which is what a required gate that cannot refuse buys: the
class is only mechanically preventable once #11829 binds the floor's adjudicator.

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>
Brian Searls and others added 2 commits September 21, 2026 13:09
…ispatch is deleted

Review 69524: the plan had no production consumer and the emitted main kept
the same three literals and messages. emit_source_root_eval_driver_main_rs now
renders main as native_driver_parse + plan-derived roots/facts path + plan exit,
dispatching on the plan's verb. The usage line stops naming a crate (the fold
had hardcoded v1_compiled, the pipeline-free crate's name).

Stage0 mirror regen follows.

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

gunbai-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Now owned by wise-raven-686. This addresses review 69524 at 1ee57f8a91cf.

One fact, two sources: fixed by cutting over at the root. v1.compiler.emit_rust emit_source_root_eval_driver_main_rs now renders main as:

  • native_driver_parse(argv);
  • then native_driver_plan_exit (on ExitFailure, print the fold's reason and exit with the fold's code);
  • then roots from native_driver_plan_source_roots;
  • then a dispatch on the plan's NativeDriverVerb.

The three literal mode comparisons and the three inline refusals are deleted. The only remaining arm the shim writes is an impossible "refused plan with a success exit", which exits 70 loudly. The stage0 mirror v1_compiler_emit_rust.rs is regenerated in the same head.

No production consumer: fixed. The rendered driver main is now the consumer of native_driver_parse, native_driver_plan_exit and native_driver_plan_source_roots.

Refusal texts pinned a copy: resolved by the cutover. The strings the witnesses assert are now the only ones the program prints. One bug surfaced along the way: the fold's usage line hardcoded v1_compiled, but this driver is emitted into the pipeline crate (v1_compiler). A fold cannot know which crate it lands in, so the usage line now names no binary.

Evidence and limits: claim_executor --required-regen --source-root dag --source-root src/v2 (local): the only drift attributable to this change is the 1-line v1_compiler_emit_rust.rs mirror, now installed. Two other drifted files (gunbc_cli_dispatch_surface.rs, std_integer.rs) are untouched by this diff and belong to the base. Not yet shown: that the emitted driver compiles and runs. The required-v2-native CI lane on this head is that control.

— sent from wise-raven-686

@briansrls

Copy link
Copy Markdown
Contributor Author

Held: this PR's contract is now subject to a deliberate amendment (Pkg 9)

Operator ruling, 2026-09-21: test becomes the public operation, with adjudicate's responsibilities split rather than renamed wholesale.

This PR's stated scope is behaviour-preserving — it moves the verb surface out of the rendered main into a modeled plan while preserving the old verbs. That is no longer the destination, so merging it as-is would land a modeled spine around a verb set that is about to change shape.

What specifically moves:

NativeDriverVerb = Census | CensusResolve | Adjudicate { facts_path, source_roots }

  • Adjudicate's facts_path is the load-bearing one. The ruling is that the user must not supply a handwritten host-facts.tsv — the evidence comes from the artifact-production, acquisition and execution paths that actually observe it. So facts_path: String as a parsed argument is the wrong shape; the runner supplies those facts, it does not read them from argv.
  • The three verbs become one public test operation consuming exact selection (Pkg 8, A target pattern selects the native route's universe, because that universe was already a prefix #11919), with the census modes preserved only where a real consumer exists — not as the daily interface.

What should be kept from adjudicate and is not bookkeeping, having read the receipt:

Field Establishes
false_control + true_control a live pair every run — without them an inert evaluator reports all-green
malformed_control the required-rejection case still refuses
old_route_control v1 did not answer — this is the "unmistakably native" property
emitted_closure_identity, executable_identity which artifact produced this result

And one trap worth recording before the amendment is written: native-lane admission does not mean "every requested test passed." It admits an observation carrying classified exclusions provided its other conditions hold. That is useful for observing an incomplete migration and is not the success contract for ordinary gunbc test — where a required test that cannot resolve, infer or execute makes the request unsuccessful even when its refusal is well classified.

I am not taking this further; flagging it so whoever owns Pkg 9 amends from here rather than rediscovering it. The witnesses in this PR (10 arms, 2 discriminating mutations) remain valid for the parse/plan layer regardless of which verbs survive.

@gunbai-bot

gunbai-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Owner's response to the hold above. These are the terms Pkg 9 is written against:

  1. facts_path from argv is the wrong shape. Agreed. It is retired in the Pkg 9 change, not here. Removing it needs a runner-side producer that observes host facts (artifact production and acquisition), and none exists on main yet. Deleting it now would either invent that producer or leave the lane with no facts. This PR's contribution is that the verb surface is one plan fold. Replacing Adjudicate { facts_path } with a public Test { pattern, source_roots } whose facts come from the runner is then a row edit in that fold, not a second dispatch. Whether this lands before that amendment is escalated to the manager.

  2. The four controls survive, unchanged: the false_control/true_control live pair, malformed_control, old_route_control (v1 did not answer), and emitted_closure_identity + executable_identity. This PR does not touch the receipt.

  3. The admission trap is taken as the Pkg 9 success contract. gunbc test <target|pattern> succeeds only when every selected identity executed natively and held. A classified exclusion that lane admission tolerates is a refusal for test.

    • Exit 0: every selected identity held.
    • Exit 1: an observation that did not hold.
    • Exit 2: no observation (a refused selection, missing artifact, or incomplete execution).

    Fixed qualification workload: v2.test.parse.expression_bodied_fn_decl_parse at fec6ef87. Interpreted, it gives 7 PASS / exit 0, and the mutated rejection arm gives 6 PASS 1 FAIL / exit 1. The native route must reproduce both. Those interpreted numbers are the reference oracle and are not credited as native evidence.

— sent from wise-raven-686

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

gunbai-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

This answers the hold comment above. Manager ruling: the spine lands now and Pkg 9 amends it.

facts_path is now named on its carrier, v2.compiler.compile NativeDriverVerb (head a02ad6712ba6), as existing behaviour of a known-wrong shape. Its retirement trigger is the capability, not an artifact: the runner-side producer that observes host facts feeds this plan. When that capability exists, NativeDriverAdjudicate loses facts_path and the public verb becomes test over a target pattern. Nothing smaller retires it.

The four controls you named (the false/true pair, malformed, old-route, closure + executable identity) are untouched by this diff. Merge readiness waits for them to be green in the required-v2-native receipt on this exact head.

— sent from wise-raven-686

…hority

Review 69567: native_driver_plan_facts_path had no production consumer (the
rendered main reads facts_path from the Adjudicate verb). Deleted, both prose
blocks corrected, and the misuse arm compares against exit_code_misuse.

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

gunbai-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Review 69567 is fixed at 18f5ff40d36f. Both findings were correct.

  • Dangling native_driver_plan_facts_path: deleted, not rendered. The rendered main already reads facts_path from the plan, from the NativeDriverAdjudicate verb in the arm that runs adjudication, so it is one plan value with one read route. A second accessor would have been the fork. It also retires with facts_path itself (the capability trigger is stated on NativeDriverVerb). Both prose blocks are corrected: the 00_compile.dag split paragraph and the claim file header. The claim arms now read the facts path the same way the main does, by destructuring the planned verb.
  • Literal 2: replaced. plan_exit_is_misuse compares against extdeps.process.gnu_bash_exit exit_code_misuse.

Control: src/v2/test/claim/native_driver_plan_test.dag passes 10/10 (local claim_batch, this head).

— sent from wise-raven-686

Brian Searls and others added 2 commits September 21, 2026 15:42
Review 69580: the cutover removed main's closing brace with the old tail.

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

gunbai-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Review 69580 is fixed at 1c644183ff50. The finding was correct, and my earlier regen evidence did not cover it. When I cut out the old dispatch tail I also removed main's closing "\}".

  • src/v1/05_emit_rust.dag emit_source_root_eval_driver_main_rs has the closing brace restored. Counting over the emitted main template gives 15 open and 15 close, format-string pairs included.
  • The stage0 mirror v1_compiler_emit_rust.rs is regenerated (--required-regen, a 1-line diff).

Honest limit, as the review says: the rendered main still has no executing consumer that has run. The executing consumer is claim_executor --v2-native-route, which builds the emitted driver crate and runs census and adjudicate through it. It is currently refused at emission on main's in-body annotations (fabric_storage_wire_witness_test, target_invocation_witness_test), which this PR does not touch. The repairs are #11969 plus #11967/#11968. I'll run the lane on this head as soon as they land and post the four controls' verdicts here. Readiness waits on that run, not on CI.

— sent from wise-raven-686

@gunbai-bot

gunbai-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Native lane run on exact head b6e4f8050f (claim_executor --v2-native-route, binary sha256 3d6b7a12… built from that head, GITHUB_SHA set):

So the four controls still cannot be observed on this PR's own head until #11971 lands. They are being run on the integration branch (main + #11971 + #11919 + this PR + the argv wiring) meanwhile. That run is labelled as composed evidence and will not be credited to this head.

— sent from wise-raven-686

Brian Searls and others added 2 commits September 21, 2026 16:16
…an-spine

# Conflicts:
#	src/v1/stage0/src/v1_compiler_emit_rust.rs
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brian Searls and others added 3 commits September 21, 2026 17:07
…an-spine

# Conflicts:
#	src/v2/compiler/00_compile.dag
…iverse

The driver plan's adjudicate is now: adjudicate <host-facts.tsv> <target-pattern>
<source-root>... The pattern is parsed by extdeps.bazel.target_pattern
parse_target_pattern; an unparseable or missing pattern is a plan refusal with
the misuse status (2). The rendered run_adjudication calls
native_lane_universe_selected(ingest, pattern). The seed lane runner passes the
default //v2/test/... (mirror of native_route_default_pattern).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 0d10ab3)
…nd over merged main

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

gunbai-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Head 1d8095ba0e27 merges main, which now includes #11919, and adds the argv wiring (manager ruling). #11919's declared frontier 1, "the only production caller passes a hardcoded default", is closed here.

  • adjudicate <host-facts.tsv> <target-pattern> <source-root>...: the pattern is parsed by extdeps.bazel.target_pattern parse_target_pattern and carried on NativeDriverAdjudicate { facts_path, pattern, source_roots }. An unparseable pattern refuses with ^native_driver_adjudicate_pattern_refused (the authority's located cause); a missing one refuses with ^native_driver_adjudicate_without_pattern. Both exit with the misuse status 2.
  • The rendered run_adjudication calls native_lane_universe_selected(ingest, pattern). The seed lane runner passes //v2/test/... (its mirror of native_route_default_pattern), so the lane's population is unchanged.
  • Controls (local claim_batch, this head): native_driver_plan_test passes 13/13, including three new arms (pattern carried; unparseable pattern refuses as misuse; missing pattern refuses). native_lane_import_refusal_witness_test passes 12/12 and v2_native_route_test 71/71.
  • Native evidence on the integration composition (main + Compose is uninhabited, so the three declarations that put a value in one now say what they compute #11971 + this): the emitted driver compiles and runs; adjudicate … //v2/test/parse:expression_bodied_fn_decl_parse dag src/v2 narrows the closure to 13 modules and then refuses on a native-parser gap in dag/std/content_hash.dag. That is composed evidence and is not credited to this head. The four controls on THIS head still wait on Compose is uninhabited, so the three declarations that put a value in one now say what they compute #11971.

— sent from wise-raven-686

@gunbai-bot

gunbai-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Side-chat review approved merging this head (b52c7b5) under the operator's delegation, as the consumed plan/target-pattern increment. It does not qualify native Boolean-test execution or complete Pkg9. I read the floor log: planned=423, executed=423, claims_failed=0, verdict=FloorClean. Still open: the live true/false pair is an execution obligation, retried and requalified once the Pkg12 resolver work lands (a changed refusal gets investigated, not auto-accepted); the identity-level no-regression comparison; and facts_path.

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