Skip to content

file_exists / ls / mkdir / getcwd / exe_path are untraced nondet reads — silently diverge under EIGS_REPLAY #585

Description

@InauguralPhysicist

Found while adding is_dir (#576) with the tape-first treatment: the older filesystem predicates in src/builtins.c are neither trace-recorded nor replay-blocked:

  • file_exists — fopen probe, plain return
  • ls — readdir listing
  • mkdir — returns a stat-based success bit (and mutates the fs)
  • getcwd, exe_path — process-environment reads

They sit in neither of docs/TRACE.md's two lists (wrapped N-record sources vs. loudly-non-replayable). Under EIGS_REPLAY they run live: a program that branches on file_exists of p replays against the current filesystem, not the recorded one — the same closed-world hole #471 closed for args, and the same class the (closed) #148 covered for proc_*. A tape recorded on one machine silently diverges on another.

Newly added fs reads are traced (is_dir #576, read_line #558 — both carry N records and replay deterministically), so the inconsistency is now visible side by side in the File I/O table of docs/BUILTINS.md.

Proposed: wrap the pure reads (file_exists, ls, getcwd, exe_path) with TRACE_NONDET_RET/TAKE+RECORD; decide mkdir (a write whose return is fs-dependent) either the same way or as a loudly-non-replayable builtin per the #148 convention. One replay test per builtin (record, mutate the fs, replay must serve the recorded answer — same shape as the #576 test in tests/test_replay.sh).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions