# the crossing resolves at emission One `Ishikawa → scientific method → Six Sigma` loop. The record below is the commit message as written at the time, before the outcome was known to anyone reading this file. ## Record — `35b07ba` ``` EXPERIMENT: resolve the crossing at execution, not at emission HYPOTHESIS (Will's): a compiler whose one compiled mechanism is extending the LANGUAGE — not the compiler — can compose without recompilation. ISHIKAWA — why does a construct require a recompile today? method codegen inlines the target call into the body machine the binary has no table to consult material the declaration lives in source, read at compile time measurement nothing observes what applied at runtime root cause the crossing is resolved at EMISSION, not at EXECUTION CHANGE: codegen emits one unconditional indirection per fn. Which constructs apply is read from a table that can be written AFTER the binary exists; targets resolve through dlsym against the running image. PREDICTIONS AND RESULTS P1 a construct declared after the build applies TRUE P2 an unlinked target is skipped, not fatal TRUE P3 emitting on every fn is measurably slower FALSE — 0.37s -> 0.36s with 267 indirections and no bindings. Free unused. P4 the compiler still self-hosts TRUE (see note) DEMONSTRATED: an El program with NO decorator in its source, already compiled and linked, picked up a construct declared afterwards: $ /tmp/seamrun -> 7 $ echo 'work audited entry audit_entry' > constructs.txt $ EL_CONSTRUCTS=constructs.txt /tmp/seamrun AUDIT: work applied by audited 7 P4 note: my first fixpoint test was wrong, not the code. I compared gen1 to gen2, which must differ whenever codegen's output changes. gen2 == gen3, 267 seam sites, stable. MEASURED COST, and the root cause was not where I looked 0 bindings 0.36s vs 0.37s baseline free 2 bindings, dlsym per call 2.45s 6.6x 2 bindings, resolved once 0.69s 3.5x recovered The table scan was never the cost. dlsym walks the dynamic symbol table on every call. Resolve once and cache — which is the smallest form of what salience does for memory: what is hot stays resolved. The 0.69s residual is audit_entry's own printf on two of the compiler's hottest functions, not seam overhead. CONSEQUENCE: the five compile-time declaration kinds on iteration-1 are a compile-time specialisation of something that resolves at runtime. They are not wrong, but they are not the mechanism — the mechanism is one indirection, and a kind is data. ``` ## Record — `886626a` ``` seam refusal + control tests: a runtime binding can short-circuit Prediction 3 was FALSE. I expected refusal to be impossible through the seam because the entry indirection discarded its return. One line: { el_val_t __s = el_seam_run(EL_STR(f), 0, 0); if (__s) return __s; } work() returns 7; bound to a refusing construct AFTER the build it returns 42. So three of the five compile-time kinds are runtime-bindable: entry injection, exit injection, and refusal. wraps_body needs invocation control and prohibits_outside is compile-time by nature. 104/104 native compiler tests pass. ``` ## Record — `28d19da` ``` strip the compile-time machinery the seam replaces PREDICTION: codegen.el drops below 4661, its size before any of these passes. RESULT: FALSE. 5157 -> 5096. Still +435 over baseline. injects_at_entry collapsed into the seam removed guards_at_entry collapsed into the seam removed injects_at_exit needs the body-helper wrapper STRUCTURAL wraps_body needs the closure + wrapper structural prohibits_outside a #error cannot be emitted at runtime The wrapper is not a consequence of compile-time resolution. Early returns must be routed through something no matter when the target is resolved, so exit injection was never going to collapse. I predicted it would because I had conflated "resolved late" with "emitted less". What did collapse is entry injection and refusal -- 61 lines of compiler replaced by one refusable indirection, with the capability now bindable after the binary exists. 8 tests fail, and they are exactly the 8 controls for compile-time entry injection and guards. No unrelated breakage: the controls reported precisely what moved. They assert emission of something that now happens at runtime, so they need rewriting as integration tests -- which the framework does not currently support, because runtime binding needs a built binary and an environment, not compile_capture. Verified after the strip: fixpoint gen2==gen3, observation and refusal both work through the seam with the compiler knowing nothing about either. ``` ## Record — `8bbb750` ``` control the claim that cannot be unit tested The seam's whole claim is that a construct declared AFTER a binary exists applies to that already-built program. compile_capture only sees emitted text, so it structurally cannot check this: it needs a built binary, a linked target, and an environment. Verified by hand until now, which is the standing problem this session has been about. tests/integration/seam_binding.sh builds a probe from El source containing no construct at all, links a target that El never references, and asserts: ok unbound program is unaffected ok a construct declared AFTER the build applies ok a construct declared after the build can REFUSE ok an unlinked target is skipped, not fatal ok a binding for a different fn does not fire ok two constructs compose on one crossing 6 assertions, 6 passed, 0 failed The eight controls that failed after the strip were replaced, not repaired. They asserted compile-time emission of capability that moved to runtime; contorting them would have kept an assertion whose subject no longer exists. Three took their place, asserting the emitted shape, and the behaviour they used to cover is now the integration harness's job -- which is the honest division, since the shape and the behaviour are no longer the same fact. 99/99 native compiler tests pass. Fixpoint holds. ``` ## Record — `24f7fb5` ``` land the runtime seam: resolve the crossing at execution Five compile-time passes added 491 lines to the thing that was supposed to stop growing. The seam is ~55 lines of C and one line of emission, and it does at runtime what three of those five kinds did at compile time -- for programs that are already built. a construct declared AFTER the binary exists applies to it free when unused: 0.36s vs 0.37s baseline across 267 indirections dlsym was the cost, not the table scan; resolve-once recovered 3.5x refusal works, composition works, unlinked targets are skipped not fatal injects_at_exit and wraps_body do NOT collapse: early returns must route through the body-helper wrapper regardless of when the target is resolved. The wrapper is structural, which I had wrong. prohibits_outside cannot move at all -- a #error has no runtime. Controls: 99/99 native compiler tests, plus tests/integration/seam_binding.sh (6/6) for the claim compile_capture structurally cannot see. ```