Skip to content

Split accumulator finding and analysis standings - #9179

Merged
briansrls merged 6 commits into
mainfrom
session/royal-cat-509-accumulator-standing
Aug 25, 2026
Merged

briansrls merged 6 commits into
mainfrom
session/royal-cat-509-accumulator-standing

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Outcome

Separates the accumulator-copy roster's semantic finding from its analysis-coverage standing without changing production compile admission.

  • RosterStanding is a product of FindingStanding and AnalysisStanding.
  • suspect and refusal counts are computed independently; a suspect no longer hides refusal coverage.
  • ingest failure is typed as not-established on both axes; the -1 count sentinel is deleted.
  • the offline Boolean gate consumes the two typed axes rather than collapsing them at classification.
  • a new SubstrateInputsOnly fixture discriminates the product cheaply, including simultaneous suspect + refusal debt, exceeded refusal budget, at-budget standing, and not-established standing.
  • the existing long symbol-index receipts consume the typed finding standing instead of sentinel-prone scalar counts.

accumulator_copy_compile_gate is deliberately untouched: proven Poly2Suspect findings still reject compilation, while Unclassifiable remains accepted diagnostics.

Why

The prior file_verdict selected RosterSuspectFound before counting refusals, so a file carrying both a product defect and analyzer-coverage debt reported only the first. Its downstream file_gate then reduced distinct remedies to one Bool. Separately, ingest failure returned -1, a sentinel inside the count domain that compared within every nonnegative ceiling.

This PR supplies the typed standing and pure classifier evidence required before #9106 retires the ten live file censuses. It does not delete those censuses or claim their corpus coverage remains live; their measured disposition and explicit rung-drop declaration belong to #9106.

Scope

Three .dag files. No compile-gate widening and no source-language acceptance change.

Producer-complete not-established causes

The first live use of the product standing found two FindingNotEstablished rows whose original single cause could not locate the responsible producer. The cause vocabulary is now shared under v2.lens.common.source_analysis_standing and is complete for source_findings: unavailable grammar, rejected grammar validation, tokenization rejection, parse rejection, and normalization rejection are distinct. The accumulator lens explicitly owns each dependency in its import closure and preserves the exact cause on both finding and analysis axes.

Direct typed remeasurement classified both live subjects as source-dependent SourceParseRejected: src/v2/lens/complexity_accumulator_copy/analyze.dag and src/v2/extdeps/languages/lean.dag. Neither is a global grammar outage. A pure malformed-source fixture independently reaches SourceTokenizationRejected, while the standing fixture proves an exact cause is preserved on both axes.

Live-subject interpretation\n\nBoth SourceParseRejected subjects are live modules inside the required production parse sweep, which is green on main. Lean (991 lines) and the accumulator analyzer (865 lines) are therefore confirmed accumulator-lens grammar gaps: the lens cannot parse sources the production parser accepts. Both remain as typed coverage-debt evidence, owned by the accumulator-lens grammar, with next-rung trigger ‘the lens parses what the production parser accepts.’ The broad 28,391-diagnostic run used /usr/local/bin/gunbc built 2026-08-18, predating current resolver behavior, and is not carried as evidence. A compiler rebuilt from this exact head instead refuses before compilation with WholeCorpusCompileBudgetBelowMeasuredDemand (7,053,705,216 B readable versus 7,516,192,768 B measured demand); its zero emitted diagnostics are no clean-corpus verdict because the compile never started.

