Skip to content

#617 M3: teach the strict take-after-flatMap trap — limitations, prompt v0.16.6, footgun row, changelog - #675

Merged
sunholo-voight-kampff merged 2 commits into
devfrom
sprint/iter185-617-m3-teach
Aug 12, 2026
Merged

#617 M3: teach the strict take-after-flatMap trap — limitations, prompt v0.16.6, footgun row, changelog#675
sunholo-voight-kampff merged 2 commits into
devfrom
sprint/iter185-617-m3-teach

Conversation

@sunholo-voight-kampff

Copy link
Copy Markdown
Collaborator

M3 (TEACH) of m-take-flatmap-peak-memory / #617. M1 and M2 are already on dev. M4 is out of scope.

The fix built in v0.10.0 (d41e43894) and exposed by M1/M2 becomes discoverable — the missing step that is the whole reason #617 exists.

What landed

  • docs/docs/reference/limitations.md — canonical entry with the V1/V2 and V25/V26 tables, the corrected cost model (peak = source residency + largest single f(x) + n retained outputs), the --max-recursion-depth anti-pattern, and the bound-it-inside-f guidance.
  • docs/LIMITATIONS.md — summary row.
  • New prompt v0.16.6 in both prompts/ and cmd/ailang/prompts/, byte-identical, real sha256 recorded in both versions.json, active bumped in both. v0.16.2/v0.16.5 untouched, so pinned eval baselines still resolve byte-identical.
  • internal/diag/footguns.md — row 22 (inventoried), blind-spot column recording both known false negatives (value-level aliases V10; allocating-f take-map V25/V26). Header repointed off the frozen v0.16.2.
  • changelogs/v0.18-current.md — AC-3b release-evidence table, both pairs.

Per the plan's D-1 correction, which supersedes the design doc's AC-5: the doc names the frozen prompts/v0.16.2.md. Teaching into it would have left the shipped prompt at zero mentions — recreating #617's own shipped-but-unreachable failure one layer up.

Verification (controller, outside the executor sandbox)

  • AC-5: takeFlatMap and takeMap both ≥1 in all five files (baseline 0/0, same-path non-empty controls firing); active == v0.16.6 in both trees; recorded hash == file sha256 in both; cross-tree diff -q rc=0.
  • Reachability — the check take(n, flatMap(f, xs)) cannot bound memory under strict evaluation — a written-as-deliberate memory cap that never capped, and OOM'd the host twice #617 itself failed: the built binary's prompt --source=embedded actually serves the new teaching (takeFlatMap=1, takeMap=1) with the v0.16.5 control content intact (toInts=2), active resolving to v0.16.6.
  • The recorded hash is a real gate, not decoration: corrupting it (mutation asserted LANDED by sha256) reds TestAILANGPromptLoading and TestPromptDisambiguation with hash mismatch for "v0.16.6" — the right mechanism, not just a red exit code. Restored from a cp backup, byte-identical.
  • Gates: check-changelog, fmt-check, verify-examples (188 modules, 1 pre-existing missing-on-disk, unchanged), test-stdlib-ail, lint, and the AC-7 builtins arm all rc=0.

Evaluator (sonnet, distinct provider from the codex executor): PASS 91/100, zero blocking. It independently re-ran all five named targets and refuted none, reproducing all four memory arms itself. Its one real finding — the AC-3b table shipped only the takeFlatMap half — was reproduced against the plan text first-party and fixed in the second commit.

🤖 Generated with Claude Code

sunholo-voight-kampff and others added 2 commits August 12, 2026 15:53
…pt v0.16.6, footgun row, changelog

M3 of m-take-flatmap-peak-memory. The fix built in v0.10.0 (d41e438) and exposed by
M1/M2 becomes discoverable — the missing step that is the whole reason #617 exists.

- docs/docs/reference/limitations.md: canonical entry with the V1/V2 (425 MB/81.9s ->
  89 MB/0.06s) and V25/V26 tables, the corrected cost model (peak = source residency +
  largest single f(x) + n retained outputs), the --max-recursion-depth anti-pattern, and
  the bound-it-inside-f guidance.
- docs/LIMITATIONS.md: summary row.
- prompts/v0.16.6.md + cmd/ailang/prompts/v0.16.6.md: new version (copy of v0.16.5 plus a
  6-line Common-Mistakes block), byte-identical across both trees, recorded with its real
  sha256 in both versions.json, "active" bumped in both. v0.16.2/v0.16.5 untouched, so
  pinned eval baselines still resolve byte-identical.
- internal/diag/footguns.md: row 22, status `inventoried`; blind-spot column records both
  known false negatives (value-level aliases V10; allocating-f take-map V25/V26). Header
  repointed off the frozen v0.16.2 per D-1.
- changelogs/v0.18-current.md: entry with the release-evidence table.

Per the plan's D-1 correction, which supersedes the design doc's AC-5: the doc names the
FROZEN prompts/v0.16.2.md; teaching into it would have left the shipped prompt at zero
mentions — recreating #617's own shipped-but-unreachable failure one layer up.

Verified by the controller outside the executor sandbox:
- AC-5: takeFlatMap AND takeMap both >=1 in all five files (baseline 0/0, same-path
  non-empty controls firing); active == v0.16.6 in both trees; recorded hash == file
  sha256 in both; cross-tree diff -q rc=0.
- Reachability (the check #617 itself failed): the built binary's `prompt
  --source=embedded` actually serves the new teaching (takeFlatMap=1, takeMap=1) with the
  v0.16.5 control content intact (toInts=2), active resolving to v0.16.6.
- The recorded hash is a REAL gate, not decoration: corrupting it (mutation asserted
  LANDED by sha256) reds TestAILANGPromptLoading and TestPromptDisambiguation with
  `hash mismatch for "v0.16.6"` — the right mechanism, not just a red exit code. Restored
  from a cp backup, byte-identical.
- Gates: check-changelog, fmt-check, verify-examples (188 modules, 1 pre-existing
  missing-on-disk, unchanged), test-stdlib-ail, lint, and the AC-7 builtins arm all rc=0.

Co-Authored-By: codex gpt-5.6-sol
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The evaluator found the changelog shipped only the takeFlatMap (V1/V2) pair. The plan's
AC-3b requires /usr/bin/time -l on BOTH rewritten repros and names both targets
(425 MB/81.9s and 559 MB/18.78s -> 101 MB/0.08s); reproduced first-party against the plan
text before acting. Adds the V25/V26 rows plus the V7 caveat that a non-allocating scalar f
does not amplify, which is why the map half is conditional rather than a blanket rule.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@sunholo-voight-kampff
sunholo-voight-kampff merged commit ebbc5a7 into dev Aug 12, 2026
21 checks passed
@sunholo-voight-kampff
sunholo-voight-kampff deleted the sprint/iter185-617-m3-teach branch August 12, 2026 14:28
sunholo-voight-kampff added a commit that referenced this pull request Aug 12, 2026
…ne died with a clean rc=0 (#677)

Records for iteration 185: charter STATUS stamp (rotation invariant held at 3, line-count
assertion passed), mission log entry 187, dashboard refreshed, #617 queue row updated to
M3 LANDED (merge ebbc5a7, PR #675).

Credits iteration 184, which ran and left zero records: it spawned the codex executor,
announced a wait and exited rc=0 six minutes later. Standing rule 7, 4th instance
(159/167/176/184), and the first confirmed under bg-wait-ceiling=0ms where the rule's own
grep-tell is blind. Raised to Mark as D-11, because the codex lane structurally mandates a
background spawn and no wording change closes that.

Co-authored-by: Claude Opus 5 <noreply@anthropic.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