Skip to content

fix(trace): args rides the tape as a nondeterminism source (#471)#522

Merged
InauguralPhysicist merged 1 commit into
mainfrom
fix/args-nondet-tape-471
Jul 9, 2026
Merged

fix(trace): args rides the tape as a nondeterminism source (#471)#522
InauguralPhysicist merged 1 commit into
mainfrom
fix/args-nondet-tape-471

Conversation

@InauguralPhysicist

Copy link
Copy Markdown
Collaborator

What

builtin_args returned argv directly, unwrapped — the last un-taped nondeterminism source reachable by a pure script, and a hole in the closed-world invariant behind deterministic replay. A program that branches on args recorded a tape under one invocation and silently diverged when replayed under a different argv. This is the exact class the #408 task layer's chaos-mode --seed N scheduling would hit (seeds arrive via CLI, liferaft's --seed N pattern).

Fix

The recorded argument list now rides the tape as one N record; replay serves it regardless of the live argv.

Because args builds its list before returning, it uses the TRACE_NONDET_TAKE / TRACE_NONDET_RECORD pair rather than TRACE_NONDET_RET — under replay the early TAKE short-circuits before the list is built, so the live construction is neither run nor leaked (the abandoned-value trap the extend-vm checklist warns about). The tape already round-trips a list of strings (parse_value_p, src/trace.c:868), so no serialization work was needed.

Verification

  • tests/test_replay.sh: record under A B, replay the same script under X Y Z, assert the recorded args win — plus a live (no-replay) run under X Y Z that prints ["X", "Y", "Z"], proving the tape actually overrides rather than coincidentally matching.
  • Manual: EIGS_TRACEN args=["A", "B"]; EIGS_REPLAY under X Y Z["A", "B"].
  • Full suite green release AND ASan (detect_leaks=1): 2689/2689, 0 failed, no leak-tally increase.

Docs

  • docs/TRACE.md: new Process category listing args, and a note that value-building builtins use the TAKE/RECORD pair.
  • CHANGELOG.md: entry under [Unreleased] → Fixed.

Closes #471

🤖 Generated with Claude Code

builtin_args returned argv directly, unwrapped — the last un-taped
nondeterminism source reachable by a pure script, and a hole in the
closed-world invariant behind deterministic replay. A program that
branched on `args` recorded a tape under one invocation and silently
diverged when replayed under a different argv — the exact class the
#408 task layer's chaos-mode `--seed N` scheduling would hit.

The recorded argument list now rides the tape as one N record and
replay serves it regardless of the live argv. Because `args` builds its
list before returning, it uses the TRACE_NONDET_TAKE / TRACE_NONDET_RECORD
pair (not TRACE_NONDET_RET): under replay the early TAKE short-circuits
before the list is built, so the live construction is neither run nor
leaked. The tape already round-trips a list of strings (parse_value_p),
so no serialization work was needed.

Regression: tests/test_replay.sh records under `A B`, then replays the
same script under `X Y Z` and asserts the recorded args win (and that a
live run under `X Y Z` differs, proving the tape actually overrides).
docs/TRACE.md gains a Process category and the TAKE/RECORD-for-builders
note; CHANGELOG under Unreleased.

Full suite green release + ASan (leaks on), 2689/2689, no leak-tally
increase.

Closes #471

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@InauguralPhysicist InauguralPhysicist merged commit d4d57b1 into main Jul 9, 2026
17 checks passed
@InauguralPhysicist InauguralPhysicist deleted the fix/args-nondet-tape-471 branch July 9, 2026 22:20
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.

trace: args builtin is an untaped nondeterminism source (closed-world hole for replay)

1 participant