@briansrls
briansrls merged commit 84e0f99 into main Aug 25, 2026
1 check passed
@briansrls
briansrls deleted the session/royal-cat-509-accumulator-standing branch August 25, 2026 15:04
briansrls pushed a commit that referenced this pull request Aug 25, 2026
…collapsing it (#9188)

* Split accumulator finding and analysis standings

* Make finding-standing Boolean descent explicit

* Own standing predicates beside their coproducts

* Export the not-established cause before its consumers

* Keep ingest-regressed cause construction canonical

* Type source analysis refusal causes

* An unreadable subject is not a clean one: carry the cause instead of collapsing it

source_has_suspect answered `false` when the analysis could not be established,
and `false` is the value that MEANS "no suspect". An instrument that could not
read its subject reported the CLEAN verdict, indistinguishable from one that read
it and found nothing. That is the empty-observation narrow, and it is worse than
the sentinel #9179 removed one function over: a sentinel never compares equal to
the passing value, `false` IS the passing value.

REACHABLE FROM A FIXTURE, NOT ONLY FROM AN OUTAGE. Three of source_findings' five
not-established causes are SOURCE-DEPENDENT -- tokenization, parse, normalization
-- so ill-formed TEXT alone produces it, with no grammar outage anywhere.
Measured on main before this change: source_has_suspect over a snippet that does
not tokenize answered false, beside a positive control answering true.

WHAT WAS ACTUALLY EXPOSED, since it is not what the shape suggests:
source_has_suspect has NO production callers. Its consumers are test claims, and
the ones at risk are the `== false` GREEN controls that pin these lenses against
FALSE POSITIVES. Had their snippet ever stopped parsing, they would have asserted
"not flagged" about a source nobody read, and the anti-false-positive guarantee
would have evaporated with every control still green. Controls that stop
controlling, rather than a lens that misses suspects.

FindingStanding is HOISTED WHOLESALE into v2.lens.common.source_analysis_standing
beside the cause #9179 put there. It carries no lens-specific payload, so this is
a move rather than a widening. A cross-lens import would have made one lens the
authority for the other's standings; a second copy would have been one concept
with two homes. Two total predicates go with it, and they are NOT each other's
negation -- finding_standing_established_clean and finding_standing_observed_suspect
are BOTH false for not-established, because an unread subject is neither a clean
one nor an observed suspect.

That distinction is why the red control changed shape. It now asserts SUSPECT
OBSERVED rather than "not clean": "not clean" is satisfied by an unread subject,
so the old form would have reported the planted defect as still alarming on a
build that analysed nothing at all.

EVIDENCE. New discriminating witness plus a positive control, driven both ways:

  as landed          not-established-rather-than-clean PASS, readable-clean PASS,
                     planted-copy PASS
  collapse restored  not-established-rather-than-clean RED, other two still PASS

The mutation is the pre-change program, and it kills only its own claim.
royal-cat's five standing tests pass unchanged over the hoist.

SCOPE, DELIBERATE: the identical defect in
v2.lens.identity_captured_navigation.roster_gate is NOT repaired here. That
module does not typecheck to the point of executing any control -- three fail
with a type cascade on plain main c271b75, before #9179 and before this
branch -- so a repair there could not be verified by execution. The work is
written and parked on parked/twin-source-standing-blocked, including the
grammar-first fix that stops a void grammar arriving disguised as a parse
rejection. It lands when that module executes.

* Point both consumers at the module that declares the hoisted names

The hoist moved FindingStanding and its predicates to v2.lens.common.source_analysis_standing
and left three references to finding_standing_holds with no definition anywhere. The receipt
witness now calls finding_standing_established_clean and imports it from its declaring module.
This is a rename, not an alias: the two bodies are byte-identical (NoSuspect => true, the other
two arms => false), so "zero poly2 suspects" asserts exactly what it asserted before -- an
established analysis with no suspect, with an unreadable source still refused rather than
counted clean.

The review named one file; the sweep found a second. accumulator_copy_roster_standing_test
still imported FindingNotEstablished, NoSuspect and SuspectObserved from roster_gate, which
no longer declares them. Its five witnesses passed anyway, by whole-pool type-position
resolution -- the same false-edge class, and one execution is structurally blind to. Both
blocks are corrected against the declaring module, and merged so the module is imported once.

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

* Carry the cause instead of collapsing it, and make the gate's answer askable

source_findings already returns a typed SourceAnalysisNotEstablishedCause. source_has_suspect
matched `SourceFindingsNotEstablished { cause: _ }` and answered false -- and false is the value
that means NO SUSPECT, so a subject the lens could not read was reported as the CLEAN verdict,
indistinguishable from one it read and found clean. The cause was not missing; it was present at
the site and discarded. It is replaced by source_finding_standing, which returns the standing.

RosterGateDisposition and file_gate_disposition give the same treatment to the gate: clean,
suspect-observed, refusal-budget-exceeded, and not-established-with-its-cause are four different
answers with four different remedies, and file_gate collapsed all but the first onto `false`.
file_gate still answers Bool for the callers that want "did it come back clean", but the collapse
is now written out arm by arm in one place, so a fifth disposition fails to compile there rather
than inheriting whichever arm it lands beside.

finding_standing_holds and analysis_standing_holds are RETAINED. A Bool projection over a typed
standing is legitimate exactly while the typed standing stays reachable by callers; it is the
defect only when it is the sole surface. The disposition is that surface.

MEASURED, and this is a live red on main rather than a hypothetical. The roster gate over
src/v2/lens/complexity_accumulator_copy/analyze.dag fails identically on unmodified origin/main
and on this head -- pre-existing, and that file has not changed since #8283. Arm-checked through
the new disposition, four probes one per arm: not clean, not suspect, not budget-exceeded,
GateNotEstablished, cause SourceParseRejected. The complexity lens cannot parse its own analyzer.
Under the old Bool that presents as `false`, the same value a genuine copied accumulator produces,
so the witness is not silent -- it is red, and its red points the reader at a defect that is not
there. Filed separately; not repaired here.

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 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