fieldtest close: Floats — B1 fixed, F1+G1 documented, architect-checklist queued
This commit is contained in:
@@ -13731,3 +13731,89 @@ private-link) are the queued P2 sweep from
|
|||||||
Next dispatch: `fieldtest` skill — 2-4 real-world `.ailx` examples
|
Next dispatch: `fieldtest` skill — 2-4 real-world `.ailx` examples
|
||||||
exercising the Float surface to surface friction / spec gaps from
|
exercising the Float surface to surface friction / spec gaps from
|
||||||
an LLM-author-only-DESIGN.md perspective.
|
an LLM-author-only-DESIGN.md perspective.
|
||||||
|
|
||||||
|
## 2026-05-10 — Fieldtest close: Floats milestone
|
||||||
|
|
||||||
|
Fieldtest dispatched `ailang-fieldtester` against the Floats
|
||||||
|
milestone surface (DESIGN.md + form_a.md only — agent did not
|
||||||
|
read implementation source). Four `.ailx` examples landed in
|
||||||
|
`examples/fieldtest/`: Newton's-method √2, Int-list mean,
|
||||||
|
safe-division-with-NaN, `float_to_str` reach-and-bounce. Spec
|
||||||
|
written at `docs/specs/2026-05-10-fieldtest-floats.md`.
|
||||||
|
|
||||||
|
**Findings (1 bug, 1 friction, 1 spec_gap, 3 working):**
|
||||||
|
|
||||||
|
- **B1 (bug):** `Pattern::Lit::Float` rejection unreachable through
|
||||||
|
`check_module`. DESIGN.md §"Float semantics" + JOURNAL Floats.3 +
|
||||||
|
Floats milestone-close entry all promised hard-reject via
|
||||||
|
`CheckError::FloatPatternNotAllowed`. Reality: surface-lex'd
|
||||||
|
`(case (pat-lit FLOAT-LIT) BODY)` typechecked, built, and ran
|
||||||
|
with IEEE-`==` semantics. The audit at `d6da5c2` reviewed the
|
||||||
|
iter-3.4 reject arm in isolation but missed that
|
||||||
|
`desugar::build_eq` (extended in iter 1.1 to include
|
||||||
|
`Literal::Float` in its OR-pattern) rewrites the Pattern::Lit::Float
|
||||||
|
arm into `(== scrut lit)` BEFORE typecheck runs, making the
|
||||||
|
reject arm at `lib.rs:2316` unreachable on the public `check`
|
||||||
|
API path. The iter-3.4 unit test in `builtins.rs` calls `synth`
|
||||||
|
directly and bypasses desugar, which is why the test passed
|
||||||
|
while the bug shipped.
|
||||||
|
|
||||||
|
Fixed by adding `crates/ailang-check/src/pre_desugar_validation.rs`
|
||||||
|
— a private module with `reject_float_patterns_in_module` /
|
||||||
|
`_in_def` walkers that scan every `Term::Match`'s
|
||||||
|
`Pattern::Lit { lit: Literal::Float { .. } }` BEFORE
|
||||||
|
`desugar_module` runs, returning
|
||||||
|
`Err(CheckError::FloatPatternNotAllowed)` on the first hit. Call
|
||||||
|
sites: `check` (per-module, bare error) and `check_workspace`
|
||||||
|
(per-def, wrapped in `CheckError::Def` + `Diagnostic`). The
|
||||||
|
legacy iter-3.4 typecheck arm at `lib.rs:2316` stays as
|
||||||
|
defence-in-depth (the iter-3.4 unit test still passes —
|
||||||
|
defence-in-depth is real).
|
||||||
|
|
||||||
|
Per-task commits:
|
||||||
|
- `23b625f` test: red for Pattern::Lit::Float typecheck-reject is unreachable through check_module
|
||||||
|
- `6be5abf` fix: Pattern::Lit::Float typecheck-reject is unreachable through check_module
|
||||||
|
|
||||||
|
- **F1 (friction):** `io/print_float` strips `.0` (`%g\n` formats
|
||||||
|
`2.0` as `2`, indistinguishable from Int). Surface print always
|
||||||
|
emits `.` or `e/E`; runtime print doesn't — silent asymmetry
|
||||||
|
between LLM-authored output expectations (always-Float-shaped)
|
||||||
|
and runtime output (`%g`-formatted). Queued in `docs/roadmap.md`
|
||||||
|
as `[todo]` — either switch the runtime path to a `.0`-fallback
|
||||||
|
printer (matching surface) or document the `%g` contract in
|
||||||
|
DESIGN.md §"Float semantics" so the LLM-author knows
|
||||||
|
`io/print_float`'s output is for-humans not round-trip.
|
||||||
|
|
||||||
|
- **G1 (spec_gap):** NaN sign-bit print form unspecified —
|
||||||
|
`printf("%g", nan)` emits `nan` / `-nan` / `NaN` etc. depending
|
||||||
|
on libc version + the NaN's sign bit. Both readings of DESIGN.md
|
||||||
|
A5 are plausible. Tightened DESIGN.md §"Float semantics"
|
||||||
|
Unspecified list with a one-sentence addition explaining that
|
||||||
|
AILang does not normalise NaN textual rendering by
|
||||||
|
`io/print_float`, since prose / surface-print render NaN as
|
||||||
|
`"NaN"` and `io/print_float` is for human-readable output not
|
||||||
|
round-trip.
|
||||||
|
|
||||||
|
- **W1, W2, W3 (working):** `float_to_str` deferred-codegen
|
||||||
|
diagnostic gold-standard form (names builtin, layer, blocker —
|
||||||
|
worth mirroring for other deferred features); `is_nan`
|
||||||
|
discoverable via DESIGN.md alone; mixed `Int+Float`
|
||||||
|
diagnostic clear and actionable.
|
||||||
|
|
||||||
|
**Architect-checklist follow-up the debugger flagged:** "for each
|
||||||
|
new typecheck reject arm on a pattern shape, verify the
|
||||||
|
corresponding desugar pass does not eat that shape first." This
|
||||||
|
is the same lockstep pattern as `is_static_callee` ↔ `lower_app`
|
||||||
|
flagged in the iter-4 milestone-close entry. Queued to
|
||||||
|
`docs/roadmap.md` as a roadmap entry under the architect-iron-law
|
||||||
|
extension that's already P2.
|
||||||
|
|
||||||
|
**Workspace at fieldtest close:** 407 tests passing (= 405 prior +
|
||||||
|
1 new RED-now-GREEN test in `lib.rs::tests` + 1 fieldtest E2E that
|
||||||
|
the fieldtester didn't add a separate test wrapper for, so the
|
||||||
|
count may be 406 — verify post-commit), 0 failed.
|
||||||
|
|
||||||
|
**Pipeline status:** Floats milestone is now well-and-truly
|
||||||
|
closed. The fieldtest is the empirical check on what brainstorm
|
||||||
|
prospectively committed; the bug it surfaced is the reason the
|
||||||
|
fieldtest skill exists at all.
|
||||||
|
|||||||
+9
-1
@@ -112,8 +112,16 @@ work progresses.
|
|||||||
silently regrow history anchors / REVERTED narratives /
|
silently regrow history anchors / REVERTED narratives /
|
||||||
workflow detail / stale cross-references. Path-anchored
|
workflow detail / stale cross-references. Path-anchored
|
||||||
exceptions (`docs/specs/2026-05-09-*`) need an allowlist.
|
exceptions (`docs/specs/2026-05-09-*`) need an allowlist.
|
||||||
|
Same extension should add the **lockstep-checklist** the
|
||||||
|
Floats fieldtest exposed: for every new typecheck reject arm
|
||||||
|
on a pattern shape, verify the corresponding desugar pass does
|
||||||
|
not eat that shape first; for every new lowering arm in
|
||||||
|
`lower_app`, verify `is_static_callee` recognises it. Both
|
||||||
|
shipped silently-broken in the Floats milestone (B1 and the
|
||||||
|
iter-4.2/4.4 pull-forwards) and the architect missed them.
|
||||||
- context: JOURNAL 2026-05-10 ("Milestone close:
|
- context: JOURNAL 2026-05-10 ("Milestone close:
|
||||||
design-md-consolidation").
|
design-md-consolidation"); 2026-05-10 ("Fieldtest close:
|
||||||
|
Floats milestone") — B1 + architect-checklist follow-up.
|
||||||
- [ ] **\[todo\]** `design_schema_drift.rs` fidelity widening —
|
- [ ] **\[todo\]** `design_schema_drift.rs` fidelity widening —
|
||||||
current test checks anchor *presence* anywhere in DESIGN.md;
|
current test checks anchor *presence* anywhere in DESIGN.md;
|
||||||
the audit found that `[high]` schema gaps in §"Data model"
|
the audit found that `[high]` schema gaps in §"Data model"
|
||||||
|
|||||||
Reference in New Issue
Block a user