Skip to content

#915 embed contract: a linked-runtime embedder that never runs compile_ast gets a silently-closed observer gate #1038

Description

@InauguralPhysicist

Found by the v0.41.0 consumer bump: ouroboros's AOT runtime (aot_rt.h) links the EigenScript runtime directly and drives observer slots without ever running compile_ast — so nothing arms obs_needed, the linked bookkeeping returns early at eigs_obs_gate_open(), and every predicate silently answers from an empty window (t27_observer: VM impr=1, AOT all-zeros). This is the silent-wrong shape the gate's header forbids, on the seam the #1034 loop's OBS_BUILTINS-rejection reasoning named ("a C embedder running an assembled chunk with no name in any pool") — now demonstrated by a real consumer rather than hypothesized.

The eigs_eval_string/eigs_eval_file paths are safe (they force the gate — verified in round 16 of the loop). The hole is embedders that BYPASS eval and drive runtime internals directly.

Fixed on the consumer side in ouroboros (one eigs_obs_enable() in aot_boot). What this issue asks for upstream:

  1. docs/EMBEDDING.md: add the contract line — an embedder that executes code through any path other than eigs_eval_* must call eigs_obs_enable() (or accept a dead observer). It is the one sanctioned arming path and is already exported (eigenscript.h:1094).
  2. docs/OBSERVER.md Known residual: this is the concrete instance of the "descriptor/embedder pre-call history" family (#915 residual: a descriptor (vm_run_bytecode/sandbox_run) reading HOST observer state answers a rest value when the gate is closed #1027) — cross-reference it.
  3. Optional hardening to evaluate: an eigs_open()-level default-armed mode, disarmed only by the compile-time verdict — which would make the closed gate opt-in-by-evidence for every entry path instead ofdefault-closed for paths that never compile. That inverts today's conservative direction for embedders and deserves its own design pass, not a drive-by.

Repro: build any observer-using program with ouroboros aot/build.sh at pin >= v0.41.0 without the aot_boot fix; compare against the VM arm.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions