Found by the phugoid consumer (rung-3 autopilot), blind-critic rounds 10–11, 2026-08-25, eigenscript v0.41.0 / EigenScript@301026d. Gap ledger: phugoid GAPS.md G7.
Corrected 2026-08-25. The first version of this issue said the arming was module-granular and suggested splitting observer-reading code into its own module. Both were wrong — round 11 refuted them from the source and the runtime. See the correction comment; this body is the corrected version.
Summary
#915 (merged as PR #1034) makes observed scalar writes nearly free when a program uses no observer features. obs_needed is a single flag on EigsState (src/eigenscript.h:561), set in compile_ast (src/compiler.c:3717) and documented there as "Monotonic: a later unit that reads the observer turns it on for good."
So arming is process-wide and monotonic: one verdict read anywhere in the process — in a function that is never called, in a different file, in an eagerly-resolved load_file target (obs_gate_resolve_static_loads), or as a bare string constant in the constant pool — arms entropy bookkeeping for every assignment in every module of that program.
Reproduction
wlib.eigs is a 200k-frame observed write loop containing no observer construct of any kind:
define run_w(n) as:
local u is 0.0
local w is 0.0
local i is 0
loop while i < n:
u is 280.0 + (sin of (i * 0.01))
w is 2.0 + (cos of (i * 0.01))
i is i + 1
print of f"w {i}"
run_w of (200000)
reader_mod.eigs holds a function nobody calls:
define never_called(z) as:
if oscillating of z:
return 1
return 0
and ctrl_mod.eigs is identical with if z > 0.0:. Four mains load these in combination. n=5 medians, two rounds, with the gate’s own verdict for wlib:
| main |
EIGS_OBS_GATE_STATS=1 for wlib |
1 |
2 |
| A: loads wlib only |
unobserved |
0.153 |
0.151 |
B: also loads reader_mod.eigs (different file, dead read) |
observed |
0.219 |
0.219 |
C: also loads ctrl_mod.eigs (numeric control) |
unobserved |
0.155 |
0.154 |
D: msg is "report" at module level, no observer construct |
observed |
0.223 |
0.223 |
Row B: a read-free module compiles as observed because a different file held a read that never executes. Row C: the numeric comparison in the same position costs nothing, so this is arming, not parse cost or function-table size. Row D: const_pool_names_observer scans for bare names, so a string literal "report" costs +48% on a program that uses no observer feature.
Why it matters to a consumer
phugoid rung 3 is a closed-loop autopilot that polls observer verdicts as its supervisory layer — the intended use of the feature. Its profile gate measured what it believed was intrinsic observed-write cost at +44% over an unobserved floor. It is not: neutering only the four predicate reads in a function the measured variant never enters drops that to ~1.03, and forcing the gate open for both programs (EIGS_OBS_FORCE=1) collapses the differential entirely, showing the whole spread is arming. Against a genuinely read-free program an observed scalar write is indistinguishable from the unobserved floor.
That inverted a published finding. An early probe reported "observed scalar writes are essentially free"; the consumer could not reproduce it, withdrew it as wrong, and carried the withdrawal for six review rounds. Both measurements were correct — different regimes, and nobody had named the regime variable.
Practical consequence: unobserved: is the only workaround. Restructuring does not help — a consumer cannot escape by moving verdict reads into their own module, because the flag is process-wide.
What would resolve it
Adding scope where today there is one process-wide bit — per-module at least, per-binding ideally. A fix would also need to cover obs_gate_resolve_static_loads’s eager resolution of literal load_file targets, the always-conservative OP_IMPORT path, and the constant-pool name scan (a program whose only "observer content" is the string "report" should not pay).
The consumer pins this live as a write/noread > 1.15 arm with a planted fault, so when this is fixed upstream that gate fails and tells us to re-attribute and close G7.
Found by the
phugoidconsumer (rung-3 autopilot), blind-critic rounds 10–11, 2026-08-25,eigenscriptv0.41.0 / EigenScript@301026d. Gap ledger: phugoid GAPS.md G7.Summary
#915 (merged as PR #1034) makes observed scalar writes nearly free when a program uses no observer features.
obs_neededis a single flag onEigsState(src/eigenscript.h:561), set incompile_ast(src/compiler.c:3717) and documented there as "Monotonic: a later unit that reads the observer turns it on for good."So arming is process-wide and monotonic: one verdict read anywhere in the process — in a function that is never called, in a different file, in an eagerly-resolved
load_filetarget (obs_gate_resolve_static_loads), or as a bare string constant in the constant pool — arms entropy bookkeeping for every assignment in every module of that program.Reproduction
wlib.eigsis a 200k-frame observed write loop containing no observer construct of any kind:reader_mod.eigsholds a function nobody calls:and
ctrl_mod.eigsis identical withif z > 0.0:. Four mains load these in combination. n=5 medians, two rounds, with the gate’s own verdict forwlib:EIGS_OBS_GATE_STATS=1for wlibunobservedreader_mod.eigs(different file, dead read)observedctrl_mod.eigs(numeric control)unobservedmsg is "report"at module level, no observer constructobservedRow B: a read-free module compiles as
observedbecause a different file held a read that never executes. Row C: the numeric comparison in the same position costs nothing, so this is arming, not parse cost or function-table size. Row D:const_pool_names_observerscans for bare names, so a string literal"report"costs +48% on a program that uses no observer feature.Why it matters to a consumer
phugoid rung 3 is a closed-loop autopilot that polls observer verdicts as its supervisory layer — the intended use of the feature. Its profile gate measured what it believed was intrinsic observed-write cost at +44% over an unobserved floor. It is not: neutering only the four predicate reads in a function the measured variant never enters drops that to ~1.03, and forcing the gate open for both programs (
EIGS_OBS_FORCE=1) collapses the differential entirely, showing the whole spread is arming. Against a genuinely read-free program an observed scalar write is indistinguishable from the unobserved floor.That inverted a published finding. An early probe reported "observed scalar writes are essentially free"; the consumer could not reproduce it, withdrew it as wrong, and carried the withdrawal for six review rounds. Both measurements were correct — different regimes, and nobody had named the regime variable.
Practical consequence:
unobserved:is the only workaround. Restructuring does not help — a consumer cannot escape by moving verdict reads into their own module, because the flag is process-wide.What would resolve it
Adding scope where today there is one process-wide bit — per-module at least, per-binding ideally. A fix would also need to cover
obs_gate_resolve_static_loads’s eager resolution of literalload_filetargets, the always-conservativeOP_IMPORTpath, and the constant-pool name scan (a program whose only "observer content" is the string"report"should not pay).The consumer pins this live as a
write/noread > 1.15arm with a planted fault, so when this is fixed upstream that gate fails and tells us to re-attribute and close G7.