Files
sx/docs/fork-c/S0.2-e6b-disposition-and-two-corpus-partition.md
agra ca8bc85120 docs(fork-c/S0): correct two doc-accuracy lines (base-equivalence wording + grounded FFI count)
attempt-2 review fixes (docs-only; contract mechanics confirmed sound):
- README + S0.2 grep-clean: 'S0 HEAD == base' / 'S0 == base' were inaccurate
  (HEAD carries the docs/examples/tests diff). Reword to: production/compiler
  behavior is base-equivalent — zero src/ changes, single-author output
  byte-identical to base by construction — HEAD is a distinct commit, not base.
- S0.3 ledger: drop the stale '116-class corpus' FFI wording for the grounded
  live count (96 entry trees / 95 active markers), matching the S0.1 count note.

No partition / manifest / examples / harness change. Gate green:
zig build + zig build test (LSP sweep 574, no crash) + run_examples (540/0);
m3te ios-sim build via main binary exit 0.
2026-06-09 10:47:42 +03:00

8.0 KiB
Raw Permalink Blame History

S0.2 — E6b disposition, the two-corpus partition, and the E6BR-5 re-file

Authority: runs/stdlib/design/fork-c-plan/planspec-r3.json (S0.2) + runs/stdlib/design/fork-c-deepdive/reconciled.md (§3 one-resolver-two-timings, §6 roadmap, §8 fold-in). Base: wt-stdlib-base @ 1f75528 (AE6a merged). E6b: flow/stdlib/E6b @ af737b0 (PAUSED, unmerged). This is documentation only — no production code change.

1. E6b transitional src is NOT merged

The transitional E6b source on flow/stdlib/E6b @ af737b0 is not brought onto the Fork C baseline. All of it is destined for S3/S6 deletion under Fork C:

  • the route-all engine + the type-reference choke-point (resolveRegistrationSigTypeInSource / sig_registration_mode) — lower.zig, protocols.zig;
  • the executable grep gate src/ir/e6br_gate.test.zig (+ its ir.zig import);
  • the supporting calls / lower / protocols / type_bridge / type_resolver / types changes.

Grounded reasons it is transitional, not load-bearing: the whole-AST resolver walks every reference position, so it closes the protocol/param-impl signature surface the choke-point policed (reconciled §3/§4 T4); and the grep gate is unnecessary once the leaf it polices no longer exists (reconciled §5). AE6a stays merged purely as proof-of-semantics + per-decl nominal infra (internNominal / nominal_id==0 byte-identity rule / RawDeclRef facts → the DeclId seed) — see S0.3-reuse-delete-ledger.md.

Grep-clean (verified on this branch — src/ is base-equivalent, zero src changes):

check base / S0 E6b
resolveRegistrationSigTypeInSource in src/ absent present (lower.zig)
sig_registration_mode in src/ absent present (lower.zig, protocols.zig)
src/ir/e6br_gate.test.zig absent present
walkConcreteSigArgs in src/ir/lower.zig absent present (the E6BR-5 site)

Because S0 introduces no production code change, these remain absent on the Fork C baseline by construction.

2. Harvested resolver-acceptance corpus + the two-corpus partition

Harvested by copying the example trees + their expected goldens ONLY (never the transitional src):

  • examples/08110829 (19 trees) from flow/stdlib/E6b @ af737b0 — error-set / protocol / param-impl / route-all same-name ambiguity & own-wins surfaces;
  • examples/07950798 (already merged on the base) — the enum/union ambiguous/own-wins pair.

The corpus is partitioned by empirically running each harvested case through the current base compiler and comparing its output to the E6b TARGET golden (the exact method: build, then sx run examples/<name>.sx, normalize with the run_examples.sh rules, diff against the E6b golden):

(a) BASELINE-GREEN — the mirror-equivalence corpus

Harvested cases whose old selector is already CORRECT on wt-stdlib-base today (actual == E6b target, byte-for-byte). They get standard examples/expected/<name>.{exit,stdout,stderr} markers, are run by tests/run_examples.sh, and are locked into the S0 baseline. This set is the S2 assert-only Debug mirror's ONLY oracle.

case exit proof it is already-correct on base
0795-modules-same-name-enum-ambiguous 1 already merged + green (E6a)
0796-modules-same-name-enum-own-wins 0 already merged + green
0797-modules-same-name-union-ambiguous 1 already merged + green
0798-modules-same-name-union-own-wins 0 already merged + green
0823-route-all-own-wins-subform-wrappers 0 base output == E6b target (opt=1 arr=2 sl=3 dep=99)
0828-protocols-param-impl-arg-wrapped-own-wins 0 base output == E6b target (tag=7 dep=9)

