What "execution is data" looks like on disk.
{
"version": 3,
"programPath": "fib.penc",
"programHash": "sha256:abc...",
"pausedAtIP": 42,
"pausedAtMs": 1716480000000,
"state": {
"ip": 42,
"valueStack": [...],
"frames": [
{ "bindings": { "x": { "tag": "int", "v": 10 } } }
],
"effects": [...],
"timeOverride": null,
"noReplay": false
}
}
{
"ip": 3,
"invocationCount": 0,
"effect": "print",
"recordedValue": { "tag": "unit" },
"status": "committed",
"eventName": "approval" // only for wait_for,
"waitUntilMs": 1716480060000 // only for wait_until
}
Snapshot v3 is NOT migratable from v2. Reasons:
nodeId; v3 keys by bytecode ip.If you have a v2 snapshot you need to keep going: re-run from source with Phase 3 binaries (don't try to resume).
JSON is verbose, but it makes snapshots:
cat foo.penz | jq .cp foo.penz bar.penz creates a real forkEvery snapshot stores the sha256 of its .penc. On resume, the runtime verifies the bytecode hasn't changed. Mismatched hash → resume refused with a clear error. (Phase 4 "live editing" will lift this restriction in controlled ways.)