Archived
d3495476f4
El SDK Release / build-and-release (push) Failing after 13m0s
The generated C, amalgams, vendored runtime pins, and compiled binaries from the Claude Code era are removed from the worktree. The El sources survive; this tree is now source-only for the first-principles rebuild. Per Principal direction 2026-08-19.
380 lines
29 KiB
Markdown
380 lines
29 KiB
Markdown
# CLAIMS — cycle 06, the crossing resolves at emission
|
||
|
||
Source doc: `docs/v1/experiments/cycles/06-the-crossing-resolves-at-emission.md`
|
||
|
||
This cycle pins **five** commits. The record is five commit messages, written
|
||
sequentially as the experiment ran, so several figures are restated at the
|
||
landing commit and one claim is silently corrected by a later commit in the
|
||
same cycle. Both are checked below.
|
||
|
||
## Pinned commits
|
||
|
||
| Tag | SHA | Committed | Subject | Parent | Worktree |
|
||
|---|---|---|---|---|---|
|
||
| 06a | `35b07bade29fcd93a663a2f538b43c31f07e28cb` | 2026-08-17 08:37:47 -0500 | EXPERIMENT: resolve the crossing at execution, not at emission | `1b324a071` | `/tmp/rerun-v1-06a` |
|
||
| 06b | `886626a64e4c64b46d8382d95ab1d0ff7b739fe9` | 2026-08-17 08:40:10 -0500 | seam refusal + control tests: a runtime binding can short-circuit | `35b07bade` | `/tmp/rerun-v1-06b` |
|
||
| 06c | `28d19da7f1b6b43394302c82ef58446deeebc9d3` | 2026-08-17 08:43:57 -0500 | strip the compile-time machinery the seam replaces | `886626a64` | `/tmp/rerun-v1-06c` |
|
||
| 06d | `8bbb750c2cefc2dc070f6c5ff598e82483df9bcf` | 2026-08-17 08:48:57 -0500 | control the claim that cannot be unit tested | `28d19da7f` | `/tmp/rerun-v1-06d` |
|
||
| 06e | `24f7fb51436bdc68838fd7651d7377f3fb919ee3` | 2026-08-17 08:56:41 -0500 | land the runtime seam: resolve the crossing at execution | **merge**: `82e998273` + `8bbb750c2` | `/tmp/rerun-v1-06e` |
|
||
|
||
`24f7fb5` is a **merge commit**, not a linear child of `8bbb750` (`0214-commit-dag-topology.out`).
|
||
Its first parent is `82e9982` (a self-review commit on the trunk). Consequently
|
||
`git diff 24f7fb5^ 24f7fb5` shows the *entire* cycle, and `codegen.el` /
|
||
`el_runtime.c` are unchanged between `8bbb750` and `24f7fb5` except for the
|
||
+60 runtime lines that come in from `82e9982`.
|
||
|
||
All five worktrees were clean at capture. Every artifact is stamped `tree clean`
|
||
in `MANIFEST.tsv`. Environment: Apple M-series arm64, Apple clang 21.0.0,
|
||
macOS 25.5.0 (`RUN.env`).
|
||
|
||
## Self-hosting method used throughout
|
||
|
||
`dist/platform/elc` (the committed bootstrap) is **stale** at every commit in
|
||
this cycle, because every one of these commits changes codegen's output. So:
|
||
|
||
```
|
||
gen1 = dist/platform/elc elc-cli.el # stale bootstrap emission, NO seam
|
||
gen2 = elc(built from gen1) elc-cli.el # first emission that carries the seam
|
||
gen3 = elc(built from gen2) elc-cli.el # the fixpoint check
|
||
```
|
||
|
||
The fixpoint is **gen2 == gen3**. `gen1 != gen2` is expected. This is exactly
|
||
the methodological point the record itself makes at `35b07ba` ("my first
|
||
fixpoint test was wrong, not the code"), and this record demonstrates both
|
||
halves. All seam-site counts below are taken from **gen2**, the self-hosted
|
||
emission — gen1 contains no seam at all.
|
||
|
||
## Verdicts
|
||
|
||
| # | Claim (verbatim from the record) | Artifact | Commit | Verdict |
|
||
|---|---|---|---|---|
|
||
| 1 | "codegen emits one unconditional indirection per fn" | `0363-fn-count-vs-seam-sites-06a.out`, `0030-seam-site-count-breakdown-06a.out` | `35b07ba` | **REPRODUCED exactly** — gen2 declares 266 `el_val_t` functions (266 prototypes + 266 definitions = 532 lines, 266 distinct names) and carries 266 indirections over 266 distinct names. The set difference is **empty**: every declared function has exactly one, and nothing else has one |
|
||
| 2 | P1 "a construct declared after the build applies" — TRUE | `0272-RECONSTRUCTED-seamrun-transcript-06a.out`, `0274-RETROFIT-seam_binding-harness-06a.out` | `35b07ba` | **REPRODUCED** |
|
||
| 3 | P2 "an unlinked target is skipped, not fatal" — TRUE | `0272-…-seamrun-transcript-06a.out`, `0274-RETROFIT-…-06a.out` | `35b07ba` | **REPRODUCED** — binding `no_such_symbol_anywhere` prints 7, exit 0 |
|
||
| 4 | P3 "emitting on every fn is measurably slower" — **FALSE**, "0.37s -> 0.36s … Free unused" | `0298-REDO-free-when-unused-clean-binary-06a.out`, `0297-RECONSTRUCTED-free-when-unused-06a.out` | `35b07ba` | **DIVERGED** — it *is* measurably slower here: +3.9 % median, B slower in 38/41 interleaved paired runs. See detail A |
|
||
| 5 | "267 indirections" / "267 seam sites" | `0013-selfhost-3gen-fixpoint-06a.out`, `0030-seam-site-count-breakdown-06a.out` | `35b07ba` | **REPRODUCED** — `grep -c el_seam_run` on gen2 = **267**, exactly. Of those, 266 are emitted statements and 1 is codegen's own `emit_line` string literal. See detail F |
|
||
| 6 | P4 "the compiler still self-hosts" — TRUE | `0013-selfhost-3gen-fixpoint-06a.out` | `35b07ba` | **REPRODUCED** — gen2 == gen3, sha256 `ca98d55ffad2…` both |
|
||
| 7 | P4 note: "I compared gen1 to gen2, which must differ whenever codegen's output changes" | `0013-selfhost-3gen-fixpoint-06a.out` | `35b07ba` | **REPRODUCED** — gen1 (`1748ab31…`) != gen2 (`ca98d55f…`); the author's diagnosis of his own bad test is correct |
|
||
| 8 | P4 note: "gen2 == gen3, 267 seam sites, stable" | `0013-selfhost-3gen-fixpoint-06a.out` | `35b07ba` | **REPRODUCED** — gen2 and gen3 both 11817 lines, both 267 `el_seam_run` lines, byte-identical |
|
||
| 9 | DEMONSTRATED transcript: `/tmp/seamrun` → 7; then `EL_CONSTRUCTS=constructs.txt /tmp/seamrun` → "AUDIT: work applied by audited" / 7 | `0272-RECONSTRUCTED-seamrun-transcript-06a.out` | `35b07ba` | **REPRODUCED** (probe reconstructed — see "Reconstructed inputs") — output matches the transcript verbatim, line for line |
|
||
| 10 | MEASURED COST: "0 bindings 0.36s vs 0.37s baseline" (absolute) | `0296-RECONSTRUCTED-seam-cost-timing-06a.out` | `35b07ba` | **NOT-REPRODUCIBLE (machine-dependent)** — this machine runs the same workload in 0.055 s / 0.058 s, ~6.7× faster than the record's hardware |
|
||
| 11 | MEASURED COST: "2 bindings, dlsym per call — 2.45s" (absolute) | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **NOT-REPRODUCIBLE (machine-dependent)** — observed 0.160 s |
|
||
| 12 | MEASURED COST: "2 bindings, resolved once — 0.69s" (absolute) | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **NOT-REPRODUCIBLE (machine-dependent)** — observed 0.112 s |
|
||
| 13 | "…dlsym per call **6.6x**" (ratio) | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **DIVERGED** — observed **2.909×** over baseline. See detail B |
|
||
| 14 | "…resolved once **3.5x** recovered" (ratio) | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **DIVERGED** — observed **1.429×** recovered. See detail B |
|
||
| 15 | "The table scan was never the cost. dlsym walks the dynamic symbol table on every call. Resolve once and cache" | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **REPRODUCED (direction)** — disabling the resolve-once cache costs 48 ms over 521 597 crossings ≈ 92 ns per `dlsym`; the table scan (2 entries) is not separable from noise |
|
||
| 16 | "The 0.69s residual is audit_entry's own printf … not seam overhead" | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **DIVERGED** — the printf is **63 %** of the residual, not all of it; the remaining **37 %** *is* seam dispatch. See detail C |
|
||
| 17 | "Prediction 3 was FALSE. I expected refusal to be impossible through the seam" | `0274-RETROFIT-…-06a.out` vs `0273-RETROFIT-…-06b.out` | `35b07ba` → `886626a` | **REPRODUCED** — at `35b07ba` the refusal assertion is the *only* one of six that fails (expected 42, actual 7); at `886626a` all six pass |
|
||
| 18 | The one-line emitted shape `{ el_val_t __s = el_seam_run(EL_STR(f), 0, 0); if (__s) return __s; }` | `0105-emitted-seam-shape-and-counts.out`, `0190-seam-c-line-count-precise.out` | `886626a` | **REPRODUCED verbatim** — emitted C reads ` { el_val_t __s = el_seam_run(EL_STR("is_digit_code"), 0, 0); if (__s) return __s; }`; the commit's codegen diff is a one-line replacement |
|
||
| 19 | "work() returns 7; bound to a refusing construct AFTER the build it returns 42" | `0273-RETROFIT-seam_binding-harness-06b.out` | `886626a` | **REPRODUCED** |
|
||
| 20 | "three of the five compile-time kinds are runtime-bindable: entry injection, exit injection, and refusal" | `0299-exit-phase-bindability-check.out`, `0324-RECONSTRUCTED-exit-binding-probe-06b.out`, `0325-…-06e.out` | `886626a` | **DIVERGED** — only **two** are: entry injection and refusal. No exit-phase indirection is ever emitted in this cycle. See detail D |
|
||
| 21 | "wraps_body needs invocation control and prohibits_outside is compile-time by nature" | `0326-strip-table-verification-28d19da.out`, `0348-residual-kind-references-28d19da.out` | `886626a` | **REPRODUCED** — both survive the strip; `prohibits_outside` resolves to `emit_line("#error \"boundary violation: …")` at codegen.el:3371 |
|
||
| 22 | "104/104 native compiler tests pass" | `0047-native-compiler-tests-06b.out` | `886626a` | **REPRODUCED** — `104 tests, 104 passed, 0 failed, 253 assertions` |
|
||
| 23 | "PREDICTION: codegen.el drops below 4661 … RESULT: FALSE" | `0128-REDO-codegen-linecount-history.out` | `28d19da` | **REPRODUCED** — the prediction is indeed false; codegen.el is 5095 after the strip, still far above 4661 |
|
||
| 24 | "**5157** -> **5096**" | `0128-REDO-codegen-linecount-history.out` | `886626a` → `28d19da` | **DIVERGED** — observed **5156 -> 5095**. Both endpoints are exactly one line high in the record. See detail E |
|
||
| 25 | "Still **+435** over baseline" | `0128-REDO-codegen-linecount-history.out`, `0348-residual-kind-references-28d19da.out` | `28d19da` | **DIVERGED** — 5095 − 4661 = **+434** |
|
||
| 26 | "4661, its size before any of these passes" (the baseline itself) | `0128-REDO-codegen-linecount-history.out` | pre-cycle | **REPRODUCED** — codegen.el is exactly 4661 lines at `409bf573` and `addd5120`, the two commits immediately preceding cycle 01's parent |
|
||
| 27 | "injects_at_entry collapsed into the seam — removed / guards_at_entry collapsed into the seam — removed" | `0326-strip-table-verification-28d19da.out`, `0348-…-28d19da.out` | `28d19da` | **REPRODUCED** — `declare_decorator`, `decorator_injection`, `declare_guard`, `decorator_guard` and both token-scan branches deleted; the single surviving mention of each name at 28d19da is a `//` comment |
|
||
| 28 | "injects_at_exit — STRUCTURAL / wraps_body — structural / prohibits_outside — a #error cannot be emitted at runtime" | `0326-strip-table-verification-28d19da.out` | `28d19da` | **REPRODUCED** — all three untouched by the strip diff |
|
||
| 29 | "**61 lines** of compiler replaced by one refusable indirection" | `0128-REDO-…-history.out`, `0190-seam-c-line-count-precise.out` | `28d19da` | **REPRODUCED exactly** — 5156 − 5095 = 61; the diff is `+4 / −65` = net −61 |
|
||
| 30 | "**8 tests fail**, and they are exactly the 8 controls for compile-time entry injection and guards. No unrelated breakage." | `0048-native-compiler-tests-06c.out`, `0051-failing-tests-detail-06c.out` | `28d19da` | **REPRODUCED exactly** — `104 tests, 96 passed, 8 failed`; every failing test named below, 4 entry-injection + 4 guard controls, nothing else |
|
||
| 31 | "Verified after the strip: fixpoint gen2==gen3" | `0069-selfhost-3gen-fixpoint-06c.out` | `28d19da` | **REPRODUCED** — gen2 == gen3, sha256 `7b9b6e0306ff…` |
|
||
| 32 | "observation and refusal both work through the seam with the compiler knowing nothing about either" | `0275-RETROFIT-seam_binding-harness-06c.out` | `28d19da` | **REPRODUCED** — 6/6 with the harness from `8bbb750` applied retroactively |
|
||
| 33 | The six assertion names of `tests/integration/seam_binding.sh` | `0228-integration-seam_binding-06d.out` | `8bbb750` | **REPRODUCED** — all six lines match the record verbatim, in order |
|
||
| 34 | "6 assertions, 6 passed, 0 failed" | `0228-integration-seam_binding-06d.out` | `8bbb750` | **REPRODUCED** — real harness, `bash tests/integration/seam_binding.sh /tmp/elc06d "$PWD"`, exit 0 |
|
||
| 35 | "The eight controls that failed after the strip were replaced, not repaired" | `0239-REDO-test-churn-names.out` | `8bbb750` | **REPRODUCED** — the eight tests deleted at `8bbb750` are, name for name, the eight that failed at `28d19da` |
|
||
| 36 | "Three took their place, asserting the emitted shape" | `0239-REDO-test-churn-names.out` | `8bbb750` | **REPRODUCED** — exactly three added: `seam-replaces-inlined-entry-injection`, `seam-entry-is-refusable`, `seam-is-emitted-for-undecorated-fns`. 104 − 8 + 3 = 99 |
|
||
| 37 | "99/99 native compiler tests pass" | `0049-native-compiler-tests-06d.out` | `8bbb750` | **REPRODUCED** — `99 tests, 99 passed, 0 failed, 240 assertions` |
|
||
| 38 | "Fixpoint holds." | `0081-selfhost-3gen-fixpoint-06d.out` | `8bbb750` | **REPRODUCED** — gen2 == gen3 |
|
||
| 39 | "Five compile-time passes added **491 lines**" | `0348-residual-kind-references-28d19da.out`, `0128-REDO-…-history.out` | `24f7fb5` | **REPRODUCED exactly** — 4661 → 5152 across `5718943`, `60737b0`, `4f7568b`, `7d01608`, `1b324a0`. 5152 − 4661 = 491 |
|
||
| 40 | "The seam is **~55 lines of C** and **one line of emission**" | `0190-seam-c-line-count-precise.out`, `0175-seam-c-block-verbatim.out` | `24f7fb5` | **REPRODUCED** — the implementation block `el_runtime.c:17095–17152` is 58 lines, of which **55 are non-blank** (51 excluding comment lines); codegen contains exactly **one** `emit_line` producing the indirection |
|
||
| 41 | "a construct declared AFTER the binary exists applies to it" | `0229-integration-seam_binding-06e.out` | `24f7fb5` | **REPRODUCED** |
|
||
| 42 | "free when unused: 0.36s vs 0.37s baseline **across 267 indirections**" | `0105-emitted-seam-shape-and-counts.out` | `24f7fb5` | **DIVERGED** — at the landing commit the emission carries **263** `el_seam_run` lines / **262** actual indirections, not 267. The 267 figure is carried forward unchanged from `35b07ba`, before the strip removed four functions. (The timing half is covered by rows 4 and 10.) |
|
||
| 43 | "dlsym was the cost, not the table scan; resolve-once recovered **3.5x**" | `0296-…-seam-cost-timing-06a.out` | `24f7fb5` | **DIVERGED** — the qualitative half reproduces (row 15); the 3.5× does not (observed 1.429×) |
|
||
| 44 | "refusal works, composition works, unlinked targets are skipped not fatal" | `0229-integration-seam_binding-06e.out` | `24f7fb5` | **REPRODUCED** — the three corresponding harness assertions pass |
|
||
| 45 | "injects_at_exit and wraps_body do NOT collapse … The wrapper is structural" | `0326-strip-table-verification-28d19da.out` | `24f7fb5` | **REPRODUCED** |
|
||
| 46 | "prohibits_outside cannot move at all — a #error has no runtime" | `0348-residual-kind-references-28d19da.out` | `24f7fb5` | **REPRODUCED** — `prohibits_outside` still emits `#error` at codegen.el:3371 |
|
||
| 47 | "Controls: 99/99 native compiler tests, plus tests/integration/seam_binding.sh (6/6)" | `0050-native-compiler-tests-06e.out`, `0229-integration-seam_binding-06e.out` | `24f7fb5` | **REPRODUCED** — both, exactly |
|
||
| 48 | Cross-cycle: cycle 08's doc says "7/7 seam_binding.sh" where this cycle says 6/6 | `0256-seam_binding-assertion-growth.out` | `285166c` | **REPRODUCED as consistent, not contradictory** — `seam_binding.sh` gains a seventh assertion ("an EXIT construct declared after the build replaces the result") at `285166c`, after this cycle ends. See detail D |
|
||
|
||
**Counts: 48 assertions — REPRODUCED 36, DIVERGED 9, NOT-REPRODUCIBLE 3, NOT-CAPTURED 0.**
|
||
|
||
The nine divergences are rows 4, 13, 14, 16, 20, 24, 25, 42, 43, detailed in
|
||
sections A–F below. Two of them (rows 13/14 and 43) are the same two ratios
|
||
stated twice, once in the experiment commit and once in the landing commit.
|
||
|
||
---
|
||
|
||
## Divergence detail A — P3, "emitting on every fn is measurably slower: FALSE"
|
||
|
||
The record's evidence is a single before/after pair, `0.37s -> 0.36s`, reported
|
||
to two decimal places on a ~370 ms run. A single pair at that resolution cannot
|
||
distinguish a 3 % effect from noise, and the sign it happened to land on
|
||
(faster) drove the verdict FALSE.
|
||
|
||
Re-measured as an **interleaved paired** benchmark, A,B,A,B,… × 41, so that
|
||
clock or thermal drift cannot favour either arm:
|
||
|
||
| | A: no seam (`35b07ba^`, self-hosted) | B: 266 indirections (`35b07ba`, self-hosted) |
|
||
|---|---|---|
|
||
| min | 0.0572 s | 0.0597 s |
|
||
| median | 0.0595 s | 0.0618 s |
|
||
| mean | 0.0597 s | 0.0618 s |
|
||
| sd | 0.0019 s | 0.0011 s |
|
||
|
||
- **B/A = 1.0391× by median, 1.0362× by mean, 1.0451× by min.** The record's
|
||
pair implies 0.36/0.37 = 0.9730×.
|
||
- Paired difference B−A: **median +2.27 ms, mean +2.16 ms, sd 1.61 ms**.
|
||
- **B was slower in 38 of 41 paired runs.**
|
||
|
||
Both arms are self-hosted to fixpoint, both `-O2 -rdynamic`, both compile
|
||
`elc-cli.el` with stdout to `/dev/null`. The only source difference between the
|
||
two compilers is this commit's 4-line codegen addition and 75-line runtime
|
||
addition. The first run of this benchmark (`0297`) used a B binary that also
|
||
linked the counting-target object file; `0298` repeats it with a clean B binary
|
||
built from gen2 plus the runtime alone, and gets the same answer (+3.9 %,
|
||
38/41), so the extra object file was not the cause.
|
||
|
||
**The record's practical conclusion survives; its literal verdict does not.**
|
||
266 unused indirections cost about 4 % of a compile — small enough that
|
||
"free unused" is a fair engineering summary, but it is a real, consistently
|
||
signed, measurable cost. The prediction "emitting on every fn is measurably
|
||
slower" was marked FALSE on evidence that could not support the call.
|
||
|
||
## Divergence detail B — the 6.6× and 3.5× ratios
|
||
|
||
Four variants, min of 9 runs each, same workload (`elc elc-cli.el > /dev/null`):
|
||
|
||
| | observed | record |
|
||
|---|---|---|
|
||
| A baseline, no seam | 0.055 s | 0.37 s |
|
||
| B seamed, 0 bindings | 0.058 s | 0.36 s |
|
||
| C seamed, 2 bindings, resolve-once | 0.112 s | 0.69 s |
|
||
| D seamed, 2 bindings, dlsym per call | 0.160 s | 2.45 s |
|
||
| E seamed, 2 bindings, **silent** target | 0.076 s | (not measured) |
|
||
|
||
| ratio | observed | record |
|
||
|---|---|---|
|
||
| D/A dlsym-per-call vs baseline | **2.909×** | 6.6× |
|
||
| D/C recovered by resolve-once | **1.429×** | 3.5× |
|
||
| C/A resolve-once vs baseline | **2.036×** | 1.865× (0.69/0.37) |
|
||
|
||
The record specifies neither the workload, nor which two functions were bound,
|
||
nor the target's body, nor the hardware. Two of those were chosen here and are
|
||
stated in "Reconstructed inputs" below; the choice of *which* two functions
|
||
dominates the result entirely, since the ratio scales with the number of
|
||
crossings. The two bound here are the two hottest **as measured** (`0276`), not
|
||
guessed: `tok_kind` (310 018 crossings) and `is_ws_code` (211 579), 521 597
|
||
total.
|
||
|
||
The direction is right in every case and the mechanism is right (detail C).
|
||
The magnitudes are not reproducible from what the record states, and they are
|
||
reported here without any adjustment toward the claimed figures.
|
||
|
||
One further caveat on D: **the `dlsym`-per-call variant reconstructs a state
|
||
that was never committed.** The code at `35b07ba` already caches
|
||
(`resolve_tried`), so the 2.45 s measurement must have been taken on a working
|
||
tree that no commit preserves. D was produced by turning
|
||
`if (!_el_seam[i].resolve_tried)` into `if (1)` in a *scratchpad copy* of
|
||
`el_runtime.c`; no worktree was modified.
|
||
|
||
## Divergence detail C — "the residual is audit_entry's own printf, not seam overhead"
|
||
|
||
This is the one claim in the cost table that is a causal attribution rather
|
||
than a number, and it is the one worth separating. Variant E repeats variant C
|
||
with a **silent** target, which the record never measured:
|
||
|
||
- C − A = 57 ms — the whole residual over baseline
|
||
- C − E = **36 ms** — attributable to the target's `printf` (63 % of the residual)
|
||
- E − A = **21 ms** — attributable to seam dispatch itself (37 % of the residual),
|
||
≈ 40 ns per crossing over 521 597 crossings
|
||
|
||
So the printf is the *larger* share, and the record is right that it is the
|
||
thing to look at. But it is not the whole thing: a third of the residual is the
|
||
seam's own dispatch, and the record's "not seam overhead" overstates it.
|
||
|
||
## Divergence detail D — "exit injection is runtime-bindable"
|
||
|
||
At `886626a` the record states that **three** of the five compile-time kinds
|
||
are runtime-bindable: entry injection, exit injection, and refusal.
|
||
|
||
Entry injection and refusal are. **Exit injection is not, at any commit in this
|
||
cycle.**
|
||
|
||
- The runtime's table parser accepts `entry|exit` and defines `EL_PHASE_EXIT 1`
|
||
(`el_runtime.c:17097`, `:17119`), so an exit binding *loads* without error.
|
||
- But codegen emits exactly **one** `el_seam_run` call, at every one of the five
|
||
commits, and its phase argument is a literal `0`. Emitted C at `24f7fb5`
|
||
contains **263** phase-0 calls and **0** phase-1 calls (`0299`).
|
||
- Empirically (`0324`, `0325`): binding `work doubler exit double_result` on an
|
||
already-built binary produces no output from the target and leaves the result
|
||
at 7, at both `886626a` and `24f7fb5`. The identical binding in the `entry`
|
||
phase fires normally.
|
||
|
||
An exit binding is therefore accepted and silently never fires — a worse
|
||
failure mode than rejection.
|
||
|
||
The record corrects itself three commits later without acknowledging the
|
||
earlier claim: `28d19da` lists `injects_at_exit` as **STRUCTURAL**, and
|
||
`24f7fb5` says plainly "injects_at_exit and wraps_body do NOT collapse". The
|
||
seventh `seam_binding.sh` assertion — "an EXIT construct declared after the
|
||
build replaces the result" — first appears at `285166c`, whose subject is
|
||
"EXPERIMENT: emit the wrapper unconditionally, **so exit binds at runtime too**",
|
||
i.e. after this cycle, as new work. That also resolves the 6/6-vs-7/7 question:
|
||
cycle 06's 6/6 and cycle 08's 7/7 are both correct for their commits.
|
||
|
||
## Divergence detail E — the codegen.el line counts, off by one at both ends
|
||
|
||
| | record | observed (`wc -l`, and `grep -c ""`) |
|
||
|---|---|---|
|
||
| `28d19da^` = `886626a` | 5157 | **5156** |
|
||
| `28d19da` | 5096 | **5095** |
|
||
| difference | 61 | **61** |
|
||
| over the 4661 baseline | +435 | **+434** |
|
||
|
||
Both files end with a trailing newline (`0128` includes the `od -c` check), so
|
||
`wc -l` is exact and `grep -c ""` agrees with it. The error is systematic and
|
||
in the same direction at both ends — the signature of a count read off an
|
||
editor that shows a phantom final line, i.e. N+1 for a newline-terminated file.
|
||
|
||
The *delta* is unaffected, which is why the load-bearing claim of the commit —
|
||
"61 lines of compiler replaced by one refusable indirection" — reproduces
|
||
exactly, and why the conclusion (the prediction was FALSE; codegen did not drop
|
||
below 4661) is untouched.
|
||
|
||
Worth noting against this: the "**491 lines**" figure in the landing commit is
|
||
computed from the *true* `wc -l` values (4661 → 5152 = 491, exact). So the
|
||
record's own line counts are not produced by one consistent method.
|
||
|
||
## Divergence detail F — the "267 seam sites", and what it counts
|
||
|
||
The record's 267 reproduces on the nose: `grep -c el_seam_run` over the
|
||
self-hosted gen2 emission at `35b07ba` returns exactly **267**, at both gen2 and
|
||
gen3.
|
||
|
||
One of those 267 lines is not an indirection. It is codegen's own emitter line,
|
||
which appears in the compiler's emitted C as a string literal:
|
||
|
||
```
|
||
8180: emit_line(el_str_concat(el_str_concat(EL_STR(" el_seam_run(EL_STR("), c_str_lit(fn_name)), EL_STR("), 0, 0);")));
|
||
```
|
||
|
||
The count of actual emitted indirections is therefore **266**, over **266
|
||
distinct function names**, one apiece — which is the cleaner statement of the
|
||
mechanism ("one unconditional indirection per fn") and is confirmed
|
||
independently in `0363`: gen2 contains 532 `el_val_t` declaration lines, exactly
|
||
266 prototypes and 266 definitions over 266 distinct names, and the set of
|
||
declared functions minus the set of seamed functions is **empty**. This is
|
||
recorded as a precision note, not as an error: 267 is the
|
||
number the obvious command prints, and the off-by-one is the compiler counting
|
||
itself.
|
||
|
||
The figure does **not** survive the strip. After `28d19da` removes four
|
||
functions, the same grep returns **263** (262 real indirections) at `28d19da`,
|
||
`8bbb750` and `24f7fb5` — whose gen2 emissions are byte-identical to each other
|
||
(sha256 `7b9b6e0306ff…`). The landing commit's restatement "across 267
|
||
indirections" is a stale carry-forward (row 42).
|
||
|
||
---
|
||
|
||
## The eight failing tests at `28d19da`, named
|
||
|
||
The record says "8 tests fail, and they are exactly the 8 controls for
|
||
compile-time entry injection and guards. No unrelated breakage." The run
|
||
(`0048`, exit code **8**; detail in `0051`) reports
|
||
`104 tests, 96 passed, 8 failed, 253 assertions`:
|
||
|
||
| # | Test | Failing assertion | Kind |
|
||
|---|---|---|---|
|
||
| 1 | `decorator-manager-beat-carries-construct` | "@manager injects the beat" | entry injection |
|
||
| 2 | `decorator-accessor-beat-carries-construct` | "@accessor injects the beat" | entry injection |
|
||
| 3 | `declared-construct-injects-without-compiler-knowledge` | "a program-declared construct injects" | entry injection |
|
||
| 4 | `builtin-constructs-still-inject` | "seeded manager still injects" | entry injection |
|
||
| 5 | `declared-guard-emits-refusable-check` | "the guard is called at entry" | guard |
|
||
| 6 | `declared-guards-stack-in-order` | "first guard runs" | guard |
|
||
| 7 | `guard-precedes-injection` | "the guard is emitted before the beat" | guard + entry injection |
|
||
| 8 | `constructs-compose-guard-entry-exit` | "guard before entry injection" | guard + entry injection |
|
||
|
||
Exactly eight, four entry-injection and four guard, nothing else. The claim is
|
||
reproduced without qualification. `8bbb750` then deletes these eight by name
|
||
(`0239`) and adds three — `seam-replaces-inlined-entry-injection`,
|
||
`seam-entry-is-refusable`, `seam-is-emitted-for-undecorated-fns` — giving
|
||
104 − 8 + 3 = 99.
|
||
|
||
## Test and seam-site totals across the cycle
|
||
|
||
| commit | native tests | seam lines in gen2 | real indirections | codegen.el | fixpoint |
|
||
|---|---|---|---|---|---|
|
||
| `1b324a0` (parent) | 102 declared | 0 | 0 | 5152 | — |
|
||
| `35b07ba` | 102 / 102 pass | 267 | 266 | 5156 | gen2==gen3 |
|
||
| `886626a` | 104 / 104 pass | 267 | 266 | 5156 | gen2==gen3 |
|
||
| `28d19da` | 104, **96 pass / 8 fail** | 263 | 262 | 5095 | gen2==gen3 |
|
||
| `8bbb750` | 99 / 99 pass | 263 | 262 | 5095 | gen2==gen3 |
|
||
| `24f7fb5` | 99 / 99 pass | 263 | 262 | 5095 | gen2==gen3 |
|
||
|
||
## Reconstructed inputs
|
||
|
||
Three inputs used below did not exist in the tree at the commit measured. Each
|
||
is an **input**, not evidence; the evidence is the captured output of running
|
||
it at the pinned commit.
|
||
|
||
1. **`/tmp/seamrun`** (`0272`). The record's DEMONSTRATED transcript names a
|
||
probe binary that was never committed. It was rebuilt from the record's own
|
||
text — an El program with `fn work() -> Int { return 7 }` and no construct
|
||
anywhere, plus a linked-but-unreferenced C target named `audit_entry`
|
||
printing `AUDIT: <fn> applied by <construct>`. The structure is copied from
|
||
`tests/integration/seam_binding.sh`, which the same author committed three
|
||
commits later (`8bbb750`) as the permanent form of this same hand check; the
|
||
only substitutions are the record's own target name and message. Captured
|
||
output matches the transcript line for line.
|
||
2. **`seam_binding.sh` applied retroactively** (`0273`, `0274`, `0275`). The
|
||
harness from `8bbb750` was run, unmodified, against the compilers built at
|
||
`35b07ba`, `886626a` and `28d19da`, where it does not yet exist. This is what
|
||
establishes that refusal fails at `35b07ba` and succeeds from `886626a` on.
|
||
Artifacts are named `RETROFIT-` to mark that the harness postdates the commit.
|
||
3. **The timing rig** (`0276`, `0296`, `0297`, `0298`) — see detail B. The
|
||
`dlsym`-per-call arm uses a scratchpad copy of `el_runtime.c` with the
|
||
resolve-once cache disabled. No worktree was modified at any point; all five
|
||
worktrees are `clean` on every artifact in `MANIFEST.tsv`.
|
||
|
||
The two hottest functions used for the 2-binding measurements were determined
|
||
**by measurement, not by guess** (`0276`): the seam itself was used as an
|
||
instrument, binding all 266 seamed functions in two batches to a counting
|
||
target that dumps at exit. Top of the distribution compiling `elc-cli.el`:
|
||
`tok_kind` 310 018, `is_ws_code` 211 579, `is_digit_code` 208 435,
|
||
`is_alpha_code` 204 417, `is_alnum_or_underscore_code` 152 568; 1 692 602
|
||
crossings over 124 functions actually reached.
|
||
|
||
## Measurement defects in this re-run, recorded rather than removed
|
||
|
||
1. **`0114-codegen-linecount-history.out` is defective and retained.** Its
|
||
`while read -r h </dev/null` attached the redirect to the whole loop instead
|
||
of to `git` inside it, so `read` had no stdin and the loop body never ran;
|
||
the artifact's history table is empty. The `=== the specific endpoints ===`
|
||
section below it is unaffected and correct. Corrected capture:
|
||
`0128-REDO-codegen-linecount-history.out`. Cite `0128`, not `0114`.
|
||
2. **`0230-test-churn-8bbb750.out` is defective and retained.** It grepped for
|
||
`test(` where the test declaration syntax is `test "name" {`, so all three
|
||
of its test-name sections are empty. Corrected capture:
|
||
`0239-REDO-test-churn-names.out`. Cite `0239`, not `0230`.
|
||
3. **`0297-RECONSTRUCTED-free-when-unused-06a.out` is superseded but not
|
||
defective.** Its B arm linked an extra object file (the counting targets).
|
||
`0298-REDO-free-when-unused-clean-binary-06a.out` repeats it with a clean
|
||
binary. Both are retained; they agree (+3.9 % median, 38/41 paired runs), so
|
||
either may be cited. `0298` is the cleaner instrument.
|
||
4. **A recipe defect that did *not* enter this record.** The re-run recipe's
|
||
original fixpoint step compared gen1 to gen2, which is exactly the wrong test
|
||
— the mistake this cycle's own P4 note diagnoses. It was corrected before any
|
||
fixpoint artifact was captured here, so all five `selfhost-3gen-fixpoint-*`
|
||
artifacts already compare gen2 to gen3 and additionally record gen1 != gen2.
|
||
No superseded fixpoint artifact exists.
|
||
|
||
## Note for later cycles
|
||
|
||
- The "267 indirections" figure is correct only for `35b07ba` and `886626a`.
|
||
From `28d19da` onward it is 263 (262 real). Cycles that cite 267 after the
|
||
strip are citing a stale number.
|
||
- The claim that exit injection is runtime-bindable (detail D) is false for the
|
||
whole of cycle 06 and becomes true at `285166c`. Any later cycle that treats
|
||
cycle 06 as having delivered runtime exit binding is inheriting the error.
|