(b) RESOLVER-TARGET — known-wrong old behavior

Harvested cases (and the re-filed E6BR-5) where the old selector is wrong on the E6b-unmerged base (silently resolves last-wins / under-diagnoses / picks the wrong author / fails own-author resolution). They are held in a documented, listed, separate harness at tests/resolver-target/ with NO active examples/expected/ marker (so run_examples.sh does not run them), but WITH their TARGET output recorded and an enumerated manifest (tests/resolver-target/manifest.md, 18 cases). The sibling xfail runner run_resolver_target.sh runs each and asserts it currently FAILS — so the set is never silently dropped. It flips to active + green at S3.9.

The 17 harvested 08xx resolver-target cases: 0811, 0812, 0813, 0814, 0815, 0816, 0817, 0818, 0819, 0820, 0821, 0822, 0824, 0825, 0826, 0827, 0829. Per-case class, base-now behavior, and target are in the manifest.

0811 and 0829 placement (required one-liners):

  • 0811 → resolver-target. Old selector is wrong here on the E6b-unmerged base: the five bare error-set forms (size_of / annotation / type-as-value / match-arm / !IoErr channel) each silently resolved one global last-wins IoErr via the type_bridge.resolveInlineErrorSet findByName short-circuit and the program exited 0; the target is five loud "type 'IoErr' is ambiguous" diagnostics + exit 1.
  • 0829 → resolver-target. Old selector is wrong here on the E6b-unmerged base: the concrete *Box prefix of the mixed pack-closure source fell to the no-author type_bridge.resolveTemplateSignatureType wrapper (global last-wins) and registered silently (exit 0); the target is a loud Box ambiguity + exit 1.

3. E6BR-5 re-filed into resolver-target

E6BR-5 (the open nested-pattern ambiguity hole that paused E6b) is re-filed into the resolver-target set as a regression — explicitly NOT an E6b attempt-6.

  • What it is: walkConcreteSigArgs (E6b lower.zig:14686) skips any direct arg that has an unbound part instead of recursing into it, so a nested concrete leaf (*Box inside Closure(Closure(*Box, ..$inner) -> $IR, ..$args) -> $R) is never ambiguity-checked; the impl compiled rc=0. On wt-stdlib-base (E6BR-4 unmerged) both the direct and nested concrete leaf silently resolve via the pre-E6BR-4 no-author wrapper path, so the reproducer exits 0 with no diagnostic.
  • Subsumption (one line): the whole-AST resolver walks every reference position — including nested parameterized-pattern leaves — so the nested Box is ambiguity-checked by construction and the "skip a nested arg" hole cannot exist.
  • Form: an authored reproducer lives at tests/resolver-target/cases/e6br5-nested-pack-source-ambiguous.sx (self-contained; verified to exit 0 silently on the base — the fail-before). Its target is a spec (exit 1 + Box ambiguous), with exact bytes produced by the resolver at S3.9 (expected/e6br5-…target.md).

4. The mirror / flip statement (locked)

  • S2's mirror asserts resolver == old-selector over the BASELINE-GREEN corpus ONLY. It never asserts new == old over the resolver-target corpus (the old selector is a wrong oracle there), and it never selects for lowering (assert-only, Debug-only, deleted in the S3.10 commit that completes the cutover).
  • S3.9 flips the resolver-target corpus to active + green, validated against each case's TARGET output (not against the old selectors). After the flip, the goldens move from tests/resolver-target/expected/ to examples/expected/, the harness goes empty, and these cases stay green through S6.

5. Acceptance (S0.2) — self-check

  • Written disposition: E6b transitional src not merged (§1, grep-clean table).
  • Harvested corpus recorded + partitioned: baseline-green (markers, locked, mirror-equivalence) vs resolver-target (enumerated manifest, separate listed harness, no active marker, TARGET goldens present, currently xfail, never dropped) — §2.
  • 0811 and 0829 each in resolver-target with the "old selector is wrong on the E6b-unmerged base" one-liner — §2.
  • E6BR-5 re-filed into resolver-target with the subsumption one-liner, NOT an E6b attempt-6 — §3.
  • Mirror/flip statement recorded — §4.
  • No transitional E6b src on the Fork C baseline (grep-clean) — §1.