Machine-First Debugging in Sigil
Sigil's debugger is not built around a human sitting in an IDE and poking at a live process.
It is built around the thing Sigil already assumes is central: a machine reading structured state, asking a better next question, and rerunning deterministically when needed.
The Shift
Traditional debugging often depends on a few loose tools:
- a stack trace
- ad hoc logs
- rerunning until the bug happens again
- an interactive debugger attached to one live process
That model is workable for a human, but it is lossy for an LLM. The model hides too much of the state the agent actually needs:
- what phase failed
- what the compiler thought the program meant
- what runtime world was active
- which exact expression failed
- how execution got there
- whether the same run can be reproduced exactly
Sigil now exposes those as first-class surfaces instead.
The Surfaces
The current debugger story is split deliberately:
sigil inspect validateshows canonical source and validation statussigil inspect typesshows solved top-level typessigil inspect worldshows the normalized runtime world for one envsigil inspect codegenshows the emitted TypeScript without writing artifactssigil run --jsonreturns structured runtime failuressigil run --json --traceshows execution flowsigil run --json --recordand--replaymake effectful runs reproduciblesigil testexposes the same debugging surface per test resultsigil debug runandsigil debug testprovide replay-backed stepping and watches
The point is not “more flags.” The point is that the debugging state is now owned by the language tooling instead of being reconstructed from informal logs.
Why Replay Matters
Replay is the part that makes the rest coherent.
Without replay, stepping and repeated inspection are always fragile:
- random values shift
- timer/process/network/file effects move
- the bad run may not happen again
With replay, the debugger can return to the same execution on demand. That means an LLM can:
- inspect the failing expression
- rerun the same execution with trace
- step through the same run later
- keep watches pinned across snapshots
This is a much better fit for agent workflows than “please reproduce the bug again while I add more logs.”
What An LLM Actually Does With It
A useful agent workflow is small and structured:
sigil run --json --trace src/main.sigil
sigil inspect world . --env test
sigil run --json --record .local/crash.replay.json src/main.sigil
sigil debug run start --replay .local/crash.replay.json --watch state.count src/main.sigil
That lets the agent answer four different questions without guessing:
- Did this fail in parsing, validation, typechecking, topology, or runtime?
- What exact Sigil expression failed?
- Was the active world correct?
- Can I step through the same execution again?
For tests, the shape is similar:
sigil test --record .local/tests.replay.json tests/
sigil debug test start --replay .local/tests.replay.json --test "tests/cache.sigil::cache hit returns cached value" --watch result.value tests/
The important part is that the test id, replay artifact, stepping snapshots, and watch values are all machine-readable and stable.
This Is Still A Human Tool
Machine-first debugging does not mean “humans are excluded.”
It means the authoritative debugging data is exposed in a form that machines can use precisely and humans can still read directly. A human can still inspect the same JSON, trace, replay artifact, or stepping snapshot. The difference is that Sigil no longer assumes debugging has to begin with human-only surfaces.
That is the broader Sigil pattern:
- canonical source instead of style drift
- explicit worlds instead of hidden runtime configuration
- replayable effects instead of ad hoc reruns
- exact expression blame instead of vague runtime ownership
Where The Details Live
This article is only the tour.
For the full debugging workflow, flags, JSON shapes, and examples, use:
- [language/docs/DEBUGGING.md](/sigil/docs/debugging/)
- [language/spec/cli-json.md](/sigil/spec/cli-json/)
- [language/docs/TESTING.md](/sigil/docs/testing/)