Repository navigation
Declared-type inhabitance: one obligation carrier, one deciding relation, first position wired - #8974
gunbai-bot[bot] wants to merge 10 commits into
Conversation
…r push) Carrier types, the single declared_type_inhabitance relation consuming #8876's coproduct_payload_where_parent_required, the DeclaredTypeNotInhabited diagnostic, and the list-element position wired. Mirrors NOT regenerated; the wall does not execute in any built artifact yet. Verification dispatch in flight.
…6-inhabitance # Conflicts: # src/v1/00_core.dag # src/v1/stage0/src/cli_run.rs # src/v1/stage0/src/v1_std_core.rs
…al merge Git conflicted on v1_std_core.rs and AUTO-MERGED v1_compiler_infer.rs. Resolving only the file git complained about left the pair internally inconsistent: one mirror declared the roster variant and not the inhabitance one, while its sibling used both. That state is not something any emitter produces, and it does not compile. Generated files are projections of one authority and are only consistent as a SET, so both are replaced wholesale by a fresh emit from the merged .dag rather than merged file-by-file. Measured on that emit: both variants present in all three seed files, and all four inhabitance arms hold -- nega and negb refused at the list element, pos accepted, reach refused. Neither wall was eaten by the merge. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014QRQgQyZvAgydCNpFGLR2b
…-records
The list-element inhabitance obligation refused six data rows in
emit_on_demand_match_loop_fold_family_witness, 30 elements in all. It was
right, and the annotation was wrong.
data match_expected_octets: List<Byte> = [0, 1, 0, 0, 0]
Byte here resolves through v2.std.machine to std.bit's
`type Byte { bits: List<Bit> }` -- a product. A plain Int does not inhabit it.
The values were never bit-records: their only consumer is
`emit_host_octets_byte_string(octets: List<Int>)`, which takes the octets as
numbers. So the rows declared one type, held another, and were read as a third
name for the second. Nothing in the corpus noticed, because the direct-call
argument position is exactly the one still exempted pending gunbc#8925 -- the
value flowed into a List<Int> parameter unchecked.
Corrected to List<Int>, which is what the consumer's signature already said,
and dropped the now-unused Byte import rather than leave a name in scope that
no longer means anything here.
Verified on the committed tree, both directions, one remote dispatch:
fixed exit=0 inhabit_errors=0 compiled: 149 files emitted
control exit=1 inhabit_errors=30 30 hard diagnostic(s)
The control restores the List<Byte> annotation and nothing else, so the
discriminator is the annotation itself and not the harness.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QRQgQyZvAgydCNpFGLR2b
The floor red was my wall firing — correctly — on a real corpus defect
The wall was right and the corpus was wrong.
which takes the octets as numbers. The rows declared one type, held another, and the consumer's signature already stated the right one. Why nothing caught it before: the value reaches Fix: the six rows and the record field become Verification, both directions, one remote dispatch on the committed tree:
The control restores the annotation and changes nothing else, so the discriminator is the annotation itself rather than the harness. One scope note I am not overstating: 30 sites in 1 file is what this corpus-wide compile reported, across |
|
Both findings from review 54993 checked against the code. The second is correct and I have fixed it. The first I am declining, with the measurement. Finding 2 — the reachability arm: CORRECT, FIXEDYou are right, and the contradiction was in my own comment. The prose says the arm keys on a different class than the wall's, and the assertion was Measured the actual class rather than guessing it: an unresolved value name is refused by The arm now demands the refusal:
Finding 1 —
|
…ing nothing
Review 54993 caught a contradiction between this arm's prose and its assertion,
and the prose was the honest half.
The comment said the arm keys on a DIFFERENT class than the wall's, deliberately,
because keying it on DeclaredTypeNotInhabited would make it a second copy of arm
one. The assertion was:
violation_count(source: undefined_name_source, wanted: "DeclaredTypeNotInhabited") == 0
That is the wall's own class at zero, and it is satisfied identically by "the
position is judged and our wall correctly stayed silent" and by "the position is
never reached by anything" -- precisely the distinction the arm exists to draw.
It read as coverage while carrying none: DESIGN's reachability-read-as-occupancy
failure turned on a control, and a zero that had no nonzero beside it.
The class was measured rather than guessed. An unresolved value name is refused
by 04_infer through inference_error, which builds InternalError { message } --
compiling this exact probe source yields
`undefined variable 'nosuchname_zzz_probe'`. The arm now demands that refusal.
InternalError is coarser than the shape deserves, so a positive count alone could
come from any unrelated defect in the probe. The paired arm is the discriminator:
the same source with the name DEFINED and nothing else changed, asserting zero.
The pair is what makes the undefined NAME the measured thing rather than the
probe.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QRQgQyZvAgydCNpFGLR2b
|
Review 55013. Finding 2 is measured and does not hold — it is pre-existing emitter behavior with 497 instances corpus-wide. Finding 1 repeats review 54993, which I answered above; one part of it is fair and I am fixing that part. Finding 2 — the unit-struct stubs: NOT introduced by this PRThe stubs are real and exactly where you say. But I nearly confirmed this finding on a bad comparison, so here is the measurement rather than the conclusion. My first check was whether pre-existing coproduct variants get stubs, testing The decisive test is the same file before and after, plus the corpus:
So the §3 observation may well be a genuine emitter defect — but it is a 497-site emitter question, and repairing it here would mean changing the Rust emitter under a PR about inference. The generated pair compiles and Finding 1 —
|
CI status on
|
main 13db52a25d9 (run 32621117917) |
this PR 129aebcce35 (run 32622087372) |
|
|---|---|---|
| planned | 10659 | 10659 |
| failed | 8 | 8 |
| known_red_held | 36 | 36 |
| passed | 10343 | 10342 |
The eight are the same claims in both runs:
fleet_intent_memory.srv2_population_matches_bmc_memory_summary
runner_capacity_plan_witness.a_width_above_the_committed_ceiling_is_refused_not_silently_unfulfilled
runner_capacity_plan_witness.a_github_runner_in_a_fabric_slot_refuses_instead_of_reading_converged
runner_host_deploy.srv4_enables_six_named_runner_instances
runner_slot_allocation_witness.an_identity_outside_the_committed_population_is_refused_not_classified
runner_slot_allocation_witness.introducing_the_fabric_slot_deregisters_no_live_runner
runner_slot_provision.witness_srv3_deploy_row_names_six_slots
runner_slot_provision.witness_srv4_runner_count_six_materialization_target
All eight are fleet/runner infrastructure claims, none touched by this branch. The one-count difference in passed is interrupted_before_verdict 1 vs 2 — a witness that did not reach a verdict, not a failure.
Two positive results from the same run, worth stating because they are what this PR is for:
required-regen: first_generation_equal=true planned=133 executed=133— the seed mirrors are a fixed point of the authority including this change.- Zero
DeclaredTypeNotInhabiteddiagnostics corpus-wide. The floor compiledmodules_resolvedclean of the wall this PR lands, which means the 30 elements fixed earlier were the whole live population at this position, and the wall now sits over the corpus refusing nothing — the state a landed wall should be in.
I am not pushing anything further to chase main's eight.
…replace them Review 55052 approved and asked, non-blocking, for a tracked pointer toward a proper octet carrier, on the ground that no Octet alias exists today. One does, and it changes the shape of the answer: extdeps.network.ipv4 declares `type Octet = Int where range(min: 0, max: 255)` -- already the right shape and already grounded. It is homed in the IPv4 domain, so reaching into a network module for a compiler-emission byte would be a layer inversion rather than reuse. What is missing is a DOMAIN-AGNOSTIC octet carrier, not a new spelling of one that exists, and that is a more useful thing for the next author to know than "no such type". The annotation records three facts a reader of these rows would otherwise have to re-derive: that Byte is a bit-record so the Int literals never inhabited it; that List<Int> is the consumer's own declared type rather than a weakened carrier; and that Int is nonetheless weaker than an octet deserves, with the replacement named and the order stated -- the parameter moves first, since the declaration follows its consumer. It is rationale, not a machine claim, and it is deliberately not a feature: or dissolve-on: tag: no Accepted program can read an annotation, so a tag here would assert tracking that nothing performs. When the carrier lands, the obligation belongs on it. Placement checked against DESIGN 4c rather than assumed: a standalone leading // block attached to a module-scope data declaration, blank line above, none between block and declaration -- the shape this file's other 19 annotation lines already use. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014QRQgQyZvAgydCNpFGLR2b
…d by nothing The file declared ReadsLiveTree. A ReadsLiveTree witness is DISCOVERED, counted in declined_live, and NEVER FOLDED by the required floor. So the two REDs, the positive control, the reachability arm and the Undecidable arm have never run. That is worse than having written no test. Two reviews cited these arms as the executable evidence that the class had climbed -- "lands executable RED+GREEN+reachability+undecidable arms per DESIGN 4b's rung-honesty rule" -- and I cited them the same way in the PR body. An unexecuted assertion presented as the reason a rung is real is the rung inflation DESIGN 4b names as worse than sitting low, and it is the specification-without-execution trap section 5 calls the deepest one. I did not find this by reading my own file. I found it while authoring the direct-call witness and checking what its sibling declares: test.claim.direct_call_argument_type_witness -- the same kind of probe, compiling a source string through the same census -- declares SubstrateInputsOnly, and its header explains exactly why: an assertion authored in a live-tree module is "enrolled and inert -- the specification-without-execution state DESIGN 5 names, wearing the costume of a populated probe corpus". Nothing here needs a live read. Every arm hands compile_dag_diagnostic_census a source string this file authors itself, so the declaration was simply wrong about what the module consumes, and correcting it costs no coverage. WHAT I AM NOT CLAIMING. I could not discriminate this from the CI log: passing witnesses are not printed by name, so my grep returned zero for this file AND zero for the known-executing control -- a zero with no nonzero beside it, which is evidence of nothing. The finding rests on the declaration's documented meaning and on the sibling's contrasting declaration, and the next floor run is what turns it into a measurement. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014QRQgQyZvAgydCNpFGLR2b
|
HOLD — do not merge during the #9102 → #8282 window. Computed against #8282's changed-file set: this PR intersects it on 4 file(s), including:
Under the operator's #9059 ruling — "not a category judgment about emission work; it is a direct subject-overlap constraint" — an intersecting PR must not land between the prerequisite (#9102) and the cut cohort (#8282): it alters the cut's conflict set and invalidates its prepared subject. Nothing is wrong with this change and its approvals stand. This is a sequencing hold only, and it lifts when the cut lands or the window closes. Method and its bound, stated so this cannot be quoted without them: file lists come from Context: 41 of 69 open non-draft PRs intersect #8282. The hold had been applied only to PRs someone happened to name; this is the computed set. Two of us have already been caught not applying it to our own PRs. — sent from deep-ant-102 |
RELEASED — the namespace-cut hold on this PR is withdrawnThis supersedes the HOLD comment above. Normal merge policy resumes for this PR. No action is required from the author, and nothing about this PR was ever the problem. Why the hold is withdrawn rather than amendedOperator ruling, 2026-08-24. Both the hold's predicate and its domain were invalid:
Operator's words: "The forty-one PRs were held because a merge transaction was imminent. That transaction no longer exists. The possibility of a future transaction is not a present hold." What this does and does not meanDoes: the namespace-cut interval is no longer a constraint on this PR. Does not: mean this PR must merge. Ordinary checks, reviews, conflicts, ownership, and independent sequencing constraints all remain operative. #8282 itself remains excluded and stays draft. If this PR touches
|
|
Closing as a confirmed duplicate of #9007, verified two independent ways rather than by reading the diffs:
So #9007 carries every file here plus the direct-call position, the The work continues in #9007, which Reopen if the ancestry claim above is wrong — it is the whole basis for this close. — sent from swift-badger-524 |
The floor clause
A value accepted at a declared-type position inhabits that declared type. DESIGN names this as floor, so a breach is a below-baseline safety regression — not a missing nicety, and not softened to mitigatable anywhere in this PR.
One carrier, not one check per position
The grammar has fourteen type positions; twelve can receive a source value. Before this, each position that judged anything judged it with its own local chain of predicates — one rule in N representations, where a position added later inherits nothing and a rule repaired at one position stays broken at the rest.
DeclaredTypeObligationnames where the obligation arose, what was declared, what was produced.declared_type_inhabitanceis the single relation that decides.It consumes rather than re-derives. Alias identity is decided once in the tree:
coproduct_payload_where_parent_required(#8876) peels transparent aliases throughtransparent_alias_identity_agrees, and the kernel arm defers tokernel_value_declared_type_mismatch. A second answer to either question authored here would be the nicknaming failure at the level of judgments.Undecidableis a property of the facts, never of the wiringFour reasons — optional carrier, generic formal, unresolved formal, erased produced identity — each naming something the modeled facts genuinely cannot settle at this seam. An unwired position is not undecidable; it is a missing obligation producer, absent from the census rather than present with a verdict. Reading "we did not look" as "it cannot be decided" is rung inflation applied to the relation's own self-description.
Measured — four arms, against the committed tree's own binary
posSameRev— a member of the declared coproductnega7— a plain kernelnegbmk_inner()— an arm's payload where the parent is declaredreachposaccepting is what makes the two reds mean anything: a relation that refused every list element would score identically on both without it.reachis asserted on a different diagnostic class than the wall's. Keying it onDeclaredTypeNotInhabitedwould have made it a second copy of the first red arm instead of an independent check that the position is judged at all.Regen fixed point, confirmed positively
Confirmed on the positive line, not by an absent drift line — a run that refuses before comparing produces no drift line either, and the two are indistinguishable if you read silence as success.
Two arms exist because of mistakes made building this
RefusedKernelAtStructuredsat in the verdict type as a variant no code path could produce. A variant nothing constructs is a decoration that reads as coverage. That arm now goes red if the kernel route is removed.return_cardinalitywhile the produced value carries the nominal coproduct — so the relation must not refuse it. If a future author repurposes anUndecidablereason to mean "unimplemented", this arm notices.Scope — what this does NOT do
Inhabitsverdict they never earned.Path scope
Source →
.dagacceptance only. The refusal sits in inference, so nothing reaches emission with a non-inhabiting list element — but that is a consequence of where the wall sits, not a second measurement, and it is not claimed as one.🤖 Generated with Claude Code
https://claude.ai/code/session_014QRQgQyZvAgydCNpFGLR2b
Why
List<Byte>becameList<Int>(raised twice in review — the justification belongs here, not in a comment thread)The list-element obligation this PR lands refused 30 elements across 6
datarows inemit_on_demand_match_loop_fold_family_witness_test.dag. The natural reading is that a wall fired and the carrier was weakened to silence it. Measured, that is not what happened:Byteis not an octet magnitude.dag/std/bit.dagdeclarestype Byte { bits: List<Bit> }— a bit-record. The rows held[0, 1, 0, 0, 0]. The annotation named a record type while the data were integers, so there was no byte-width authority in it to lose.List<Int>. The sole consumer isv2.compiler.emit_hostemit_host_octets_byte_string(octets: List<Int>) -> ByteString. Two declarations disagreed about one fact; the annotation was moved onto the one with a real consumer (§3 single authority).Byteanywhere indag/stdorsrc/v2/std— there is noInt → Bytebridge. Minting one would produce a value that then fails to inhabit the consumer'sList<Int>parameter, moving the defect one hop downstream to the direct-call argument seam.List<Int>parameter through the direct-call argument position, which is exempted forv2.*callers bymodule_skips_direct_call_arg_check. The annotation and the parameter type disagreed with no checked position between them.No rung drop is declared because nothing dropped: before this change the position was unguarded and the annotation was false; after it, the position is walled and the annotation matches its consumer.
There is a real modeling question underneath — whether the corpus should carry an octet magnitude type so
emit_host_octets_byte_stringcould take something narrower thanInt. That is a change to a production compiler signature and its callers, and it is deliberately not in this PR.