Skip to content

Re-land #8055 with data-initializer roots: classify test data declarations instead of refusing selection - #8110

Merged
briansrls merged 2 commits into
mainfrom
reland/8055-live-read-data-roots
Aug 10, 2026
Merged

briansrls merged 2 commits into
mainfrom
reland/8055-live-read-data-roots

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

DRAFT — INCOMPLETE. The branch in its current state still reds main. Do not merge, do not flip to ready.

Re-land of #8055, which #8104 reverted at ca64dbae.

Why #8055 was reverted

It made live-read classification load-bearing at every selection decision, but the classifier's subject universe is fn-arrow declarations while the enrolled population contains 38 test data rows across 14 files (census re-measured on this branch, independently matching the reported figure). Those rows cannot bind, so the manifest carries a Refused row and the consumer stops the line:

AFFECTED-SET REFUSAL cause=LiveReadClassificationRefused

The refusal itself is correct and is not weakened here — it exists so a modelled refusal cannot be folded into a boolean and pass as SelectionSuperset. The defect is that #8055 made classification load-bearing before teaching it the test data form.

State of this branch

#8055 restored by cherry-pick of 7f7da933 done
#8099's P3 cohort probe deliberately not restored — measurement plumbing for the implementation, not needed to establish behaviour
main's ci_layer_roots #7446 citation correction verified present after the pick
gate_test note took #8055's wording; both sides carry the fixed symbol, they differ only by a G1 qualifier that is wrong once G2 returns
the test data repair NOT DONE — this is the whole point of the branch
ci.yml to be regenerated from authorities before ready, never hand-resolved (#8104's own lesson)

The repair, as designed so far

Feasibility established rather than assumed: the lens consumes a host-marshalled FnArrowDecl stream (v2.std.fn_index fn_arrow_decl_facts_live, itself a registered Scaffold), and data declarations are reachable in the Node tree — v2.lens.mandatory_tag already reads ^dag_surface_data_decl_name / _type / _expr, and _expr is the initializer body a data root classifies from. So this is a marshal extension plus a second root shape, not a new parser and not a cast of a data initializer into FnArrowDecl.

Binding must be decided once over the combined population. bind_g2_root's existing law exists because zero and many both looked like success: zero matching declarations seeded an empty walk that reaches no carrier and therefore classified LocalRead — the strongest answer, the one that licenses a skip. Trying fn-roots then data-roots and taking the first match would reintroduce that exact empty-observation narrow one level up. So: zero → Refused(Unbound), exactly one → classify that form, many → Refused(Ambiguous), over both populations at once.

Open, and not mine to decide

Whether a known-but-unsupported root form should force that entry to run (typed, counted, per-row) rather than refusing the entire affected-set computation. That is a three-way decision — classified / conservative-run / refused — reserving global refusal for genuine substrate incoherence. It is likely right and it changes what a refusal means on a load-bearing path, so it is awaiting operator sign-off rather than being inferred.

Acceptance bar (behaviour first, no falsifier run required)

  • all 38 test data roots bind and classify; unsupported = 0, ambiguous = 0, missing = 0
  • a paired control: a test data root classifies, AND a genuinely unclassifiable root still refuses and is counted — the first alone is satisfiable by weakening the refusal
  • the incident controls unchanged: total_entry_groups = 2, selected = 1, skipped = 1, B skipping via skip-before-resolve-fast-path
  • both G1 restoration mutations still produce 2 selected / 1 expected

No budget change of any kind is part of this branch.

Re-land base. Restores the G2 manifest consumption at every selection
decision, group_by, streaming value_hash, the accumulator fix, the
identity-join oracle, and the per-index selection-plan hoist.

NOT included, deliberately:
- #8099's P3 cohort probe. It was measurement plumbing for this
  implementation, not needed to establish behavior, and its removal in
  #8104 was forced rather than incidental.

Conflicts resolved:
- gate_test live_tree_disposition_note: took the #8055 side. Both sides
  already carry the corrected symbol live_read_carrier_homes_v0; they
  differ only by a 'G1' qualifier, which is wrong once G2 is restored.
- ci.yml: taken from the cherry-pick, to be REGENERATED from authorities
  before push rather than hand-resolved (#8104's own lesson).

main's ci_layer_roots #7446 citation correction verified present after
the pick.

THIS COMMIT ALONE STILL REDS MAIN. The test-data gap repair follows in
this branch; nothing is pushed until it lands.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title falsifier green Re-land #8055 with data-initializer roots: classify test data declarations instead of refusing selection Aug 10, 2026
The cherry-pick carried #8055's ci.yml, which no longer equals generator
output against current authorities. heal_generated_artifacts cannot
repair it: .github/workflows/** is author-commit-required by
construction (heal stages a fixed enumeration that excludes workflow
paths), so it uploaded a heal-author-commit-required bundle and refused
rather than committing.

Regenerated with a gunbc built from THIS branch (17:08), which is the
instrument CI uses: ci.yml checks out github.sha and compiles its bins
from that checkout. Generator run: 0 problems, ExitSuccess.

Not hand-resolved — #8104 demonstrated why a spot-check of a generated
artifact is insufficient.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls marked this pull request as ready for review August 10, 2026 20:40
@briansrls
briansrls merged commit f4add06 into main Aug 10, 2026
3 of 4 checks passed
@briansrls
briansrls deleted the reland/8055-live-read-data-roots branch August 10, 2026 20:40
briansrls pushed a commit that referenced this pull request Aug 11, 2026
#8120)

#8110 was merged while its own PR body reads "DRAFT — INCOMPLETE. The
branch in its current state still reds main. Do not merge, do not flip
to ready", and its status table marks the `test data` repair "NOT DONE —
this is the whole point of the branch". Merging it put #8055's
load-bearing G2 live-read classification back on main without the root
support it needs, which is exactly the class #8104 reverted #8055 for.

The located refusal, from the head run of 1741c08 (job 93623181081):

  AFFECTED-SET REFUSAL cause=LiveReadClassificationRefused
    entry=src/v2/test/claim/manual/derivable_coercion_nickname_triple_test.dag
    function=witness_claim_crux_substrate_gap
    detail=no fn-arrow declaration is named
           v2.test.manual.derivable_coercion_nickname_triple.witness_claim_crux_substrate_gap

Checked in code, not inferred from the title: the lens's root population
is fn_arrow_decl_facts_index_live alone, and fn_arrow_decl_rows_from_facts
skips every kind that is not FnItem/FuncItem, so no data root can bind.
The live population is 29 `test data` declarations across 5 files.

The refusal itself is correct and is not weakened here. What is removed
is the consumer that made an unrepaired classifier load-bearing.

Mechanically clean: no commit merged after #8110 touches any file it
changed, so every reverted file is byte-identical to its pre-#8110
content — verified, not assumed.

NOT CLAIMED: that this greens main. A second, independent failure
predates #8110 — the witness non_fold_residue_no_unrostered_or_stale was
already the red on ca64dba (the #8055 revert) at 15:45 on 2026-08-10.
This revert removes one of two causes; that one is being worked
separately.

What #8110 also carried and this revert therefore removes — none of it
implicated in the defect, all of it re-landable with the repair:
#8055's group_by primitive, the streaming value_hash, and the manifest
accumulator fix.

Operator authorized the revert directly (2026-08-11), having read the
draft's second half.


Claude-Session: https://claude.ai/code/session_01XxLzhuMisV3GAPpP2mBtSG

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 11, 2026
#8116 landed both halves of the #8059 dissolution-carrier skew and #8110 was
reverted, so main derives its own artifacts again and this branch's inherited red
clears. Merged with no conflicts -- the previous commit had already reverted the
duplicated heal, which is what left nothing to collide.

The three new emitted stage0 modules are now registered by the derived plan rather
than by hand: the bridge witness, the declaration matrix, and its support module.
`main_wet` reaches a fixed point proven by BYTES rather than by a third quiet pass
-- md5 of .gitattributes, ci.yml and the emit plan is unchanged across a further
run -- and the two-round seed regen verifies at regen_divergence_count=0 with
build exit checked before the verify.

Evidence re-run on the merged tree, not carried over: all seven scoped-roster
witness files green -- the declaration matrix 18/18, the import-deletion bridge
3/3, and the four siblings 13/4/4/7/3. Zero failures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 11, 2026
The live-read classifier asks what must be evaluated to produce a declaration's
value, and what that evaluation reads. Nothing in that question is about
functions -- but its root carrier is FnArrowDecl, its binder parameter is named
fn_name, and gunbc.ci_spec's witness row field is named function. So a
declaration form is welded into a type answering a question orthogonal to it.

The cost is visible: 'test data name: Bool = expr' is an enrolled witness form
(the test marker precedes BOTH fn and data in the grammar; the hygiene authority
carries test_fns and test_data as separate populations), and it arrives at a
function-only lookup as ZERO MATCHES -- byte-identical to a name that does not
exist. Two states, different remedies, one outcome: it cannot be counted, named,
or told apart from a broken reference.

EvaluationRoot is the shape both forms produce. A function projects its body and
params; a data declaration projects its initializer through the same named child
the grammar emits and mandatory_tag already consumes -- a projection over
existing structure, not a new parser. It takes the surface node rather than
DataInitDecl deliberately: that carrier holds literal_fp, a fingerprint of a
literal, which cannot be walked.

EvaluationRootUnavailable { subject, form, cause } is the state the chain lacks.
It names an EXISTING declaration whose expression could not be projected, and is
distinct from any 'no such declaration'. That split closes the path this exists
to prevent: form not representable -> no root -> empty walk -> no carrier ->
LocalRead -> licenses a SKIP. Under-selection presents as a faster green floor
rather than a failure, which is why it outranks over-selection.

DELIBERATELY INERT. Nothing imports it. #8055 and #8110 were both reverted for
making the classifier load-bearing ahead of its root support; the abstraction
lands and is witnessed first.

Evidence, by execution (claim_batch cannot run these -- its whole-tree precompute
fails on doc_graph_roots.dag v2.* imports, reproduced on pure origin/main -- so
each witness ran through gunbc run):

  5/5 green on the real code
  control 1 returns false against a mutant whose projection discards decl.output
  and returns a fresh empty node

That mutation initially left control 1 GREEN. The assertion was right and the
FIXTURE was vacuous: the specimen body was an empty synthetic node, structurally
identical to what the hollow projection returns, so 'carries the body' and
'carries a fresh empty node' were the same value. The specimen now carries a
named child edge. A witness that cannot fail is not evidence, and this one could
not until the fixture was fixed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot mentioned this pull request Aug 11, 2026
6 tasks
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