Skip to content

trace: descriptor-assembled chunks arm their own history recording (#831) - #858

Merged
InauguralPhysicist merged 1 commit into
mainfrom
fix-831-descriptor-history-arming
Aug 5, 2026
Merged

trace: descriptor-assembled chunks arm their own history recording (#831)#858
InauguralPhysicist merged 1 commit into
mainfrom
fix-831-descriptor-history-arming

Conversation

@InauguralPhysicist

Copy link
Copy Markdown
Collaborator

Closes #831

g_trace_hist is set only by the bytecode compiler's source scan, so a descriptor assembled by vm_run_bytecode/sandbox_run containing prev/at opcodes recorded nothing and its own temporal reads answered null — unless the host program's text happened to contain a temporal query of its own, a relationship no bytecode producer (ouroboros codegen, iLambdaAi's vendored copy) can reason about. Not a regression: reproduces on v0.34.0; this is the older half split out of #830.

Fix

chunk_arm_temporal (src/chunk.c) — the assembler's twin of the compiler's temporal scan, per the sketch in #831. It steps the verified code stream reusing the op_verify_operands width table (call it only after chunk_verify accepts) and recurses into nested function chunks:

  • OP_INTERROGATE_NAMED kind 6 (prev) → arm that name
  • OP_INTERROGATE_NAMED_AT any kind → arm that name; kinds 3–5 (where/why/how) also set observer-state capture
  • OP_GET_NAME of state_at → wildcard, exactly as a source-level reference does

Pay-for-what-you-use: a chunk with no temporal opcode arms nothing, so temporal-free producers keep recording off (the cost constraint that kept this out of #830). Called from both descriptor sites: vm_run_bytecode and sandbox_run (where state_at is allowlisted, so sandboxed generated code legitimately reaches it).

Coverage

New suite [70f]tests/test_temporal_producers_unarmed.eigs, [70e]'s missing half: a host program with no temporal query anywhere in compiled source, so every answer exists only if the assembler armed the names. Checks: prev, what-at both sides of the line boundary, prev inside a nested function chunk, and a state_at reference (last, since it widens to the wildcard for the process).

Verified fail-without-fix: all 5 checks answer null with the fix stashed.

Gates

  • Release suite 3744/3744
  • ASan+UBSan with detect_leaks=1: 3742/3742, leak tally 0
  • make jit-smoke, make freestanding-check green

🤖 Generated with Claude Code

Copilot AI lite review requested due to automatic review settings August 5, 2026 09:10
)

g_trace_hist was set only by the bytecode compiler's source scan, so a
chunk assembled by vm_run_bytecode/sandbox_run containing the
history-reading opcodes recorded nothing and its own prev/at reads
answered null — unless the HOST program's text happened to contain a
temporal query, a relationship no bytecode producer can reason about.
Reproduces back to v0.34.0 (the non-regression half split from #830).

chunk_arm_temporal (src/chunk.c) replays the compiler's scan over the
verified code stream, stepping with the same op_verify_operands table
and recursing into nested function chunks: per-name arming for
OP_INTERROGATE_NAMED kind 6 (prev) and every OP_INTERROGATE_NAMED_AT,
observer-state capture for the where/why/how-at kinds, and the
wildcard on a GET_NAME of state_at. Called from both descriptor sites
after chunk_verify accepts, so a chunk with no temporal opcode arms
nothing and temporal-free producers keep recording off.

Suite [70f] (test_temporal_producers_unarmed.eigs) is [70e]'s missing
half: a host with NO temporal query anywhere — all 5 checks answer
null without the fix.

Closes #831

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@InauguralPhysicist
InauguralPhysicist force-pushed the fix-831-descriptor-history-arming branch from 544a4ee to a41806f Compare August 5, 2026 09:11
Copilot AI previously approved these changes Aug 5, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Ready to approve

The change is narrowly scoped, reuses the verifier’s operand layout for safe bytecode walking, adds targeted regression coverage (including nested-chunk recursion), and is consistent with the compiler’s established arming rules.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Fixes a long-standing gap where bytecode descriptors executed via vm_run_bytecode / sandbox_run could contain temporal-read opcodes (prev / … at …) yet still record no history (and therefore return null) unless the host program’s compiled source happened to contain its own temporal query. This aligns descriptor-assembled execution with the compiler’s temporal scan behavior so non-compiler producers (e.g., ouroboros codegen, vendored generators) get correct temporal semantics.

Changes:

  • Add chunk_arm_temporal() to replay the compiler’s temporal scan over verified assembled bytecode (including recursion into nested function chunks).
  • Invoke chunk_arm_temporal() from both vm_run_bytecode and sandbox_run so descriptors can enable/arm history recording based on their own content.
  • Add a new test suite [70f] to cover the “host contains no temporal query” case, including nested-function and state_at wildcard behavior.
File summaries
File Description
tests/test_temporal_producers_unarmed.eigs New regression test ensuring descriptors arm/enable history recording without any host-level temporal query.
tests/run_all_tests.sh Registers the new [70f] suite entry for CI/suite execution.
src/vm.h Exposes chunk_arm_temporal() alongside the chunk verifier API.
src/chunk.c Implements chunk_arm_temporal() by walking verified bytecode and arming names / observer-history capture; recurses into nested chunks.
src/builtins.c Calls chunk_arm_temporal() in vm_run_bytecode and sandbox_run after descriptor verification/build.
CHANGELOG.md Documents the fix and its impact/behavior (including pay-for-what-you-use intent and new suite coverage).
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 0
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Copilot AI review requested due to automatic review settings August 5, 2026 09:14
Copilot AI dismissed their stale review, a newer Copilot review was requested August 5, 2026 09:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Ready to approve

The change correctly arms temporal recording for verified descriptor chunks (including nested functions), adds targeted regression coverage, and cleanly limits overhead to chunks that actually use temporal opcodes.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

@InauguralPhysicist
InauguralPhysicist merged commit 194dfd3 into main Aug 5, 2026
19 checks passed
@InauguralPhysicist
InauguralPhysicist deleted the fix-831-descriptor-history-arming branch August 5, 2026 09:42
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.

vm_run_bytecode descriptors cannot turn history recording on, so their own prev of / at reads answer null (pre-#827, split from #830)

2 participants