fieldtest close: canonical-type-names — route findings + roadmap update

Per-iter journal entry for the fieldtest run plus INDEX pointer.
Roadmap absorbs four actionable findings as P2/P3 todos (split the
merged BadCrossModuleTypeRef diagnostic, workspace subdir search,
`ail check` on `.ailx` extension, `.ailx` counterpart for the
canonical happy-path JSON exhibit). The two carry-on items
(`(import prelude)` doc-gap, the working ones) stay as notes in the
fieldtest spec only. P0 Floats milestone removed — closed
2026-05-10 and no longer load-bearing context.

No bug findings, so no debug dispatch. canonical-type-names is fully
shipped.
This commit is contained in:
2026-05-11 12:17:21 +02:00
parent 45dca692dd
commit 94d8016da1
3 changed files with 116 additions and 14 deletions
@@ -0,0 +1,75 @@
# fieldtest — canonical-type-names
**Date:** 2026-05-11
**Branch:** main (orchestrator-direct dispatch; the or.1 branch-per-iter rule lands on the *next* implement run)
**Status:** DONE_WITH_CONCERNS
**Examples:** 5 of 5 authored + committed
**Findings:** 9 (4 working, 4 friction, 1 spec_gap, 0 bugs)
## Summary
Standard skill-pipeline step after audit cleanly closed
canonical-type-names. The fieldtester wrote five `.ailx` examples
that exercise the milestone surface — one happy-path exhibit and
four diagnostic-triggers, one per new diagnostic plus a second
branch of the merged BadCrossModuleTypeRef case. Spec at
`docs/specs/2026-05-11-fieldtest-canonical-type-names.md`; fixtures
under `examples/ct_*`.
All four milestone-scoped findings landed as **working**: the new
diagnostics fire on the LLM-natural authoring mistakes, the
diagnostics carry actionable recipes (BareCrossModuleTypeRef lists
import candidates + names the migration tool), and Form-A
round-tripping stays byte-stable across cross-module type refs.
One milestone-internal friction: `BadCrossModuleTypeRef` collapses
two distinguishable cases (unknown owner vs. known owner / unknown
type name) into one diagnostic shape. A future tidy iter can split
these and, in the known-owner branch, list the available type names
the way `bare-cross-module-type-ref` lists candidates from imports.
Three orthogonal friction items surfaced as pre-existing UX gaps
that every fieldtest invocation will keep tripping on:
- Workspace search confined to the entry module's directory — no
way to organise fieldtest fixtures under
`examples/fieldtest/` while still importing prelude or std.
- `ail check foo.ailx` returns a misleading JSON-parse error
instead of either auto-parsing `.ailx` or pointing to `ail parse`.
- `(import prelude)` is rejected with a clear diagnostic but no
corpus example warns the author that prelude is auto-injected.
One spec_gap: the canonical happy-path exhibit shipped with this
milestone (`examples/compare_primitives_smoke.ail.json`) exists
only as JSON. Decision 6 makes Surface the LLM-author surface; the
milestone should ship a `.ailx` counterpart (or retire the JSON
fixture in favour of `ct_1_ordering_signum.{ailx,ail.json}`).
## Routing
| Finding | Class | Action |
|---|---|---|
| BareCrossModuleTypeRef recipe + JSON ctx | working | carry-on |
| BadCrossModuleTypeRef catches Surface | working | carry-on |
| QualifiedClassName fires on `(class prelude.Eq)` | working | carry-on |
| Form-A round-trip byte-stable | working | carry-on |
| BadCrossModuleTypeRef merges two cases | friction | roadmap P2 |
| Workspace search confined to entry dir | friction | roadmap P2 |
| `ail check` on `.ailx` misleading | friction | roadmap P2 |
| `(import prelude)` corpus doc gap | friction | carry-on (one-line DESIGN.md hint sufficient) |
| No `.ailx` for `compare_primitives_smoke.ail.json` | spec_gap | roadmap P3 |
No bug findings, so no debug dispatch. The five `.ailx` fixtures
stay in the corpus as live exhibits.
## Lesson — orthogonal UX gaps surface together
Three of four friction items are orthogonal to canonical-type-names
proper. They predate the milestone. None would have surfaced in a
brainstorm or planner pass because none touches the milestone's
substance. Fieldtest's role IS to surface this kind of cross-cutting
UX debt — DESIGN.md does not mention `.ailx` extension handling,
workspace-root flags, or the prelude doc-gap, but every downstream
LLM author trips on them within ten minutes of writing their first
program. The roadmap entries below are the persistent backlog this
fieldtest produced.
+1
View File
@@ -6,3 +6,4 @@
- pre-2026-05-11 — see `../journal-archive.md` for all prior history
- 2026-05-11 — iter or.1: orchestrator-refactor → 2026-05-11-iter-or.1.md
- 2026-05-11 — fieldtest canonical-type-names → 2026-05-11-fieldtest-canonical-type-names.md
+40 -14
View File
@@ -35,20 +35,9 @@ work progresses.
## P0 — In flight
- [x] **\[milestone\]** Floats — introduce `Float` as IEEE-754
binary64 primitive type. One float type only (no `f32`).
IEEE-conformant equality: `eq : Float → Float → Bool` returns
`false` for `NaN == NaN`; **no `Eq` instance** (the partiality
is real and surfaces through `Maybe`-shaped comparators rather
than through a lying total instance). `Ord` likewise partial:
`compare : Float → Float → Maybe Ordering`. Includes literal
syntax in Form-A + Surface, codegen for arithmetic ops,
conversions Int↔Float, and `Show`-style printing without the
typeclass machinery (the typeclass wiring lands in Post-22
Prelude).
- context: this conversation (2026-05-10) — Float status quo
was "documented as a primitive but never implemented";
`crates/ailang-core/src/canonical.rs:14` says "no floats".
_(empty — canonical-type-names milestone closed 2026-05-11; Floats
closed 2026-05-10 and was removed once it stopped being load-bearing
context. Pick the next milestone from P1.)_
## P1 — Next
@@ -156,6 +145,34 @@ work progresses.
block, or extract JSON-schema blocks into a machine-readable
file the test consumes.
- context: JOURNAL 2026-05-10 ("Audit close").
- [ ] **\[todo\]** Split `BadCrossModuleTypeRef` into two diagnostics —
the current single shape collapses unknown-owner and
known-owner / unknown-type-in-owner into one message. The two
cases suggest different fixes (add `(import <owner>)` vs. fix the
type name). In the known-owner branch, list the owner's available
type defs as candidates the way `bare-cross-module-type-ref`
lists candidates from imports.
- context: fieldtest 2026-05-11 — `examples/ct_3*.ailx` exhibits both branches with identical-shape diagnostics.
- [ ] **\[todo\]** Workspace search beyond entry-module's directory —
`load_workspace` only finds sibling `.ail.json` files in the same
directory as the entry module, so any consumer of prelude/std in a
subdirectory has no way to resolve cross-module imports. Add either
a `--workspace-root` flag on `ail check` / `ail build` / `ail run`,
or upward-search from the entry module's directory. Alternatively
ratify the flat-workspace assumption in DESIGN.md if intentional.
- context: fieldtest 2026-05-11 — fieldtest fixtures could not be
placed under `examples/fieldtest/` because of this; predates the
canonical-type-names milestone but surfaces every time.
- [ ] **\[todo\]** `ail check`/`build`/`run` accept `.ailx` extension —
today `ail check foo.ailx` produces a misleading JSON-parse error
(`json: expected value at line 1 column 1`) because the loader only
accepts `.ail.json`. Either teach the CLI subcommands to auto-parse
`.ailx` internally, or detect the extension and emit a
"did you mean `ail parse foo.ailx`?" hint. The LLM-author's natural
first command should not be the one that produces a misleading
diagnostic.
- context: fieldtest 2026-05-11 — orthogonal to canonical-type-names
but every fieldtest invocation hits this on its first command.
- [ ] **\[todo\]** `check_in_workspace` per-module overlay narrowing —
`crates/ailang-check/src/lib.rs:1234` still clears+rebuilds
`env.ctor_index` per-module; ct.3.2 narrowed the analogous mono
@@ -169,6 +186,15 @@ work progresses.
## P3 — Ideas
- [ ] **\[todo\]** `compare_primitives_smoke.ailx` counterpart —
the canonical happy-path exhibit for canonical-type-names ships
only as JSON. Per Decision 6, Surface is the LLM-author surface;
the milestone should have a `.ailx` counterpart. Two paths: author
`examples/compare_primitives_smoke.ailx` to round-trip into the
existing JSON, OR retire the JSON fixture in favour of
`examples/ct_1_ordering_signum.{ailx,ail.json}` as the new canonical
happy-path exhibit.
- context: fieldtest 2026-05-11 (spec_gap).
- [ ] **\[todo\]** Codegen `lookup_ctor_in_pattern` type-anchoring —
`crates/ailang-codegen/src/lib.rs:1790` still walks every module's
ctor_index by bare ctor name. Plumbing the scrutinee's