From be0a36362bd84cbf885bc95a64c70ad6d6725834 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 23 Aug 2026 03:28:13 +0000 Subject: [PATCH 1/2] Refuse per-code board shares for emitter roots --- .../rc-ownership-wrap-decision-design.md | 2 + docs/probes/e0308_classify_sites.py | 7 +- docs/probes/e0308_partition_2026-08-22.md | 87 ++++++++++--------- .../summary_stamp.md | 59 ++++++------- .../r1_reference_layer_producer_2026-08-23.md | 73 ++++++++++++++++ 5 files changed, 156 insertions(+), 72 deletions(-) create mode 100644 docs/probes/r1_reference_layer_producer_2026-08-23.md diff --git a/docs/plans/rc-ownership-wrap-decision-design.md b/docs/plans/rc-ownership-wrap-decision-design.md index 4384c996ad3..6d542e8fa50 100644 --- a/docs/plans/rc-ownership-wrap-decision-design.md +++ b/docs/plans/rc-ownership-wrap-decision-design.md @@ -23,6 +23,8 @@ Band A flip policy (`frontier_band_a_emit_readiness.dag`) already blocks `parse_ The paragraph above says the fail-open is that the emitter *wraps every `shared_types` member*. Measured against a real emitted corpus that is **not what happens**, and the difference decides what a fix may be. This section records the correction, the located root, the two facts a fix has to respect, and what was built in consequence. +**2026-08-23 reporting correction:** per-code partitions are projections, not mechanism membership: one mechanism can surface under several rustc codes, while M=1 closure boards overlap and the published receipts span different revisions. They therefore supply vocabulary and located observations but no board shares, ranking, or completion census. The population-independent producer trace is [`r1_reference_layer_producer_2026-08-23.md`](../probes/r1_reference_layer_producer_2026-08-23.md); cross-code membership is owned by the cross-code classifier and is not re-derived here. + ### What was measured, by whom, and on which emitter smart-ibex-716 built an emitted-crate census at `M=11` compiler-module entries (`05_emit`, `06_translate`, `04_infer`, `03_ingest`, `emit_host`, `01_tokenize`, `materialization_carriers`, `emit_module`, `03_normalize`, `program_partition`, `05_eval`; head `5e1a73fa33`), using the `docs/probes/curated_cargo_probe_one.sh` invocation contract with `cargo check --message-format=json` so the expected/found pair comes from the span label rather than a text grep. **55** E0308 `Rc` mismatches survive dedup to distinct `(file, line, column, code, signature)`: **28 under-wrapped** (`expected Rc, found T`) and **27 over-wrapped**. **54** of those appear in the `03_ingest` closure, the one tree kept on disk, and **53 of those 54 sit at call-argument position** (1 record literal, 0 signatures). The three totals are three denominators, not an arithmetic error, and one site (`v2_compiler_parse.rs:582:12`) carries **both** signs, so 55 diagnostics do not mean 55 distinct positions. diff --git a/docs/probes/e0308_classify_sites.py b/docs/probes/e0308_classify_sites.py index 8d97630dc29..cea8f74d374 100755 --- a/docs/probes/e0308_classify_sites.py +++ b/docs/probes/e0308_classify_sites.py @@ -369,10 +369,13 @@ def main(path, out): ["file", "line", "col", "expected", "found", "delta", "root", "reason", "carrier_flags", "callee", "callee_kind", "msg"]) + "\n") print("raw E0308 blocks: %d" % len(blocks)) - print("canonical sites : %d" % len(sites)) + print("mismatch projections: %d" % len(sites)) hist = collections.Counter(s["root"] for s in sites) + # Counts only. This classifier sees one error code in one overlapping M=1 closure at one + # revision. A percentage would mistake this code-local projection for a closed mechanism + # population and make it look comparable with another code, closure, or revision. for r, n in hist.most_common(): - print(" %-12s %4d %5.1f%%" % (r, n, 100.0 * n / len(sites))) + print(" %-12s %4d" % (r, n)) flagged = collections.Counter(s["carrier_flags"] for s in sites if s.get("carrier_flags")) if flagged: print("\nCarrier flags (evidence beside the root, not a category):") diff --git a/docs/probes/e0308_partition_2026-08-22.md b/docs/probes/e0308_partition_2026-08-22.md index 2f89adb701b..1b818afb1c3 100644 --- a/docs/probes/e0308_partition_2026-08-22.md +++ b/docs/probes/e0308_partition_2026-08-22.md @@ -1,4 +1,4 @@ -# E0308 repartitioned on current main — 128 raw blocks / 154 canonical sites / 13 clusters + 6 residue (2026-08-22) +# E0308 repartitioned on current main — 128 raw blocks / 154 mismatch projections / 13 clusters + 6 residue (2026-08-22) **Session:** `eager-lark-892`. **Work item:** `node://adhoc-7a94657d-f17`. **Assignment (`smart-ram-730`):** re-derive raw rows → canonical sites → mechanism roots against the @@ -27,7 +27,7 @@ which are reused here as a vocabulary. | classifier | [`e0308_classify_sites.py`](e0308_classify_sites.py), committed, run over the raw log below | | raw log | [`e0308_partition_2026-08-22/03_ingest.cargo.log`](e0308_partition_2026-08-22/03_ingest.cargo.log) — published so this population can be **re-partitioned without a rebuild** | -Board this run reproduces in full, so the E0308 share is readable beside its denominator: +Raw diagnostic histogram reproduced by this run (counts only; see the share refusal below): ``` E0308:128 E0425:24 E0277:23 E0599:22 E0004:21 E0609:18 E0560:17 E0061:17 @@ -36,17 +36,16 @@ E0533:1 E0223:1 uncoded_unsupported_mock_expression:13 uncoded_UNRESOLVED_ CARGO_ERROR_TOTAL=329 HISTOGRAM_SUM=330 ``` -E0308 = **128 / 315 coded rows = 40.6%** (329 is cargo's own error total, a different instrument; -the two are published together and never differenced — see the probe's `WHY 10 AND 11` note). +E0308 has **128 raw blocks**. The 315 coded rows are a different grain and are retained only as an +instrument receipt; no mechanism share is derived from them. -**Corrected 2026-08-22 from 316 / 40.5%.** This clause read 316, which disagreed with the +**Corrected 2026-08-22 from 316 coded rows.** This clause read 316, which disagreed with the `315-board` row in this document's own series table below and with the published raw log, whose per-code histogram sums to 315. The slip was in the subtraction, not the measurement: `HISTOGRAM_SUM=330` counts `^error(\[E[0-9]+\])?:` lines and therefore includes cargo's trailing `could not compile … due to 329 previous errors` line, so the summary line must be removed before -the 14 uncoded rows — 330 − 1 − 14 = 315, agreeing with `CARGO_ERROR_TOTAL=329` = 315 + 14. Only -this one percentage is denominated in coded rows; every other percentage in this document is -denominated in the 154 canonical sites and is unchanged. Full derivation: +the 14 uncoded rows — 330 − 1 − 14 = 315, agreeing with `CARGO_ERROR_TOTAL=329` = 315 + 14. No +percentage is derived from either grain. Full derivation: [`summary_stamp.md`](e0308_partition_2026-08-22/summary_stamp.md). ### The brief's board did not reproduce, and the cause is now known: it was a different tree @@ -54,7 +53,7 @@ denominated in the 154 canonical sites and is unchanged. Full derivation: The brief stated 315 rustc errors with E0308 = **182** on this exact sha. At that sha, with the prior partition's exact producer and contract, this run measures 315 coded rows with E0308 = **128**. The totals agree exactly — the "within one row" this clause previously reported was the -316 slip corrected above, not a real difference — and the E0308 share did not. Two corroborations said the +316 slip corrected above, not a real difference — and the E0308 count did not. Two corroborations said the instrument here was not simply wrong: the brief reported **T2 now zero** and **T3 currently 14**, and this run independently measured T2 = 0 and T3 = 14. @@ -71,16 +70,16 @@ continues: | 339-board | `629252b6df` | 135 | | 315-board | `967b5bc1b9` | **128** ← this run | -The 182 and every claim derived from it are **withdrawn by their author** — including "E0308 is -58% of the board", "nothing else is above 15%", and the accompanying histogram (E0599 41, E0277 +The 182 and every share or ranking derived from it are **withdrawn by their author**, along with +the accompanying histogram (E0599 41, E0277 38, E0004 31, E0597 27, E0425 23, E0609 19, E0560 17, E0061 17), all of which are 465-era. **The 182 is used nowhere in this document and nothing here is differenced against it**; it is recorded only because the brief that commissioned this run carried it as framing. -## Raw rows → canonical sites +## Raw rows → mismatch projections - **128** — raw `error[E0308]` blocks (what the probe histogram counts). -- **154** — canonical mismatch sites. +- **154** — expected/found mismatch projections. These are not a durable site-identity authority. Blocks < sites because one `arguments to this function are incorrect` block carries one `expected …, found …` per wrong argument. Two collapses run the other way and both are *unit* @@ -100,29 +99,41 @@ its expectation. ## The partition — 14 clusters + a live residue arm, summing to 154 +### Share refusal — these counts are vocabulary, not a ranking + +No percentage over this table is sound. This receipt observes one error code in one overlapping +M=1 closure at one revision. A mechanism crosses rustc codes: the independently measured +absent-`Clone`-bound mechanism appears in `E0308`, `E0277`, and `E0599`, so its `E0308` rows are a +projection of that mechanism, not its membership. The surrounding measurements also carry +different units and refs: coded diagnostic rows are not mismatch projections, and the published +partitions were not taken from one tree. Counts remain useful as observations and mechanism +vocabulary. They may not be added, differenced, ranked, or reported as board shares. Cross-code +population membership belongs to the single cross-code classifier; this receipt does not mint a +competing denominator. + **REPARTITIONED 2026-08-22 after a keying defect was found by review** (`royal-dove-436`, `smart-ram-730`); the counts below are the corrected ones and the superseded table is not kept beside them, because two tables for one measurement is two authorities. What changed and why is in *The keying ruling* immediately after. -| cluster | sites | % | files | top pair (n) | -|---|---:|---:|---:|---| -| **R1** bare↔`Rc` wrap decision | 34 | 22.1% | 18 | `Rc \| LetBinding` (4) | -| **R2** Optional surface fork | 24 | 15.6% | 8 | `Option> \| Rc<_>` (8) | -| **D** alias arity / generic argument count | 16 | 10.4% | 2 | `Coverage> \| CoverageDefectAcceptanceKey` (13) | -| **T3** collection carrier fork | 14 | 9.1% | 10 | `OrdSet \| Rc>` (5) | -| **A-clone** generic parameter `Clone` bound absent | 12 | 7.8% | 6 | `_ \| &_` (6) | -| **ARG-ORDER** call argument order | 11 | 7.1% | 1 | (no pair; rustc's own reorder help) (6) | -| **B3** modeled `Nat` vs native integer | 10 | 6.5% | 1 | `Rc \| {integer}` (10) | -| **RESIDUE** unclassified | 7 | 4.5% | 5 | printed in full below | -| **C** carrier collapses to `()` | 6 | 3.9% | 3 | `Rc \| ()` (2) | -| **B2** `Bool` carrier vs `bool`/variant | 6 | 3.9% | 1 | `Bool \| True` (3) | -| **ELEM-COLL** element vs its own collection — **NEW** | 5 | 3.2% | 2 | `StateDurabilityBoundary \| Vector>` (2) | -| **W** `Witness<_>` type argument | 5 | 3.2% | 2 | `Witness> \| Witness>` (2) | -| **DIAG** diagnostic carrier fork | 3 | 1.9% | 1 | `Rc \| Rc` (3) | -| **BOX-WRAP** `Box` wrap decision — **NEW** | 1 | 0.6% | 1 | `i64 \| Box` (1) | - -Classified = 147 / 154 = **95.5%**; residue = **7 sites, 4.5%**. The stop rule is met on both arms. +| cluster | projections | files | top pair (n) | +|---|---:|---:|---| +| **R1** bare↔`Rc` wrap decision | 34 | 18 | `Rc \| LetBinding` (4) | +| **R2** Optional surface fork | 24 | 8 | `Option> \| Rc<_>` (8) | +| **D** alias arity / generic argument count | 16 | 2 | `Coverage> \| CoverageDefectAcceptanceKey` (13) | +| **T3** collection carrier fork | 14 | 10 | `OrdSet \| Rc>` (5) | +| **A-clone** generic parameter `Clone` bound absent | 12 | 6 | `_ \| &_` (6) | +| **ARG-ORDER** call argument order | 11 | 1 | (no pair; rustc's own reorder help) (6) | +| **B3** modeled `Nat` vs native integer | 10 | 1 | `Rc \| {integer}` (10) | +| **RESIDUE** unclassified | 7 | 5 | printed in full below | +| **C** carrier collapses to `()` | 6 | 3 | `Rc \| ()` (2) | +| **B2** `Bool` carrier vs `bool`/variant | 6 | 1 | `Bool \| True` (3) | +| **ELEM-COLL** element vs its own collection — **NEW** | 5 | 2 | `StateDurabilityBoundary \| Vector>` (2) | +| **W** `Witness<_>` type argument | 5 | 2 | `Witness> \| Witness>` (2) | +| **DIAG** diagnostic carrier fork | 3 | 1 | `Rc \| Rc` (3) | +| **BOX-WRAP** `Box` wrap decision — **NEW** | 1 | 1 | `i64 \| Box` (1) | + +Classified = **147 projections**; residue = **7 projections**. The stop rule is met on both arms. R1's depth split is now **four delta values, published as four rather than rolled up into two**: `rc_depth` 17 (outer), `generic_arg` 10 (type-argument depth), `generic_arg+container` 5 (element @@ -302,16 +313,14 @@ width of one file. | `src/v2_extdeps_languages_dag.rs` | 6 | R2 6 | | `src/std_realization_schedule.rs` | 5 | D 3, R1 2 | -45 emitted files carry the 154 sites. **Four clusters are single-file** (ARG-ORDER, B3, B2, -BOX-WRAP) and two more sit in two files each (D, ELEM-COLL), which is the strongest cost-shape -signal in this run: 49 of 154 sites sit behind six decisions in eight files. +45 emitted files carry the 154 projections. File concentration is recorded as an observation, not +as a cost ranking: a code-local projection is not a mechanism's closed membership. -## Cost shape — the staffing question the brief asked +## Former cost ranking — refused -The board is **not** a long tail of independent site repairs. Four clusters (R1, R2, D, T3) cover -88 of 154 = 57%, and six near-single-file clusters cover another 49. The tail is 7 residue sites in -5 files. This agrees in shape with the 2026-08-21 finding (7 largest categories = 79%) even though -the population is different. +The former percentage ranking is withdrawn. The table below preserves the code-local observations +and routing suggestions, but it cannot size or order root lanes. Cross-code membership is required +before any mechanism's completion or relative size can be stated. | cluster | sites | suggested owner | why that owner | |---|---:|---|---| diff --git a/docs/probes/e0308_partition_2026-08-22/summary_stamp.md b/docs/probes/e0308_partition_2026-08-22/summary_stamp.md index 3c15ed6a6d0..e68037e87f7 100644 --- a/docs/probes/e0308_partition_2026-08-22/summary_stamp.md +++ b/docs/probes/e0308_partition_2026-08-22/summary_stamp.md @@ -4,7 +4,7 @@ ``` VISIBLE CANARY coded rustc rows: 315 | subject: 03_ingest closure (M=1) | ref: 967b5bc1b92 - canonical E0308 sites: 154 + E0308 mismatch projections: 154 DIAGNOSTIC COVERAGE standing: PARTIAL known censor LexMatchThunk.apply / generic-instantiation failure (E0599 aborts before inference reaches the expressions behind it) @@ -22,13 +22,13 @@ censor is removed the board will RISE, and that is diagnostic completion, not re | entry | `src/v2/compiler/03_ingest.dag` (M=1) | | producer | `curated_cargo_probe_one+emit+seedlink+cargo`, `CSSL_STD_SEED_LINK=1`, shim `""` | | emitted roster | 177 files, 503 emit diagnostics (same roster count as the 2026-08-21 run — same subject) | -| raw E0308 blocks | **128** (40.6% of **315** coded rows; `CARGO_ERROR_TOTAL=329`, `HISTOGRAM_SUM=330`) | -| canonical sites | **154** | +| raw E0308 blocks | **128** (`CARGO_ERROR_TOTAL=329`, `HISTOGRAM_SUM=330`; different grains, no share) | +| mismatch projections | **154** | | clusters | 14 + residue | -| unclassified residue | **7 (4.5%)**, printed in full; residue arm known-positive | +| unclassified residue | **7**, printed in full; residue arm known-positive | | classifier | `docs/probes/e0308_classify_sites.py` (committed; re-runnable over the published raw log) | -### Coded-row count corrected 316 → 315 (2026-08-22), and one derived percentage moved +### Coded-row count corrected 316 → 315 (2026-08-22) The stamp and the receipt both reported **316** coded rustc rows. The published raw log yields **315**, which is also what this board's own name in the receipt's series table already said @@ -43,35 +43,33 @@ So 330 = 329 real error blocks + 1 summary line. Subtracting only the 14 uncoded to 315 independently (`grep -o '^error\[E[0-9]*\]' | sort | uniq -c`), so the two agree. `CARGO_ERROR_TOTAL=329` = 315 coded + 14 uncoded is the third agreeing reading. -**Derived percentages that moved:** exactly one. The E0308 share of the coded board is -128 / 315 = **40.6%**, not 128 / 316 = 40.5%. Every other percentage in this stamp and in the -receipt is denominated in the **154 canonical sites**, not in coded rows, so no cluster share, the -95.5% classified figure, or the 4.5% residue figure changes. The 128, the 154, the cluster counts, -the histogram and every disposition are unaffected — this was a denominator arithmetic slip, not a -measurement error. +No percentage is derived. Raw blocks, coded rows, and mismatch projections are different units, +and this code-local M=1 closure is not the membership of any mechanism that crosses rustc codes. +The 128, the 154, the cluster counts, the histogram and every disposition are unaffected — this +was a denominator arithmetic slip, not a measurement error. -## Clusters (site grain, this subject only) — every one a CANDIDATE root +## Clusters (projection grain, this subject only) — every one a CANDIDATE root Repartitioned 2026-08-22 after a keying defect found by review; R1's four delta values are published as four, because a two-bucket rollup erases the element arm and element depth is a separate producer root; precedence between delta-keyed, carrier-keyed and context-keyed arms is now declared in the classifier and in the receipt's *keying ruling*, not left to source order. -| cluster | sites | % | -|---|---:|---:| -| R1 bare↔`Rc` wrap (17 outer / 10 type-argument / 5 element / 2 outer-of-container) | 34 | 22.1% | -| R2 Optional surface fork | 24 | 15.6% | -| D alias arity / generic argument count | 16 | 10.4% | -| T3 collection carrier fork | 14 | 9.1% | -| A-clone generic `Clone` bound absent | 12 | 7.8% | -| ARG-ORDER call argument order | 11 | 7.1% | -| B3 modeled `Nat` vs native integer | 10 | 6.5% | -| RESIDUE | 7 | 4.5% | -| C carrier collapses to `()` | 6 | 3.9% | -| B2 `Bool` vs `bool`/variant | 6 | 3.9% | -| ELEM-COLL element vs its own collection (**NEW**) | 5 | 3.2% | -| W `Witness<_>` type argument | 5 | 3.2% | -| DIAG diagnostic carrier fork | 3 | 1.9% | -| BOX-WRAP `Box` wrap decision (**NEW**) | 1 | 0.6% | +| cluster | projections | +|---|---:| +| R1 bare↔`Rc` wrap (17 outer / 10 type-argument / 5 element / 2 outer-of-container) | 34 | +| R2 Optional surface fork | 24 | +| D alias arity / generic argument count | 16 | +| T3 collection carrier fork | 14 | +| A-clone generic `Clone` bound absent | 12 | +| ARG-ORDER call argument order | 11 | +| B3 modeled `Nat` vs native integer | 10 | +| RESIDUE | 7 | +| C carrier collapses to `()` | 6 | +| B2 `Bool` vs `bool`/variant | 6 | +| ELEM-COLL element vs its own collection (**NEW**) | 5 | +| W `Witness<_>` type argument | 5 | +| DIAG diagnostic carrier fork | 3 | +| BOX-WRAP `Box` wrap decision (**NEW**) | 1 | ## Carrier flags (beside the root, not a category) @@ -94,9 +92,8 @@ the mismatch and no pair-keyed rule can recover it. ## Cost shape -Four clusters cover 57% of sites; six more are single- or two-file and cover another 49. Tail = 7 -residue sites in 5 files. This is a small number of producer decisions with wide fanout, not a site-by-site -tail — the same shape the 2026-08-21 board reported on a different population. +This code-local projection supplies mechanism vocabulary, not a population or ranking. Cross-code +membership is required before any root's completion or relative size can be stated. ## The 182 in the commissioning brief diff --git a/docs/probes/r1_reference_layer_producer_2026-08-23.md b/docs/probes/r1_reference_layer_producer_2026-08-23.md new file mode 100644 index 00000000000..1f64ebaadf5 --- /dev/null +++ b/docs/probes/r1_reference_layer_producer_2026-08-23.md @@ -0,0 +1,73 @@ +# R1 reference-layer producer trace (population-independent) + +This is a producer trace, not a population census. It does not inherit the `E0308` partition's +R1 count, create a second classifier, or claim completion. A reference-layer mechanism can surface +under several rustc codes, and the cross-code classifier owns its membership. Symbols below are +the durable identities; generated Rust positions are deliberately not used as authority. + +## Membership authority + +The v1 Rust emitter builds one bare-name set in `v1.compiler.emit_rust` `build_shared_types`. +`maybe_mark_shared_type` admits a `TypeSummary` when the Rust target needs sharing and the summary +is a non-unit struct/coproduct that is neither a grounded native coproduct alias nor a type +constant. `build_shared_types` also admits target collection-template names. This answers one +question at type grain: whether a declared carrier belongs to the seed emitter's shared set. + +That set is not an absolute identity authority. Its key is `TypeSummary.name: String`, and +`rust_carrier_is_at_shared_layer` projects a resolved node through +`rust_fn_sig_leaf_name`/`qualified_last_segment` back to that bare leaf before membership lookup. +Two declarations with the same leaf therefore cannot carry different sharing facts. The source +already records this ceiling in `rust_carrier_is_at_shared_layer` and correctly calls the result +mitigatable, not structural. + +## The projections are not one producer + +Outer, generic-argument, and element-depth `Rc` differences must not be presumed to share a root. +The current emitter has several consumers of the bare-name membership, and they apply the layer at +different recursion points: + +- `rust_carrier_is_at_shared_layer` is the carrier-level projection. Its current consumers include + `rust_field_carrier_final_type`, `analyze_rc_match`, and + `value_inferred_type_is_rc_wrapped`. This consolidated four former local opinions, including the + struct-field and value-position forks, but remains a Bool projection over the bare-name set. +- `render_rust_shared_type_if_needed` is a rendered-text idempotence projection. It asks membership + by a supplied name and separately asks `rust_type_is_rc_wrapped` whether the already-rendered + string begins at the target's shared layer. `render_rust_applied_type`, alias-RHS rendering, and + several specialized renderers call it directly. This is where an outer layer can be applied + after a path-specific rendering decision. +- Recursive type rendering decides nested positions independently. `render_rust_applied_type` + maps arguments through `render_rust_applied_type_arg`; alias RHS rendering recurses through + `render_rust_alias_rhs_type`; generic `render_node_type` recurses over collection elements and + generic children while recomputing `set_contains(shared_types, tn)` at each node. Element and + generic-argument differences can therefore originate below the outer carrier even when the + outer projection agrees. +- `emit_data_def` still computes `needs_rc` from + `set_contains(shared_types, authored_name_at(type_node))` and then uses rendered-text prefix + detection before wrapping its return type. This bypasses the carrier-level projection and is a + distinct writable opinion. + +Therefore the answer is neither “one producer at three depths” nor “three roots” yet. There is one +membership set, multiple projections of it, and recursive render paths that can consult membership +again below the outer carrier. A cross-code identity join must attribute observations to these +symbolic producer paths before any root lane can be sized. + +## Already-consolidated boundary and remaining ceiling + +`rust_carrier_is_at_shared_layer` is real convergence work: field declarations, variant record +fields (through `rust_field_carrier_final_type`), match scrutinees, and selected value positions now +ask one carrier question. It must not be described as though the old field-only +`authored_name_at` miss were still the whole mechanism. + +The class remains writable because direct `set_contains(shared_types, ...)` and rendered-text +prefix checks survive on other paths. Copying the Bool predicate into every recursive renderer +would add validations to the seed and preserve the bare-name authority. The declared next rung is +the modeled `TargetReferenceLayer` plus `target_layer_transition` in +`v2.std.compilers.target_model`, consumed by `v2.compiler.wrap_decision`. That model is not +reachable from the v1 seed closure today; moving it to a root both compilers can consume is a +model-first carrier migration, not an edit justified by this probe. + +## Reporting rule + +This trace reports symbols and producer relationships only. It reports no board share, no root +rank, and no completion count. The code-local partition remains a historical projection; the +cross-code classifier supplies membership, and only that membership can define a closing census. From 8e89d6f1b6c82fb51d440403715db500ee7a40b6 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 23 Aug 2026 05:25:17 +0000 Subject: [PATCH 2/2] Audit shared-types membership authority consumers --- .../r1_reference_layer_producer_2026-08-23.md | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/docs/probes/r1_reference_layer_producer_2026-08-23.md b/docs/probes/r1_reference_layer_producer_2026-08-23.md index 1f64ebaadf5..50418ce8e81 100644 --- a/docs/probes/r1_reference_layer_producer_2026-08-23.md +++ b/docs/probes/r1_reference_layer_producer_2026-08-23.md @@ -1,17 +1,29 @@ -# R1 reference-layer producer trace (population-independent) +# `shared_types` membership-authority audit (R1 producer trace, population-independent) This is a producer trace, not a population census. It does not inherit the `E0308` partition's R1 count, create a second classifier, or claim completion. A reference-layer mechanism can surface under several rustc codes, and the cross-code classifier owns its membership. Symbols below are the durable identities; generated Rust positions are deliberately not used as authority. -## Membership authority +## What fact does `shared_types` represent? The v1 Rust emitter builds one bare-name set in `v1.compiler.emit_rust` `build_shared_types`. `maybe_mark_shared_type` admits a `TypeSummary` when the Rust target needs sharing and the summary is a non-unit struct/coproduct that is neither a grounded native coproduct alias nor a type -constant. `build_shared_types` also admits target collection-template names. This answers one -question at type grain: whether a declared carrier belongs to the seed emitter's shared set. +constant. `build_shared_types` also admits target collection-template names. The closest faithful +reading of the constructed set is: + +> For the selected target, this bare declared name is predicted from its source representation +> shape to need the target's shared indirection realization. + +That sentence exposes the fusion. The producer starts from a **declaration fact** (`TypeSummary` +shape, recursive/type-constant exclusions), applies a **target realization policy** +(`sharing_for_target(target).needs_sharing` plus target collection-template rows), and stores only a +bare `String`. It does not retain the declaration identity from which the prediction came, the +target realization identity selected, the layer (`Rc`, `Box`, or owned), or the use-site position. +It is therefore not a general fact named “this type is shared.” It is a lossy, target-specific +Boolean projection whose name and carrier make it available as though it answered all of those +questions. That set is not an absolute identity authority. Its key is `TypeSummary.name: String`, and `rust_carrier_is_at_shared_layer` projects a resolved node through @@ -20,6 +32,31 @@ Two declarations with the same leaf therefore cannot carry different sharing fac already records this ceiling in `rust_carrier_is_at_shared_layer` and correctly calls the result mitigatable, not structural. +## Consumer audit — three different information needs + +The direct readers partition by what their decision actually requires. Passing `Set` to +all three groups hides this distinction; it does not make their questions the same. + +| required fact | symbolic consumers | why the present set is insufficient or excessive | +|---|---|---| +| **Declaration identity** | `render_node_type`; `render_rust_decl_type`; `render_rust_alias_rhs_type`; `emit_rust_expr_record_lit`; `emit_typed_record_lit`; `emit_field_value_with_context` | These resolve a type/constructor or recurse into its arguments. A bare leaf cannot distinguish equal spellings declared by different modules, and the correct layer must follow the resolved declaration through every nested position. They need a declaration-keyed lookup; the Boolean is a projection after that join. | +| **Realization identity** | `rust_render_checkpoint_scalar_bare`; `render_rust_shared_type_if_needed`; `needs_box_wrapping`; `v1_emit_struct_derives`; `v1_emit_struct_from_capability_table` | These decide Rust representation: native scalar vs structural carrier, `Rc` vs already-indirect/recursive `Box`, and heap-capable vs copy-capable derive surfaces. “Member” does not say which realization was selected or whether indirection is already supplied. The rendered-string prefix guard is evidence that realization identity was discarded and reconstructed from bytes. | +| **Boolean projection only** | `rust_carrier_is_at_shared_layer` consumers (`rust_field_carrier_final_type`, `analyze_rc_match`, `value_inferred_type_is_rc_wrapped`); `analyze_rc_pattern`; `variant_ref_self_wraps`; `emit_typed_expr_base`; `emit_discriminant_call_scrutinee_lowering`; `emit_typed_call`/`emit_rust_with_method_call`; `emit_rust_fold_method_call`; `emit_data_def` | Once declaration and realization have already been resolved, these only choose a local lowering: wrap a constructor, dereference/clone a value, suppress a second `Box`, or select an Rc-aware pattern. They should consume a total projection such as “this resolved value is at shared indirection,” not the membership set or a rendered spelling. Several currently redo the bare-name lookup themselves, so they can disagree even though their required output is only Bool. | + +Two qualifications keep the table honest. First, `needs_box_wrapping` consumes realization identity +to establish *which* indirection satisfies sizedness, even though its immediate return is Bool; +classifying every Bool-returning function as “Boolean only” would confuse output shape with input +grain. Second, trait derivation does not ask whether a use site should be wrapped. It asks which +Rust capabilities the realized declaration supports. Its use of the same membership set is direct +evidence that `shared_types` is serving more than the R1 wrap question. + +The audit result is therefore: **one set is answering at least three questions**. Declaration +identity is required to locate the subject, realization identity is required to derive the target +representation, and only then may use-site consumers safely read a Boolean layer projection. The +minimum information flow is not a wider `Set` and not three replacement rosters: resolve a +declaration-keyed realization fact, then derive total projections for the narrower consumers. This +is a requirement exposed by the audit, not a promoted root or an authorization to mint that carrier. + ## The projections are not one producer Outer, generic-argument, and element-depth `Rc` differences must not be presumed to share a root. @@ -46,7 +83,8 @@ different recursion points: detection before wrapping its return type. This bypasses the carrier-level projection and is a distinct writable opinion. -Therefore the answer is neither “one producer at three depths” nor “three roots” yet. There is one +Therefore the answer is neither “one producer at three depths” nor “three roots” yet. R1 is one +symptom family produced by multiple consumers of insufficient identity information. There is one membership set, multiple projections of it, and recursive render paths that can consult membership again below the outer carrier. A cross-code identity join must attribute observations to these symbolic producer paths before any root lane can be sized. @@ -66,6 +104,10 @@ the modeled `TargetReferenceLayer` plus `target_layer_transition` in reachable from the v1 seed closure today; moving it to a root both compilers can consume is a model-first carrier migration, not an edit justified by this probe. +This audit does not itself prove that carrier is the root. Per the promotion order, it is the +producer trace between classification and intervention: a single-axis change followed by an exact +site-conversion receipt is still required before any manifestation is promoted to a root. + ## Reporting rule This trace reports symbols and producer relationships only. It reports no board share, no root