|
Important
|
This document is authoritative for issue #229: the post-#228 re-audit numbers,
the true RS-surface scope, the language-grounded canonical RS→AffineScript
map, the escalation set (constructs with no clean target), and the per-repo
port plan. It is the #229 analogue of the front-loaded ledger established by
#239 for the spine. Per-feature readiness remains
CAPABILITY-MATRIX.adoc; the coordination ledger
remains TECH-DEBT.adoc; the spine remains
ECOSYSTEM.adoc. Reproducer:
|
- What #229 is
- Post-#228 re-audit (authoritative)
- The honest scope correction
- Construct frequency (estate, excl. affinescript)
- The canonical RS→AffineScript map (language-grounded)
- Tier 1 — Mechanical (clean grammar target; scriptable, oracle-revalidated)
- Tier 2 — Semantic redesign (maps onto the affine model; per-case, NO blind codemod)
- Tier 3 — Escalate as a language-side issue/ADR (bidirectional evidence — the #228 discipline)
- Tier 4 — Cross-unit gating (a sequencing finding, language-grounded)
- Per-repo port plan
- #229 closure status (post-port truthing, 2026-05-19)
- Reproduce / see also
A subset of estate .affine files are unfinished ReScript→AffineScript
hand-ports: the file declares itself AffineScript (module …;) but the body
still carries ReScript surface syntax. Such a file is neither valid ReScript
nor valid AffineScript — debt in limbo that cannot be oracle-certified. The
committed goal is zero ReScript surface in any estate .affine. #229 was
blocked on #228 (ADR-014, module-qualified type/effect paths) because the
oracle stops at the first parse error: qualified-path faults masked each
file’s full RS inventory. #228 landed on main via #241 — this re-audit is
the now-unblocked step 2.
Oracle = affinescript main with #241/ADR-014 (parse-equivalent to the
int01-178-xmod build: zero lib/+bin/ delta vs origin/main). Same
cached estate corpus as the pre-#228 baseline (controlled: only the oracle
changed). Harness + raw data: tools/estate-rs-audit/.
| Class | n | Meaning |
|---|---|---|
|
552 |
parses + typechecks on the oracle |
|
491 |
first line is a parse/syntax error |
|
133 |
parses; fails later (resolution/type) — not a syntax port |
total |
1176 |
|
Zero class-delta vs the superseded #231 postfix — #241 reproduces ADR-014 parse behaviour exactly; #231 was superseded for implementation reasons, not behaviour. This table is now the post-#228 baseline of record.
|
Warning
|
|
| Repo | RS files | Shape |
|---|---|---|
|
32 |
Whole-repo RS port; richest construct mix (e.g.
|
|
28 |
Uniform |
|
4 |
|
|
4 |
|
|
3 |
|
|
3 |
|
|
3 |
|
|
3 |
|
|
1 |
|
|
1 |
|
|
1 |
|
total |
~83 |
over 11 repos (panll removed — see note) |
|
Warning
|
The text-scan inventory is a lower-bound triage signal, not the true
per-file inventory. The oracle stops at the first parse error, so a file’s
deeper RS layers are invisible until earlier ones are removed (e.g. the
|
standards 112, proof-burrower 98, developer-ecosystem 97, bofj-kitt
96, affinescript 84 (its own negative fixtures), airborne-submarine-squadron
13, accessibility-everywhere 13, idaptik 9, stapeln 6, burble 3,
singletons elsewhere. These DRIFT for non-ReScript reasons; they belong to
separate workstreams, not #229.
import-as 31 · mutable-field 29 · rs-generic<> 26 · array<T> 17 ·
%%raw 14 · labelled-(~x) 12 · List(X) 7 · JSON.t 7 · Dict.t 6 ·
rs-stdlib 4 · open-Mod 4 · type-rec 3.
Derived from the language side — grammar / spec v2.0 / stdlib — not guessed. Every target form carries its grounding citation. Four tiers.
| ReScript | AffineScript | Grounding |
|---|---|---|
expression-position record literal |
the
record sigil |
The dominant estate blocker — and NOT in 229’s
named construct set. |
ReScript string |
|
Concat is |
|
|
list type is |
lowercase |
|
The RS tell is the lowercase type
name, not the angle brackets. Oracle-verified: |
|
|
|
|
|
AS |
|
Note
|
The record-sigil row was discovered by oracle-peeling the four allegedly
"quick-win" |
| ReScript | Why it is not mechanical |
|---|---|
|
AffineScript is immutable-by-default with explicit
mutation via ownership ( |
|
No labelled/named-argument syntax in the grammar or
stdlib (stdlib is uniformly positional, e.g. |
|
ReScript stdlib; no 1:1 AffineScript target. Per-symbol remap to the estate stdlib, semantic. |
These have no clean AffineScript target today. Per #229 step 3 they are escalated language-side rather than patched divergently across N repos — the same discipline that produced #228.
| Esc | Construct | Finding |
|---|---|---|
ESC-01 (#245) — SETTLED by ADR-018 |
|
Doctrine: no
raw escape, by design. Typed |
ESC-02 (#246) |
|
No stdlib JSON type ( |
ESC-03 (#247) — LANDED |
|
|
import X as Y ports to use X as Y;. That parses and the alias registers
(lib/parser.mly:168 ImportSimple(path, Some alias);
lib/resolve.ml:787-797 registers the alias on lookup_qualified success).
But qualified-value call sites Y.fn(x) hit the post-#228 INT-01 #178
qualified-value resolution gap (lib/resolve.ml:719,797
UndefinedModule) — the exact gap recorded as the next spine unit.
⇒ idaptik-dlc-vm (28 files, 33% of #229 scope) is gated on the INT-01 #178
qualified-value resolver. burble (rs-generic/array/mutable/%%raw-dominated,
not module-coupled) and the three smallest non-coupled repos
(git-scripts, game-server-admin, invariant-path) are not gated and
proceed first. This does not reorder the mandate (#229 foundation first, as
instructed); it is the foundation’s own finding that the idaptik-dlc-vm
slice of the per-repo work naturally sequences after INT-01 #178.
Each repo: oracle-validate locally first (estate CI does not compile
.affine), one branch + squash-merge PR per repo, noreply author,
Refs #229 (multi-repo, sequenced, human-gated — never Closes). Per-repo
hands-off confirm before touching: policy hands-off is the ReScript
ecosystem (.res); .affine-with-RS is an in-scope unfinished port — but
confirm per repo it is an intended AffineScript target, not a deliberate
interop artefact (burble’s standing caveat), before removal.
-
Smallest non-coupled — DONE 2026-05-19:
git-scripts(PR 9),game-server-admin(PR #14),invariant-path(PR #4). One file each; layered:List(X)→[X]+ expr record literals{→{(patterns/decls left{ }) + ReScript string`→`+(the latter two oracle-peeled, not scanner-visible). Each oracle-validated "Type checking passed" onmain.panllexcluded (no listed RS construct — scanner FP; see the lower-bound-triage warning). -
See §#229 closure status for the truthed disposition of
burble, the small tail, andidaptik-dlc-vm.
Doing the ports collapsed the apparent scope. The honest end-state:
git-scripts 9 · game-server-admin #14 · invariant-path #4 ·
standards/session-management-standards/…/system_update_gui.affine #142.
Each oracle-validated "Type checking passed" on main. Transform:
List(X)→[X], expr record literals {→{, ReScript string `→`+,
ReScript import P [as A]→use P [as A];, single block-module
module P { body }→module P;-header-first + dedented body.
-
Structural Tier-1: ReScript
import P[.Q] [as A]→use P.Q [as A];(parser.mly:166-169); single block-modulemodule P { body }→module P;header (hoisted before imports —parser.mly:130-134requires the header first), braces dropped, body dedented one level. Oracle-verified to parse. -
ESC-04 (#262) — SETTLED by ADR-017: AffineScript is strictly one-module-per-file. Doctrine: split, do not nest — each ReScript
module X { body }(incl. each of N in a multi-block file likestandards/lol/…/OpenCyc.affine) becomes its ownX.affinewith amodule X;header. No grammar change (ADR-011 file=module; a block-module form is the ADR-012-forbidden contortion). Full validation still needs the per-repo module graph (INT-02, Tier-4).
-
developer-ecosystem,proof-burrower,bofj-kitt: every flagged file is a vendored copy of the affinescript repo itself (affinescript/stdlib/effects.affine,affinescript/tests/conformance/run_all.affine,…/docs/guides/warmup/02_ownership.affine); themutablehits are comments ("// State effect - mutable references", "// ── mut …"). Same discipline as the affinescript-own-corpus exclusion + thepanllFP. 0 real #229 files in these three repos. -
standards/a2ml/prototype/rescript/src/{A2ml,Json}.affine: inside arescript/ecosystem folder → policy hands-off (as.res), not a port target.
| Repo | n | Gate |
|---|---|---|
|
28 |
RS surface mechanically eliminated (block-module
+ import-as transforms verified to parse), but every file then hits
|
|
32 |
Tier-3 dominated: |
|
3 |
|
|
3 |
|
The remaining #229 work is now fully attributed to ESC-01..04 (#245/#246/#247/#262) + the INT-02 cross-module loader/layout concern — no unbounded "tail". This is the "once and for all" closure: completable done, false scope removed, residue precisely gated.
-
tools/estate-rs-audit/— harness + captured data + how-to. -
ECOSYSTEM.adoc — the spine; #229 is its estate-port arm.
-
TECH-DEBT.adoc — coordination ledger.
-
#228 / ADR-014 — the unblocker.