Skip to content

Make Rust emitter deterministic: correct variant owner-selection + sort import keys - #5879

Merged
briansrls merged 14 commits into
mainfrom
session/stern-fox-585
Jun 28, 2026
Merged

briansrls merged 14 commits into
mainfrom
session/stern-fox-585

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jun 27, 2026 •

Copy link
Copy Markdown
Contributor

What

Three non-determinism/correctness sources in the v1 Rust emitter, all fixed:

  1. `variant_to_enum` HashMap owner-selection (`v1_compiler_infer.rs`): `variant_fold` iterated `env.bindings` (HashMap) without sorting, so the first-processed enum for a shared variant name varied per-process. Fixed by alpha-sorting `env.bindings` values before folding, and selecting the correct owner using `imported_variants` (built from the source module's locally-defined items, not the full transitive `type_env.bindings`).

  2. `map_keys` on exported HashMap (`v1_compiler_emit_rust.rs`): three call-sites (`reexport_parents`, `wildcard_import_pool_surface_names`, `wildcard_reexport_surface_names`) iterated `HashMap::keys()` non-deterministically, producing non-deterministic USE statement ordering. Fixed by sorting each key-vec before iteration.

  3. `find_struct_name_by_fields` record disambiguation (`v1_compiler_emit_rust.rs`): when multiple struct types share the same field names (e.g. `AnthropicModelSpec` and `OpenAiModelSpec` both have `model, model_id, context_window, max_output_tokens`), the previous sort-by-name fallback was deterministic but semantically wrong — it always picked `AnthropicModelSpec` for both modules, emitting `AnthropicModelSpec { model: OpenAiModel::Gpt4o }` = invalid Rust. Fixed by building `field_type_hints` (field_name → inferred value type) at the call site and filtering candidates by type compatibility before falling back to alpha sort.

Why the correct-owner fix matters (DESIGN §7)

The `ApiKey` variant appears in two coproducts:

  • `AuthScope = None | FilesystemPerms | ApiKey | NetworkAcl` (defined in `std.cache_interface`)
  • `AuthScheme = Bearer | Header | Basic | ApiKey` (defined in `std.types`, transits in via `std.cache_interface`)

`buildbuddy.dag` imports `ApiKey` from `std.cache_interface`. The correct owner is `AuthScope`.
With alphabetical sort alone, `AuthScheme` (h < o) would win — emitting `AuthScheme::ApiKey` where `AuthScope` is expected = compile error. So determinism alone would have frozen a real §3 bug (deterministic-but-wrong).

The fix: `imported_variants` uses only locally-defined items of the source module (via `parent_tm.items`) to build the variant→unique-owner map. This ensures `AuthScope` wins because `AuthScheme` is not locally defined in `std.cache_interface` — only `AuthScope` is.

Residual: PosixSubject / FileOwnership

`PosixSubject { uid: Int, gid: Int }` and `FileOwnership { uid: Int, gid: Int }` are distinct named Rust types with identical field names and identical field types — full-signature matching cannot distinguish them, so alpha sort applies. This is latent-safe (corpus builds green, no current construction site forces one into a field typed as the other), NOT structurally-impossible. If such a site appeared — e.g. a field typed `PosixSubject` constructed with a `FileOwnership` literal — it would be a live compile error, same trap as `AnthropicModelSpec/OpenAiModelSpec`. Precise §5 framing: wall-after-grounding, not never. The two types are a §3 nicknaming candidate for a future de-collision.

.dag authority follow-up (known, not fixed here)

This fix lives in the hand-maintained v1 Rust seed (`v1_compiler_infer.rs`, `v1_compiler_emit_rust.rs`) because `regen --verify` is deferred and the stage0 is hand-synced (see `regen_verify_gate.dag`). When regen un-defers (§7 fixed-point dissolution / v2 self-host), the same determinism + correct-owner-selection + field-type-disambiguation logic must be ported to the `.dag` emitter model or it will regress on regen. Tied to the §7 fixed-point trigger.

Oracle results (run locally on HEAD 12ff922)

Double-emit (609 dsl modules, 616 files): diff -r emit1 emit2 → EMPTY (deterministic)

Semantic correctness checks:

  • `extdeps_llm_anthropic.rs`: only `AnthropicModelSpec` constructors ✓
  • `extdeps_llm_openai.rs`: only `OpenAiModelSpec` constructors ✓
  • `extdeps_cache_buildbuddy.rs`: `AuthScope::ApiKey` ✓
  • `extdeps_cache_github_actions.rs`: `AuthScope::ApiKey` ✓

Discriminating witness

`variant_owner_disambiguation_test::shared_variant_resolves_to_locally_defined_owner_not_transitive` — verifies that `ZLocalOwner::SharedV` is emitted (not `ATransitiveOwner::SharedV`). Designed so the wrong owner sorts alphabetically first; confirmed RED on revert.

briansrls and others added 9 commits June 27, 2026 20:04
variant_fold in build_module_context iterated env.bindings (HashMap<i64,TypeBinding>)
via map_values(), producing non-deterministic ordering. When multiple coproducts share
a variant, the first-processed wins; HashMap iteration order varies per process, so 37
files diffed between two runs of the same corpus. Sort bindings by binding.name before
folding so the alphabetically-first type name always wins — stable across runs.

Also removes debug eprintln! instrumentation added during diagnosis (v1_compiler_emit_rust.rs
effective_variant_parent and v1_compiler_infer_emit_info.rs derive_variant_to_enum).

Oracle: two corpus emits produce empty diff.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rt emit imports

- v1_compiler_infer.rs: replace dead imported_enum_names (per-binding) with
  imported_variants (per-child) disambiguation. Looks up variant→parent enum in
  the SOURCE module (parent_index), not the current module's transitive env.
  ApiKey in std.cache_interface is unambiguously AuthScope (not AuthScheme
  which transits in from std.types). writeThenCommit is ambiguous (both
  AtomicityModel and CacheWriteSemantics define it) → falls back to alpha sort.
  Sort is kept for determinism on ambiguous cases.

- v1_compiler_emit_rust.rs: sort map_keys outputs at 3 export_sets call sites
  (wildcard_reexport_surface_names, wildcard_import_pool_surface_names,
  reexport_parents) to make pub use ordering deterministic.

Residue (noted): WriteThenCommit owner-selection is correct-by-alpha-accident
(AtomicityModel < CacheWriteSemantics alphabetically, which is the intended
field type). This is a latent §3 collision; the imported_variants map returns
None for it (ambiguous in source module) and alpha tie-break happens to win.
@gunbai-bot gunbai-bot Bot changed the title Make the Rust emitter deterministic (variant_to_enum HashMap owner-selection) — restore DESIGN section 7 bit-identical fixed point Make Rust emitter deterministic: correct variant owner-selection + sort import keys Jun 27, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review June 27, 2026 22:00
briansrls and others added 4 commits June 27, 2026 22:15
1. find_struct_name_by_fields (emit_rust.rs): candidates Vec came from
   HashMap iteration (map_values), making .first() non-deterministic when
   multiple record types share the same field names. Sort candidates by name
   before selecting first. This fixes emit alternating between AnthropicModelSpec
   vs OpenAiModelSpec (same field names, different model-field types) and
   PosixSubject vs FileOwnership (identical field sets uid/gid).

2. interp_string_family_cast_test (test update): #5818 removed the hollow
   Url=String alias from std.types (§3 violation). Update the Rust unit test
   to match string_family_cast_witness_test.dag — remove the Url import and
   string_to_url fn; Uri is a struct and does not participate in the
   string-cast family.

Oracle after all fixes: double-emit of 609 dsl modules → EMPTY diff.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…iple struct candidates share the same field names

AnthropicModelSpec and OpenAiModelSpec have identical field names but different field types (model: AnthropicModel vs model: OpenAiModel). The previous sort-by-name fix was deterministic but wrong — it always picked AnthropicModelSpec for both modules, emitting invalid Rust (wrong constructor name). Now passes field_type_hints (field_name → inferred value type) from the call site; the function filters candidates by type compatibility before falling back to alpha sort.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jun 27, 2026
…v1-survivable) (#5880)

Author the operator-funded follow-on to the acute floor-OOM fix (#5867 shared
InternTable: whole-tree resolve 14.2 -> 5.5 GiB, 61% reclaimed). This lane is
REPRESENTATION minimization at the root (distinct from the ALLOCATION lane,
resource-aware-scheduler.md), repointing the orphaned tidy-wren-707 lane.

Operator steer: minimal representation, attack root causes as much as we can,
v1 is going away. Every item is gated on one discriminator -- does the fix live
in the .dag authority (survives the v2 self-host) or is it a hand-edit to the
doomed v1 Rust seed (dies with v1). Root-first sequencing:

  1. Emitter determinism is THE GATE for Lever B -- points at PR #5879
     (stern-fox-585) as the single authority for the gate's status/mechanism;
     this plan only sequences on it.
  2. Lever C (stream/evict) -- biggest mover, no emitter dependency; one
     batching-and-eviction model shared with the prune-resolve/affected_set lane.
  3. Lever B (variant-Node minimal representation) -- after the gate, modeled in
     std/ and emitted (so it regenerates, not hand-edited into the seed).
  4. func_env.sigs single-authority -- resolve each sig once, share the Rc;
     hundreds-of-MiB (payloads already Rc-shared, established by code read).
  5. Cheap v1-seed hygiene -- bank-if-cheap, NOT a pillar (dies with v1);
     Node.ident is NOT dead (execution-refuted a 0%-used reflection claim).

Plumbing: registered in plan_registry_batch_g (code-graph inbound link);
ROADMAP link line (doc-graph inbound link, one short line); docs/plans md is a
generated projection (regenerated via main_wet, drift-gated). Gates verified
green by execution: no-orphan-docs, no-dangling-links, plan dissolution+title.

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor Author

Corroborating baseline non-determinism witness from #5884 lane.

While verifying a separate PR (#5884, func_env.sigs dedup), I ran the unmodified origin/main gunbc binary 3 times over the same 619-file dsl corpus and diffed all 3 pairs. Union S = 50 files that ever differed across those 3 runs — independent confirmation of the same families this PR fixes:

  • ProviderKeyEncoding ↔ CatalogProviderKeyEncoding
  • AuthScheme::ApiKey ↔ AuthScope::ApiKey (your buildbuddy/sccache witness)
  • OpenAiModelSpec ↔ AnthropicModelSpec
  • CacheWriteSemantics ↔ AtomicityModel
  • pub use line-ordering

This is an independent repro from a different binary build, different PR context, same 50-file non-deterministic universe. The variant families match yours exactly. May help as additional evidence for reviewers.

@briansrls
briansrls merged commit f1d806a into main Jun 28, 2026
2 checks passed
@briansrls
briansrls deleted the session/stern-fox-585 branch June 28, 2026 00:54
briansrls added a commit that referenced this pull request Jun 28, 2026
Tests 2+3 previously imported both AEarlyEnum and ZLaterEnum from a
separate owner module. Since they share a variant, the pre-existing
imported-both guard (curr_is_imported && prev_is_imported) fires a
VariantCollision diagnostic, which would block the regen path.

Fix: collapse each two-module scenario into a single module with locally-
defined enums and no imports. imported_enum_names is empty → no collision
possible. Discrimination is preserved via variant_locals_from_items
last-write-wins: ZLaterEnum defined first, AEarlyEnum second → AEarlyEnum
wins scope; the function return type (ZLaterEnum) triggers the expected-
type override on the site that needs it.

Verified: removing expected_type_override_enum → tests 2+3 go red
(AEarlyEnum::SharedVarField emitted for make_late); restoring → green.
Test 1 (local-vs-transitive, #5879 fix) unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jun 28, 2026
…uthority) (#5891)

* WIP: Variant-owner-by-expected-type §3 grounding (KEYSTONE, correctness wall)

* WIP: Variant-owner-by-expected-type §3 grounding (KEYSTONE, correctness wall)

* Ground variant owner by expected type at each site: fix + tests (#5891 prep)

- v1_compiler_infer.rs (ExprVar): when the scope binds a shared variant to
  enum A (by import-order or alpha-sort), but the declared expected type at
  the call site is a different enum B that also contains the variant, prefer
  B. Both binding_kind and inferred resolved-type are updated so the emit
  path sees a consistent owner without needing its own fallback.

- variant_owner_disambiguation_test.rs: two new §2 witnesses:
  · shared_variant_resolves_by_expected_type_not_alpha_order — AEarlyEnum
    and ZLaterEnum both define SharedVarAmbig; fn return type ZLaterEnum must
    emit ZLaterEnum::SharedVarAmbig not AEarlyEnum (alpha-first default).
  · shared_variant_resolves_per_site_independently — two functions in the
    same module with different declared return types each get the correct
    variant owner independently, proving the fix is per-site not per-module.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* WIP: Variant-owner-by-expected-type §3 grounding (KEYSTONE, correctness wall)

* Add .dag discriminating witness: expected_type_picks_variant_owner_not_alpha_order

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* WIP: Variant-owner-by-expected-type §3 grounding (KEYSTONE, correctness wall)

* Revert regen'd v1_compiler_infer.rs — restore hand-sync

The regen activates pre-existing VariantCollision logic in 04_infer.dag
(line 5815) that is a blocking diagnostic and breaks the corpus (e.g.
std.cache_interface defines both AtomicityModel and CacheWriteSemantics
sharing WriteThenCommit — regen fires VariantCollision there). This is a
known X/Y modeling decision being escalated; the hand-sync is correct and
faithful for the expected_type_override_enum grounding in this PR.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* WIP: Variant-owner-by-expected-type §3 grounding (KEYSTONE, correctness wall)

* Redesign Rust disambiguation tests to avoid VariantCollision on import

Tests 2+3 previously imported both AEarlyEnum and ZLaterEnum from a
separate owner module. Since they share a variant, the pre-existing
imported-both guard (curr_is_imported && prev_is_imported) fires a
VariantCollision diagnostic, which would block the regen path.

Fix: collapse each two-module scenario into a single module with locally-
defined enums and no imports. imported_enum_names is empty → no collision
possible. Discrimination is preserved via variant_locals_from_items
last-write-wins: ZLaterEnum defined first, AEarlyEnum second → AEarlyEnum
wins scope; the function return type (ZLaterEnum) triggers the expected-
type override on the site that needs it.

Verified: removing expected_type_override_enum → tests 2+3 go red
(AEarlyEnum::SharedVarField emitted for make_late); restoring → green.
Test 1 (local-vs-transitive, #5879 fix) unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Jun 28, 2026
* Restore emit-path variant-owner determinism lost in #5873 regen (#5879 grounding)

Port #5879's variant-owner disambiguation back into .dag authority and hand-sync
the v1 Rust seed: imported_variants (source-module local items), alpha-sorted
variant_fold bindings, sorted export-set map_keys, and field-type-hint struct
disambiguation. Regen in #5873 overwrote these fixes; this re-lands them on
current main (#5899) without disturbing expected_type_override_enum (#5891).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix #5899 func_sigs merge regression in variant-owner restore

Re-land imported_variants + sorted variant_fold on top of #5899's
func_sigs/all_declared_sigs path (not the reverted imported_sigs fork).
Restores compile-clean hand-sync; variant_owner_disambiguation 3/3 green.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Ground emit-path variant-owner determinism in .dag authority with pure regen.

Fix imported_variants map type so regen emits valid Rust (Map<String,String>
for unambiguous owners only), then regen stage0 to match .dag fixed point.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request Jun 28, 2026
…x deepening.

The arena/u32-index analysis is a deepening of Lever B (same lever: bytes-per-node;
same gate: #5879), not a separate plan. Single-authority in representation_minimization.dag.

- Lever B item in sequencing ol() updated to name two sub-moves: (i) minimal
  per-kind sum type [existing] + (ii) arena/index container [new], both gated on
  #5879, both landing in v2/.dag realization.
- Added two-paired-axes note: Lever B attacks BYTES-PER-NODE; Lever C attacks
  MODULES-HELD-AT-ONCE; orthogonal, compose multiplicatively, neither blocks the other.
- Added "Lever B (item 3) — arena/index deepening" section with: verified Node anatomy
  (size_of=144 B, Rc-wrapped 160 B/node, 12 pointer fields) reconciled with the
  existing 18-field/627k-nodes framing; arena/u32-index insight (ACYCLIC DAG = Rc
  pays for unused cycle-safety; u32 arena index = 4 B vs 16 B Rc ctrl, halves 12
  ptr fields, ~40-55% node-graph cut); cheap recoverables (.dag-first, independent
  of emitter gate) with corrections: empty-Vec singleton win already landed (#5878),
  Node.ident is LIVE (u32-shrink fine, deletion refuted by execution).
- Reverted incorrectly-created arena_node_representation.dag (§3 fork) and registry
  entry.
- Regenerated docs/plans/representation-minimization.md via wet gate (drift-clean).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jun 28, 2026
The two-axes note incorrectly said both levers are gated on #5879; Lever C
explicitly has NO dependency on the emitter gate (sequencing item 2 and the
A3 disposition both state this). Corrected paragraph now precisely states:
Lever B gated on #5879; Lever C deferred to v2 streaming-infer, no emitter
gate. Regen'd representation-minimization.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jun 28, 2026
…rom .dag-path.

The 'independent of emitter gate / .dag-first' framing was contradictory: kernel-slice
sharing targets v1_compiler_infer.rs (doomed v1 seed, bank-if-cheap per plan's
discriminator); ident u32-shrink and SourceSpan file-id are Node/SourceSpan
representation changes whose .dag-authority path IS gated on #5879 like Lever B.

Per-item gating now stated explicitly:
- Empty-Vec singleton: already landed, remaining is bank-if-cheap v1-seed work
- Ident u32-shrink / file-id side table: .dag path gated on #5879; v1-seed is bank-if-cheap
- Kernel-slice sharing: v1-seed work, bank-if-cheap, NOT a root item
- Node.name interning: item 5 bank-if-cheap, unchanged

Decidability section corrected: sub-moves i/ii are RATCHETS gated on #5879;
ident/file-id are representation changes gated on #5879 on the .dag path;
kernel-slice is v1-seed bank-if-cheap (not WALL-NOW in .dag).
Regen'd representation-minimization.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jun 29, 2026
…pening (#5923)

* WIP: Write up arena/u32-index Node representation as a design note (plan proj

* Enrich Lever B in representation_minimization.dag with arena/u32-index deepening.

The arena/u32-index analysis is a deepening of Lever B (same lever: bytes-per-node;
same gate: #5879), not a separate plan. Single-authority in representation_minimization.dag.

- Lever B item in sequencing ol() updated to name two sub-moves: (i) minimal
  per-kind sum type [existing] + (ii) arena/index container [new], both gated on
  #5879, both landing in v2/.dag realization.
- Added two-paired-axes note: Lever B attacks BYTES-PER-NODE; Lever C attacks
  MODULES-HELD-AT-ONCE; orthogonal, compose multiplicatively, neither blocks the other.
- Added "Lever B (item 3) — arena/index deepening" section with: verified Node anatomy
  (size_of=144 B, Rc-wrapped 160 B/node, 12 pointer fields) reconciled with the
  existing 18-field/627k-nodes framing; arena/u32-index insight (ACYCLIC DAG = Rc
  pays for unused cycle-safety; u32 arena index = 4 B vs 16 B Rc ctrl, halves 12
  ptr fields, ~40-55% node-graph cut); cheap recoverables (.dag-first, independent
  of emitter gate) with corrections: empty-Vec singleton win already landed (#5878),
  Node.ident is LIVE (u32-shrink fine, deletion refuted by execution).
- Reverted incorrectly-created arena_node_representation.dag (§3 fork) and registry
  entry.
- Regenerated docs/plans/representation-minimization.md via wet gate (drift-clean).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix gating contradiction: Lever C has no emitter-gate dependency.

The two-axes note incorrectly said both levers are gated on #5879; Lever C
explicitly has NO dependency on the emitter gate (sequencing item 2 and the
A3 disposition both state this). Corrected paragraph now precisely states:
Lever B gated on #5879; Lever C deferred to v2 streaming-infer, no emitter
gate. Regen'd representation-minimization.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix stale kernel-binding citations: infer.rs -> v1_compiler_infer.rs, line 13854->13998.

The live seed file is src/v1/stage0/src/v1_compiler_infer.rs, not infer.rs.
seed_kernel_intern_table is at line 13998 (not 13854 as cited).
kernel_bindings_base at 11695 and intern TABLE at 11641 are correct lines.
Regen'd representation-minimization.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* CI retry (OOM on srv1-01 in batch 2, runner-level flake)

* Rebucket cheap-recoverables: correct gating claim, separate v1-seed from .dag-path.

The 'independent of emitter gate / .dag-first' framing was contradictory: kernel-slice
sharing targets v1_compiler_infer.rs (doomed v1 seed, bank-if-cheap per plan's
discriminator); ident u32-shrink and SourceSpan file-id are Node/SourceSpan
representation changes whose .dag-authority path IS gated on #5879 like Lever B.

Per-item gating now stated explicitly:
- Empty-Vec singleton: already landed, remaining is bank-if-cheap v1-seed work
- Ident u32-shrink / file-id side table: .dag path gated on #5879; v1-seed is bank-if-cheap
- Kernel-slice sharing: v1-seed work, bank-if-cheap, NOT a root item
- Node.name interning: item 5 bank-if-cheap, unchanged

Decidability section corrected: sub-moves i/ii are RATCHETS gated on #5879;
ident/file-id are representation changes gated on #5879 on the .dag path;
kernel-slice is v1-seed bank-if-cheap (not WALL-NOW in .dag).
Regen'd representation-minimization.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Jun 29, 2026
Addresses claude-opus #33136 minor finding; scaffold eq/kind-bridge debt
unchanged (Disposition + non-fold roster + #5879 hold per sketch checkpoint).

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request Jun 29, 2026
… (model sketch FIRST; arena/u32 container is (ii), separate; lands in v2/.dag not the Rust seed; escalate on load-bearing Node/build_type_env) (#5936)

* WIP: Representation-min Lever B(i): minimal per-kind Node sum type in std/ (m

* WIP: Representation-min Lever B(i): minimal per-kind Node sum type in std/ (m

* WIP: Representation-min Lever B(i): minimal per-kind Node sum type in std/ (m

* Fix node_minimal witness tests: parse-safe dag and green execution.

Correct ResolvedGraph import in the Rust runner, fix dag syntax that blocked
resolve, and tighten witnesses so Lever B(i) compiles and runs green.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: add Lever B(i) per-kind Node sum type design sketch

Design-first review artifact for stern-moth-225: v2 authority confirmation,
variant split, NOT-edited boundary, witness checkpoint status, and explicit
exclusion of sub-move (ii) arena/u32 container.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix CI: cargo fmt for node_minimal test runner.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: Representation-min Lever B(i): minimal per-kind Node sum type in std/ (m

* Complete Lever B(i) superset field partition with coverage witness.

Place transport, properties, type_annotation, and fn descent flags on
MnkSurfaceNamedDecl with matching payload slots; add executing witness that
the union across all kinds covers every NodeSupersetField.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix CI: parse-safe orphan-field witness (nested if, not multiline &&).

Retriggers floor discovery on current HEAD; prior dashboard failure was at
83f843f before parse/fmt/partition fixes landed.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add executable three-bucket superset partition witness for Lever B(i).

Split fields into placed (12 on kind arms), owed_placement (3 staged arms),
and migrated_to_facts (3 to InferredFacts). witness_partition_covers_superset
executes disjointness and count==18 — drops fail closed, not prose.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix CI: doc-graph inbound link and non-fold residue roster for Lever B(i).

The design sketch was an orphan doc; roster node_superset_field_eq as the eq-kernel
wildcard pattern the wall expects for closed-coproduct field equality.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: Representation-min Lever B(i): minimal per-kind Node sum type in std/ (m

* Address review nits: derive superset field count, use unary negation.

Replace literal 18 with count(node_superset_field_all) as single authority
for NodeSupersetField arity; collapse if/else false/true to !any(...) per
review feedback (claude-opus APPROVE #33119).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add roster-length guard per stern-moth-225 emit-integration follow-on.

Rename node_superset_field_all → all_node_superset_fields; restore census
node_superset_field_count=18 as independent authority; witness roster length
and per-field partition coverage fold. Hold at sketch checkpoint.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Cosmetic: return Bool witnesses directly, not if/else true/false.

Addresses claude-opus #33136 minor finding; scaffold eq/kind-bridge debt
unchanged (Disposition + non-fold roster + #5879 hold per sketch checkpoint).

Co-authored-by: Cursor <cursoragent@cursor.com>

* CI: retrigger floor after 36568ea failure fixes landed on branch.

36568ea failed discovery corpus (doc_graph orphan + non_fold roster).
Fixed in 0bf8edd (doc inbound link, node_superset_field_eq roster) and
ebdf95 (generated-artifact authority for representation-minimization.md).
Local floor batches 1-2 green on HEAD.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Resolve representation_minimization merge conflict: keep both sketch links.

Merge #5935 func_env.sigs design-sketch link with PR #5936 Lever B(i)
node-minimal sketch link in the .dag authority; regen generated md via main_wet.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant