Repository navigation
Reshape the fn-arrow body skeleton so a call is a call: the marshal now emits the Transform carrier node_is_call accepts - #10282
Conversation
…ow emits the Transform call carrier node_is_call accepts
Every node the fn-arrow body skeleton marshal produced was a `TypeNode { connective: Conj }`
-- calls included -- while `v2.std.node_query` `node_is_call` accepts only a
`ComputationNode { behavior: Transform }` whose first positional child is a callee reference,
the carrier `v2.compiler.body_lowering_fold` produces for a lowered body. A Conj type node
cannot match a Transform computation node, so across the WHOLE live skeleton substrate
`node_is_call` was false, `node_callee_symbol` was Absent, and every call-shaped lens over it
-- `v2.lens.determinism` transitive findings, `v2.lens.machine_shape`, the origin probe's call
walk -- was GREEN BY CONSTRUCTION. That is DESIGN section 4b's decoration: a check whose RED is
unauthorable in the population it ranges over, worse than absent because it is cited as coverage.
THE REPAIR IS IN THE PRODUCER, NOT IN THE CHECK. Widening `node_is_call` to accept the Conj
spelling would have ratified the fork and made the substrate's own definition of a call
advisory. `marshal_generic` now returns `transform_record` for an `ExprCall` with a non-empty
authored name -- exactly the case where the callee identity leaf is already `edges[0]` -- and
`conj_record` for everything else, including a call through an unnamed callee expression, which
has no callee reference to be first and which `node_is_call` would refuse anyway.
THE SECTION 3 RECEIPT WAS ALREADY STANDING AND IS NOW DISSOLVED.
`v2.lens.no_dual_representation_test.scan` carried `skeleton_is_call`,
`skeleton_is_callee_atom` and `skeleton_call_argument_targets` -- private copies of
`node_is_call` / `call_callee_target` / `call_argument_targets` respelled against Conj, because
the shared authority could not read its own substrate. One question with two answers. The
copies are deleted, not parameterised, and that module now calls the authority. Its
`replace_param_in_output` descends every non-atom kind rather than Conj alone: a Conj-only arm
would have returned bodies containing calls UNSUBSTITUTED, answering "not alpha-equivalent" for
exactly the bodies the check is about.
EXECUTED EVIDENCE, with the delete arm confirmed to have deleted.
`marshaled_call_carries_the_transform_call_carrier` and its control
`marshaled_non_call_stays_a_conj_type_node` run on the required `cargo test -p v1-compiler
--lib` path. Reverting `marshal_generic` to the unconditional `conj_record` reddens EXACTLY the
first of them (4 passed, 1 failed) and restoring returns 5/5 green -- the mutation asserted its
own substitution before the verdict was read.
In .dag, `the_lens_fires_on_a_transform_shaped_call` and
`the_lens_is_blind_to_the_conj_shape_the_marshal_no_longer_emits` are enrolled as a pair
differing in ONE field, the node kind: one green alone cannot separate a correct lens from an
inexpressible subject. The `blind` row stays enrolled per section 4b(4) as the regression
control. The determinism fixture's seed body is now the call carrier itself rather than a shape
no marshal emitted.
Files one recurring_failure_mode row,
`fixture_shape_diverges_from_the_producer_shape`, bounded against
`executed_conjunct_discriminates_nothing` (there the RED was never authored; here the fixture
EXISTS and is what hides the defect) and against the sibling `v2.lens.effect_reach` disjunction
defect at adhoc-f0508f41-ae9, which presents identically and is repaired in the check rather
than in the producer.
NOT REGENERATED HERE: docs/design-failure-modes.md. Resolve refuses on this tree for reasons
that predate this change -- `absence_classifier_default_bucket` and
`green_reported_over_a_population_the_instrument_does_not_own` are each declared twice in
`gunbc.recurring_failure_mode` on main, plus unresolved `Plan`/`NonEmptyStr` types under
dag/gunbc -- so no projection can be produced from this authority until gunbc#10278 lands. The
.dag authority carries the row; the projection is a generated artifact and heals downstream.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vmMNtRoPfgkR75q8feHYg
# Conflicts: # dag/gunbc/recurring_failure_mode.dag
…er_shape row to the per-class carrier main split it into
|
Both findings in review 59532 verified against the current head (1e188e8). One is answered with a receipt, one is disputed on the authority it cites. Neither is fixed by a code change and I say why. Advisory — seed census for the hand-written Rust (accepted, receipt below). Measured on this diff, not estimated: Blocking — §4c on the The shape is also not mine to choose. So the finding is real as a CLASS OBSERVATION about the carrier and I am not disputing that the debt exists — it is filed on the carrier, by the carrier, today. It is not a defect in this row, and repairing it here would mean redesigning — sent from cool-fox-470 |
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
# Conflicts: # docs/design-failure-modes.md
… same class, dissolve the duplicated shape-gap pair, and retire the stall its trigger just satisfied #10245 landed the same class from the same specimen while this PR was in review: check_subject_shape_cannot_represent_the_state_the_check_detects. Two names for one concept is the defect this PR exists to remove, so fixture_shape_diverges_from_the_producer_shape is DELETED and the three receipts of mine that its row does not carry are appended to it instead -- the non-symmetric repair direction (reshape the producer, never widen the check), the static field tell (a private copy of the shared predicate is visible by reading), and the evidence shape (a hand-built fixture can attest a lens and never a marshal, so the producer's row lives on the seed test path). Same move on the witness: #10245's shape_gap pair and mine were the same two rows, so mine are deleted and theirs kept. Their blind arm is renamed for what it now means -- the marshal no longer emits that shape -- and the paragraph's prediction that the blind arm would RED when the capability landed is corrected rather than removed: the arm asserts a Conj node is not a call, which was true before and is true after; what changed is whether the live substrate can produce the other one. v2.lens.determinism's stall named its trigger as a capability -- the fn-arrow body skeleton represents a call at a shape node_is_call accepts -- and this PR is that capability, so the annotation retires it by its trigger. What it does NOT claim: that a live RED is constructible end-to-end. atom_identities_in_node reads callees at depth one, so a call inside a block body is below the horizon call_reachable_decls seeds from; that is a different defect, unrepaired here, at work item adhoc-6af6a225-11d. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011vmMNtRoPfgkR75q8feHYg
…ape_cannot_represent_the_state_the_check_detects An edit slip from appending receipts to an existing list: the anchor line already ended with a comma and the insertion added its own, producing `",,` between two elements. Caught by review 59625 before the parser had to. No content change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011vmMNtRoPfgkR75q8feHYg
… for CI to regenerate from the authority The only conflicting path is the GENERATED PROJECTION, and a generated artifact is not hand-merged: choosing a side there is how two hand-resolved regions produced the duplicate-declaration break on main earlier tonight. Neither side's bytes are authored, so main's are taken as a placeholder and the heal-generated-artifacts actuator re-derives the file from gunbc.recurring_failure_mode -- the same route that has healed this branch three times in this PR. The authority carries the receipts; the projection follows it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011vmMNtRoPfgkR75q8feHYg
…ecl.output is Conj except a named call, which is the Transform carrier A consumer of `FnArrowDecl.output` looks up the type here, not in the seed marshal that builds it, and a consumer that guesses the shape wrong does not get an error -- it gets a green. That is exactly how this defect ran: every call-shaped lens over these skeletons was permanently green, and `v2.lens.no_dual_representation_test.scan` grew a private copy of `node_is_call` spelled against `Conj` rather than anyone noticing the authority did not apply. Both repaired in this PR; the shape is now stated where the type is declared, with the pre-#10282 state kept as the reason the paragraph exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011vmMNtRoPfgkR75q8feHYg
… main (generated projection left to the heal actuator)
Review 59706 is right and it is this repo's own §5 tell aimed at my regression wall: the probe read
only the outer variant names, so a marshal emitting ComputationNode { behavior: Loop } over a
TypeNode { connective: Conj } child would have kept it green while node_is_call went false again.
The assertion could be satisfied while the realization lied. It now reads the full path both
predicates read -- kind ComputationNode AND behavior Transform, first positional child TypeNode AND
connective Atom -- and the control asserts Conj rather than merely TypeNode.
The mutation receipt still holds and is now stronger for a different reason: it discriminated
before because the mutation changed the outer tag, which is exactly the narrow case the old
assertion happened to cover.
docs/design-failure-modes.md is the only conflicting path and it is generated; neither side's bytes
are authored, so main's are taken and heal-generated-artifacts re-derives it from the authority.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vmMNtRoPfgkR75q8feHYg
…der the chain forces The regen drift was mine and it was TWO levels, not two files. LEVEL 1 -- v1_compiler_compiler_tests_rust.rs. I added ct_kernel_identity_single_authority_test to src/v1/compiler_tests_rust.dag and never wrote that module's own generated twin. It now carries the new emitter function and its entry in ct_coercion_tests's concat chain. LEVEL 2 -- compiler_tests.rs. Its only difference from the emitter's output was the POSITION of the test: I hand-inserted it before shaped_type_node, the emitter appends it at the end of ct_coercion_tests. Verified as a pure move rather than a content change -- the two files have an IDENTICAL MULTISET OF LINES and equal byte length, differing only in order. THE ORDER OF THE TWO PASSES IS FORCED AND THE NAIVE FIX IS SILENTLY DESTRUCTIVE. compiler_tests.rs is emitted by the seed's COMPILED-IN emitter, so a first-pass candidate is produced by the emitter as it was BEFORE this change -- it cannot emit a test it does not know about. That candidate was 134 lines short, exactly the size of the test, and copying it would have DELETED the enrolled RED while satisfying the drift check: a green PR whose discriminating probe no longer exists. So: pass 1 installs the emitter's own mirror, the seed is REBUILT so the emitter knows the test, and pass 2 produces a compiler_tests.rs that contains it -- 4521 lines, matching, with the test present. Checked rather than assumed: both files are byte-identical to their pass-2 candidates after cargo fmt, so formatting cannot re-introduce drift; the test and its discriminating assertion are present in the committed bytes. Regenerated on top of ce937d0, merged first because #10282 reshapes the marshal and a candidate computed on the older base could have been bytes that fight it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg
…t the rung above codex review 59889 is right and it is a blocking defect: the row declared "CEILING: 3 (mechanically preventable)", and DESIGN.md section 4b numbers those differently -- 2 is mechanically preventable, 3 is structurally guaranteed. A row whose whole subject is a grain mismatch between a stated loss and its trigger carried a grain mismatch between its own ceiling's number and its name. THE NUMBER WAS RIGHT AND THE NAME WAS WRONG, established from the mechanism the row already described rather than by picking the safer digit. "Triggers and losses become typed references to the same capability identity" is a refusal the compiler derives from modeled structure, which is section 4b's rung 3 -- not a gate that must execute and stay enrolled, which is rung 2. AND THE ROW NOW DERIVES WHY IT IS NOT 4, because "could this be structurally impossible" is the question a corrected ceiling invites and leaving it unanswered is how the next reader re-opens it. Section 4b(1) reads a class's rung as the MINIMUM across its in-scope parts. The subject-mismatch half could reach 4: typed at one grain, a trigger naming a route has no constructor. The other half cannot, because retirement also requires the capability's discriminating witness to HOLD at its named position, and a witness holding is executed evidence rather than a constructor. The ceiling is the weaker of the two, and claiming 4 would be the rung inflation this ladder exists to name. Projection regenerated as a UNION rather than resolved to a side: main's content (#10282's amendment among it) plus this row's new body. Verified at both halves rather than by confirming my own row came back -- membership join 97/97 MISSING=0 order-equal, and the authority diff against main shows only this row file and the two roster lines, so every other row is byte-identical to main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FSjamJZnktJ59XsarNLyeH
… it was never there Review point from the #10282 lane: writing all four rows as "declared cause falsified" lets the next reader conclude #10282 fixed nothing. It fixed one of these four. The structural-fixture row WAS held red by the marshal, that repair is real, and what remains is a different mechanism -- the marker read -- holding the same row red. The other three were never operatively blocked by the marshal. So that row's note, its admission reason, and the fixture module's annotation now name the superseded sentence, say it was true when written, and say what took over. The file-level paragraph splits the four the same way rather than asserting one verdict over all of them. Wording only; the four rows are still red and the admission walls still hold. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JFCwaz6h5cQv3fih9is2Yc
… of above the module that had to re-spell it (#10350) * Home the kernel-identity authority beside the minter it asks, instead of above the module that had to re-spell it XL-0B's first constraint, discharged. gunbc.type_reference_decl_file_occurrence_census's kernel-minted-provenance row states it: the KernelMinted arm must be DERIVED from resolved_node_is_kernel_identity_for_name rather than re-spelled, "because a fifth prefix test would add an authority while claiming to remove four." THE FORK WAS POSITIONAL. v1.compiler.infer_env DECLARED that predicate and never called it. The module that mints the span it tests -- v1.std.core, whose kernel_span synthesizes "<kernel:NAME>" -- cannot import infer_env without closing a cycle, so declaration_provenance_of re-derived the same comparison in place. One fact, two spellings, for no reason but where the declaration sat. The predicate now lives in v1.std.core beside kernel_span, and declaration_provenance_of reads it. AND THE SPELLING IT REPLACED WAS THE WEAKER ONE, which the census had not counted. The infer_env body inlined concat("<kernel:", name, ">"), reproducing kernel_span's output by hand -- so it was a second authority for the span FORMAT as well as for the identity question. The relocated body asks kernel_span. Editing that format used to leave the recognizer answering the old shape with no refusal anywhere; that divergence now has no constructor. EVIDENCE, BOTH DIRECTIONS, BY EXECUTION. ct_kernel_identity_single_authority_test runs in the required rust-unit-tests job under `cargo test --release -p v1-compiler --lib`. Green as authored. Red under exactly the mutation it exists to catch -- exact equality replaced by a "<kernel:" prefix test -- failing on the discriminating row (a node carrying a kernel span for a DIFFERENT name), with a positive control that stops that row being satisfied by a predicate that had simply stopped answering true. Enrolled per DESIGN 4b(4): the climb keeps its discriminating red. That suite is RED ON MAIN independently of this change -- 16 failed / 728 passed on an unmodified tree at e5a51d6, measured by running the identical command on a clean checkout before attributing anything here. The failures are host/index-sensitive (schedule_retention, regen_round_cost, required_floor) and are not touched by this diff. SCOPE, STATED SO THE LARGER HALF IS NOT READ AS DONE. This discharges the FIRST of the two constraints the census names. The second is untouched and is bigger: CorpusDeclared still carries decl_file as a position, so the DeclarationCarrier half std.repair_input_origin explicitly defers to XL-0B/C is still owed. Both ledger rows are updated to say so and to cite the predicate at its new home rather than at the stale (and, in state_space_conflation, never-existent "v1.compiler.env") one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg * Escape the quotes in the census row's prose so the module index can parse it The XL-0B receipt I appended to gunbc.type_reference_decl_file_occurrence_census quoted the spelling it was retiring -- concat("<kernel:", name, ">") -- with RAW double quotes inside a .dag String literal, which terminates the string and makes the source unparseable. The module index then refuses the whole corpus, so heal-generated-artifacts could not index the tree and never reached the regeneration the design-ledger carve-out delegates to it. The file already uses the escaped form for exactly this; the added row now matches it. AND THE DIAGNOSTIC'S LOCATION IS A BYTE OFFSET WEARING A LINE NUMBER'S CLOTHES. It reads `dag/gunbc/type_reference_decl_file_occurrence_census.dag:15713-15714`, and that file is 526 lines in every tree -- main, this head, and the merge result. 15713 is the BYTE offset of the opening quote of the broken literal. So the span is correct and its RENDERING sends every reader to a line that does not exist. Filed separately rather than fixed here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg * Emit the assertion message with a positional placeholder: {name} interpolates in a .dag string The emitter row I added spelled its Rust assertion message with an inline format capture, `{name}`. Inside a .dag String literal that brace form is INTERPOLATION, so the compiler resolved a variable `name` that does not exist in ct_kernel_identity_single_authority_test and refused the v2 self-compile. The bare `{}` placeholder already used elsewhere in this file does not interpolate, so the message takes an explicit argument instead. THIS ERROR WAS HIDDEN BEHIND THE PARSE REFUSAL and is the reason the whole-corpus pass matters: while the module index refused to build, nothing downstream ran, so a second defect in a different file sat invisible behind the first. Two sequential whole-tree runs were needed to see both, and neither is visible to a cargo build of the seed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg * File the mislocated-span class: a located refusal that renders a byte offset as a line Filed at the manager's request after gunbc#10350's module-index refusal cited dag/gunbc/type_reference_decl_file_occurrence_census.dag:15713-15714 in a file that is 526 lines in every tree. The span was CORRECT: 15713 is a byte offset, and the path was right. Only the rendering was wrong, and 'path:N-M' declares no unit, so the reader cannot tell which they hold. WHY IT EARNS A ROW RATHER THAN A FIX AT THE SITE. The reader who hit it did the correct diligence -- checked the cited file in main, the PR head and the merge result, confirmed it is not a generated artifact, declined to guess -- and was defeated anyway, authoring two candidate mechanisms (wrong path attribution, corpus-global line index) that were both false and neither eliminable from the log. A diagnostic that defeats correct diligence is the subject, not the quoting bug that surfaced it. It is the fabricated-plausible-output shape applied to a diagnostic's own span, and it is worse than an unlocated refusal rather than better: an unlocated refusal makes the reader search and they know it, while a confidently mislocated one makes them doubt the path and the tool. CEILING is rung 4 and the class is decidable, so the row names the capability rather than an artifact: a span type whose constructors distinguish byte offsets from line-column positions, with renderers deriving format from the constructor. That is a change to the span carrier and every renderer, so it is filed at the grain it must be repaired at rather than patched where it appeared. Carrier only -- docs/design-failure-modes.md is authored by heal per gunbc.generated_artifact's HealRegeneratesAfterProvisionalMerge carve-out. Appended at the END of the roster, per its own source-order rule. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg * Cite jolly-ferret's sibling instance: two right-value wrong-rendering diagnostics in one night gunbc#10352 found the floor rendering cost=500ms EXACT from an integer-truncated nanosecond measurement -- comparison correct, refusal correct, rendering defective, and it recruited auditors into filing against the comparator. Same shape as this row's byte-offset-as-line, reached from an unrelated subject by a reader who was not looking for it. Two independent instances is what makes the operative rule worth stating: WHEN A LOCATED DIAGNOSTIC POINTS SOMEWHERE IMPOSSIBLE, DISTRUST THE UNITS BEFORE THE LOCATION. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg * chore: regenerate drifted generated artifacts (ci auto-heal) * Regenerate both levels of the compiler-tests emitter chain, in the order the chain forces The regen drift was mine and it was TWO levels, not two files. LEVEL 1 -- v1_compiler_compiler_tests_rust.rs. I added ct_kernel_identity_single_authority_test to src/v1/compiler_tests_rust.dag and never wrote that module's own generated twin. It now carries the new emitter function and its entry in ct_coercion_tests's concat chain. LEVEL 2 -- compiler_tests.rs. Its only difference from the emitter's output was the POSITION of the test: I hand-inserted it before shaped_type_node, the emitter appends it at the end of ct_coercion_tests. Verified as a pure move rather than a content change -- the two files have an IDENTICAL MULTISET OF LINES and equal byte length, differing only in order. THE ORDER OF THE TWO PASSES IS FORCED AND THE NAIVE FIX IS SILENTLY DESTRUCTIVE. compiler_tests.rs is emitted by the seed's COMPILED-IN emitter, so a first-pass candidate is produced by the emitter as it was BEFORE this change -- it cannot emit a test it does not know about. That candidate was 134 lines short, exactly the size of the test, and copying it would have DELETED the enrolled RED while satisfying the drift check: a green PR whose discriminating probe no longer exists. So: pass 1 installs the emitter's own mirror, the seed is REBUILT so the emitter knows the test, and pass 2 produces a compiler_tests.rs that contains it -- 4521 lines, matching, with the test present. Checked rather than assumed: both files are byte-identical to their pass-2 candidates after cargo fmt, so formatting cannot re-introduce drift; the test and its discriminating assertion are present in the committed bytes. Regenerated on top of ce937d0, merged first because #10282 reshapes the marshal and a candidate computed on the older base could have been bytes that fight it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg * chore: regenerate drifted generated artifacts (ci auto-heal) * chore: regenerate drifted generated artifacts (ci auto-heal) * Adjudicate the relocation's two binding deltas by name, and stop the emit side reading a resource as a type TWO SEPARATE THINGS LAND TOGETHER BECAUSE CI IS THE BINDING CONSTRAINT, not because they are one change: the wave-admission rows this PR's own relocation requires, and the emit-side repair the type-occurrence census refusal pointed at. -- THE ADMISSION ROWS -- required-ci refused with `namespace-wave-admission (2 unadjudicated delta(s), 0 stale admission(s), 16 consumed admission(s))`. The two deltas are this PR's whole content: TargetChanged binding v1.compiler.infer::ancestry_binding_is_kernel_identity TargetChanged binding v1.compiler.emit_rust::import_name_resolves_to_host_realized_kernel_scalar both for `resolved_node_is_kernel_identity_for_name`, base {v1.compiler.infer_env} -> head {v1.std.core}. A relocation MUST produce TargetChanged bindings; the wall refusing until someone says so out loud is the wall working. They are UNADJUDICATED, not unadjudicatable. Adjudicated at full identity grain -- module, in_declaration, spelling, target -- one row per delta, so the count goes 2 -> 0 by naming both subjects and not by widening. A third delta of the same shape still refuses, which is what makes this distinguishable from erasing the subject. The rows are born with their own death declared: when this merges, base and head both carry the relocation, no run can produce these deltas, and both go STALE -- which reds every unrelated PR. The trigger beside them says explicitly not to trust itself: join each row against MAIN'S tree on its own tuple, and assert rows-checked equals rows-in-label, because a path guessed from a module path reads empty and empty reads identically to "the binding is absent" -- the mechanism that nearly carried 128 rows wrongly on the twenty-sixth entry. -- THE EMIT-SIDE REPAIR -- The activation-revision recensus refused: CensusUnavailable { cause: DeclarationDomainDisagrees }, two occurrences, `dag/std/resources.dag::Network` and `::AuthContext`. The cause was already authored in the tree. v1.compiler.parse's classifier gained a resource arm, dropping divergence from 202 items across 100 modules to these two, and its note ends: "Repairing the emit-side shape predicates is a change to a different authority and is deliberately not smuggled in here." This is that repair. Those two resources declare NO capabilities, so they carry no children, no body, no params and no connective -- they ARE bare leaves by shape, so the emit side read them as type items while the parser read them as resources. Not instrument-only: all three emitters test is_type_decl_item BEFORE is_resource_def_item, so both were EMITTED AS TYPE DECLARATIONS and the resource arm was unreachable for them. The exclusion DERIVES rather than re-spelling: is_type_alias_item and is_type_decl_item ask v1.compiler.parse parsed_item_carries_resource_entries, the same single authority the parser asks, so "what a resource item is" has one definition and these are two consumers of it. Spelling the shape again here is what produced the divergence. NOT PLACED IN is_bare_leaf_item, which would have been one site instead of two: that predicate is a statement about SHAPE, a capability-less resource genuinely IS a bare leaf, and it has consumers outside these arms whose meaning depends on its params-count claim -- narrowing it would have silently changed alias hopping instead of resource classification. AND NOT REPAIRED BY REORDERING THE CHAIN, which would also have greened the census. is_resource_def_item still COUNTS properties -- the shape parse already had to fix -- so it would claim any sole_constructor type, masked today only because the type arms run first. Reordering would have ARMED that over 202 items while turning the instrument green. That dormant defect is filed as the failure-mode row dispatch_correctness_resting_on_arm_order: mitigatable today, ceiling structurally impossible, and its next-rung trigger names the CAPABILITY -- a positive item kind carried on the emit side, so dispatch derives as an exhaustive match and cannot be order-sensitive. -- EVIDENCE -- The enrolled test asserts the composite the census actually joins on -- is_type_def_item OR is_type_alias_item OR is_type_decl_item -- and not one arm. An earlier draft asserted is_type_decl_item for a property-free bare leaf and went RED: with no inferred type such an item reads as a type ALIAS. It is still a type item; the arm was the wrong subject, and a control that had passed by luck would have shipped a test measuring something other than the refusal. Four rows: the positive control, the resource discriminator (removing the exclusion turns it true), an over-correction guard asserting a sole_constructor-only item is STILL a type item so the exclusion can never be re-spelled as a property count, and a reader-agreement equality that fails from either side. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg * Restore the generated mirrors from this branch's side so the tree compiles before regeneration Taking main's side of the four generated artifacts during the merge was wrong in a way the merge itself could not show. v1_compiler_emit_rust.rs on main still calls crate::v1_compiler_infer_env::resolved_node_is_kernel_identity_for_name -- the symbol THIS BRANCH MOVED to v1.std.core -- so the merged tree did not compile, and a tree that does not compile cannot be regenerated. The plan 'take theirs, regen will supply the truth' has a precondition I did not state: regen must be able to BUILD, and the file breaking the build was the one waiting to be regenerated. Restored all four from this branch's pre-merge head, which is a compiling tree. These bytes are still not authored on either side and are not the answer -- they are a build-able starting point so the regeneration can produce the real ones from the merged .dag authorities, which carry both this branch's relocation and main's changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg * Bootstrap the emit mirror to a tree that compiles: main's bytes plus this branch's three-substitution delta NEITHER SIDE OF v1_compiler_emit_rust.rs COMPILES AGAINST THE MERGED TREE, which is why two regen attempts died at 127 with no regeneration running at all. Main's copy calls crate::v1_compiler_infer_env::resolved_node_is_kernel_identity_for_name -- the symbol this branch moved -- and fails E0432. This branch's copy predates main's call-arity change and fails E0061. The file that must be regenerated is the file preventing the build that produces the regenerator. Broken by applying THIS BRANCH'S DELTA to MAIN'S BYTES, counted rather than eyeballed: three substitutions, each asserted to occur exactly once before replacement -- drop the spelling from the v1.compiler.infer_env re-export list, add it to the v1.std.core import list in the slot this branch uses, repoint the single call site. Post-conditions asserted: zero stale references remain, exactly one repointed reference exists. The re-wrap that follows is cargo fmt's, not mine: the pre-commit hook refused the hand edit until the import list was re-wrapped, which is the hook catching exactly the class of damage hand-editing a generated file does. The other three generated artifacts are taken from main verbatim, because none references the moved symbol and none needs a delta to build. Confirmed rather than assumed for compiler_tests.rs, which is the one that could have. THESE BYTES ARE A BOOTSTRAP, NOT THE ANSWER. The regeneration that follows overwrites all four from the merged .dag authorities. If the regenerated bytes differ from these, the regenerated ones are right. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg * chore: regenerate drifted generated artifacts (ci auto-heal) * Install the regenerated stage0 mirrors, and confirm the bootstrap reproduced the generator exactly The four generated artifacts now carry what --required-regen emits from the merged .dag authorities, produced by the forced two-pass order: install the emitter's own mirror, REBUILD so the emitter knows the new test, then regenerate the file it emits. A single pass emits compiler_tests.rs from the PRE-EDIT emitter, which cannot know a test that was just added. THE BOOTSTRAP WAS EXACT, AND THAT IS A RESULT RATHER THAN AN ASSUMPTION. v1_compiler_emit_rust.rs is ABSENT from this commit: the regenerated bytes are identical to the hand-applied bootstrap, so the three counted substitutions reproduced the generator's output precisely. Had they differed, the generator's bytes would have won and this commit would say so. VERIFIED BY EXECUTION, NOT BY COMPILE: cargo test --release -p v1-compiler --lib on the regenerated tree runs a_resource_item_is_not_read_as_a_type_item and it PASSES. The over-correction guard -- a sole_constructor-only item must still read as a type item -- is present in the emitted bytes, so the exclusion cannot be silently re-spelled as a property count without this going red. Both files are byte-identical after cargo fmt, so formatting cannot re-introduce drift. docs/design-failure-modes.md is deliberately NOT updated here. --required-regen does not emit it -- a run where all four .rs mirrors installed cleanly produced no projection candidate at all -- because that artifact is heal's under the design-ledger carve-out. The tree therefore lands authority-ahead-of-artifact on that one file BY DESIGN: the roster carries 101 rows and the projection 99. That is the state heal repairs and the generated-artifact gate can see. The state nothing downstream can see -- a row deleted -- was checked for by set difference against main and is absent. THE 16 SUITE FAILURES ARE MAIN'S, ESTABLISHED BY AN IDENTITY JOIN AND NOT BY A COUNT. Two trees on one runner, preconditions asserted before the comparison was trusted: the patch present in one (4 references) and absent in the other (0), and the two tree shas required to differ. Failing test NAMES compared as sets: mine MINUS main is EMPTY, main MINUS mine is EMPTY. An earlier attempt at this join was VACUOUS -- both arms silently measured the same tree, which guarantees identical sets by construction and looked exactly like the answer. Two sets of sixteen can be disjoint, so the count match established nothing on its own. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg * chore: regenerate drifted generated artifacts (ci auto-heal) * chore: regenerate drifted generated artifacts (ci auto-heal) * Retire the 30 consumed gunbc#10355 admissions this roster-touch owes The namespace-wave-admission phase refused with `0 unadjudicated delta(s), 0 stale admission(s), 30 CONSUMED ADMISSION(S) DUE FOR DELETION ON THIS ROSTER-TOUCH`. The zero/zero half is the good reading -- this branch's own namespace work is clean. What refuses is the obligation the roster imposes on whoever touches it next: #10355 is in this branch's base, so its rows are satisfied at the base, and a consumed row comes due on the roster's own next touch. This change touches it. ADJUDICATED BY THE DECLARING-MODULE JOIN, NOT BY THE TRIGGER SENTENCE, because the entry being retired says in terms that a trigger sentence is not evidence the trigger fired. Each row was joined against MAIN's tree by its own (module, in_declaration, spelling, target) tuple: 30 of 30 name a spelling DECLARED in gunbc.scm.proposal, none open. Rows checked equals rows in label equals the count the wall reported -- 30 = 30 = 30 -- so the subject was not silently narrowed by a parser that could not see some of it. ONE OF THIS FILE'S TWO RECORDED JOIN FAILURE MODES ACTUALLY FIRED. RequireBinding and RequireBindingAbsent are COPRODUCT VARIANTS rather than data/fn/type declarations, so a declaration index reading only line-start declarations would have answered "not found" for both -- indistinguishable from "not declared", which is precisely the defect the TWENTY-NINTH DISSOLUTION records catching on its second pass. The join resolves variants and fields as well as declarations, and it was CALIBRATED rather than trusted: MergeCommit, ObjectStore and a fabricated name all answer NOT DECLARED against the same module, so a uniform "found" was not available to it. The two gunbc#10350 kernel-identity rows REMAIN. They are not consumed: this PR has not merged, so the base does not carry the relocation and the deltas are still producible. Their own deletion is owed to the first roster-touch after this lands, by the same join. SCM_PROPOSAL_VOCABULARY_LABEL is deleted with its rows, and the cohort's entry is retitled as the THIRTIETH DISSOLUTION recording the adjudication, including what the hand join does NOT establish: it is a necessary condition only, since admission_consumed_at_base resolves the full subject through the re-export chain and requires an exact singleton, which no hand join reproduces. The wall's own run at the exact head is the proof. The remaining required-witnesses-floor red is NOT addressed here and is not this branch's: STALE-QUARANTINE on test.claim.declared_type_expected_type_path_witness, inherited from #10402 landing a wall without retiring the expected-red row it greened. It is owed a standalone repair; carrying it here would put main's recovery inside a feature PR that is separately blocked on review. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Every node the fn-arrow body skeleton marshal produced was a
TypeNode { connective: Conj }-- calls included -- while
v2.std.node_querynode_is_callaccepts only aComputationNode { behavior: Transform }whose first positional child is a callee reference,the carrier
v2.compiler.body_lowering_foldproduces for a lowered body. A Conj type nodecannot match a Transform computation node, so across the WHOLE live skeleton substrate
node_is_callwas false,node_callee_symbolwas Absent, and every call-shaped lens over it--
v2.lens.determinismtransitive findings,v2.lens.machine_shape, the origin probe's callwalk -- was GREEN BY CONSTRUCTION. That is DESIGN section 4b's decoration: a check whose RED is
unauthorable in the population it ranges over, worse than absent because it is cited as coverage.
THE REPAIR IS IN THE PRODUCER, NOT IN THE CHECK. Widening
node_is_callto accept the Conjspelling would have ratified the fork and made the substrate's own definition of a call
advisory.
marshal_genericnow returnstransform_recordfor anExprCallwith a non-emptyauthored name -- exactly the case where the callee identity leaf is already
edges[0]-- andconj_recordfor everything else, including a call through an unnamed callee expression, whichhas no callee reference to be first and which
node_is_callwould refuse anyway.THE SECTION 3 RECEIPT WAS ALREADY STANDING AND IS NOW DISSOLVED.
v2.lens.no_dual_representation_test.scancarriedskeleton_is_call,skeleton_is_callee_atomandskeleton_call_argument_targets-- private copies ofnode_is_call/call_callee_target/call_argument_targetsrespelled against Conj, becausethe shared authority could not read its own substrate. One question with two answers. The
copies are deleted, not parameterised, and that module now calls the authority. Its
replace_param_in_outputdescends every non-atom kind rather than Conj alone: a Conj-only armwould have returned bodies containing calls UNSUBSTITUTED, answering "not alpha-equivalent" for
exactly the bodies the check is about.
EXECUTED EVIDENCE, with the delete arm confirmed to have deleted.
marshaled_call_carries_the_transform_call_carrierand its controlmarshaled_non_call_stays_a_conj_type_noderun on the requiredcargo test -p v1-compiler --libpath. Revertingmarshal_genericto the unconditionalconj_recordreddens EXACTLY thefirst of them (4 passed, 1 failed) and restoring returns 5/5 green -- the mutation asserted its
own substitution before the verdict was read.
In .dag,
the_lens_fires_on_a_transform_shaped_callandthe_lens_is_blind_to_the_conj_shape_the_marshal_no_longer_emitsare enrolled as a pairdiffering in ONE field, the node kind: one green alone cannot separate a correct lens from an
inexpressible subject. The
blindrow stays enrolled per section 4b(4) as the regressioncontrol. The determinism fixture's seed body is now the call carrier itself rather than a shape
no marshal emitted.
Files one recurring_failure_mode row,
fixture_shape_diverges_from_the_producer_shape, bounded againstexecuted_conjunct_discriminates_nothing(there the RED was never authored; here the fixtureEXISTS and is what hides the defect) and against the sibling
v2.lens.effect_reachdisjunctiondefect at adhoc-f0508f41-ae9, which presents identically and is repaired in the check rather
than in the producer.
NOT REGENERATED HERE: docs/design-failure-modes.md. Resolve refuses on this tree for reasons
that predate this change --
absence_classifier_default_bucketandgreen_reported_over_a_population_the_instrument_does_not_ownare each declared twice ingunbc.recurring_failure_modeon main, plus unresolvedPlan/NonEmptyStrtypes underdag/gunbc -- so no projection can be produced from this authority until gunbc#10278 lands. The
.dag authority carries the row; the projection is a generated artifact and heals downstream.
🤖 Generated with Claude Code
https://claude.ai/code/session_011vmMNtRoPfgkR75q8feHYg