Skip to content

fix(interactive): snapshot start State and startIntent before first await - #18

Merged
rockyshi1993 merged 1 commit into
mainfrom
fix/r04-start-input-snapshot-20261112
Nov 12, 2026
Merged

rockyshi1993 merged 1 commit into
mainfrom
fix/r04-start-input-snapshot-20261112

Conversation

@rockyshi1993

@rockyshi1993 rockyshi1993 commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • start() now takes a bounded canonical snapshot of caller-owned State and startIntent before its first await.
  • Checkpoint creation, the start-intent hash, and the Store writes use those copies. Mutating the caller's top-level fields or nested objects after the call does not change the Run.
  • Illegal State or startIntent is rejected by the same canonical JSON rules before putArtifact / createRun.
  • The two R04 regression tests are the same cases as Draft PR test(interactive): R04 pre-await State/intent mutation regression (expected fail) #17. This PR makes them pass. Do not merge both, or the tests land twice.

Not changed

  • No Program ABI, Store schema, CAS, Receipt, or Journal rule changes.
  • No public SDK surface change. adminTerminate, async Store, and terminal State projection are untouched.
  • CF-08 (compileInteractive option snapshot) is reproduced and left out of this diff.

Verification

Local Windows, Node 22.22.2 and Node 24.22.2. npm run verify is 371 pass / 0 fail on both. This is not the Ubuntu/Windows CI matrix and not a native Grok Host acceptance.


Note

Medium Risk
Changes run-creation timing for durable state and idempotency keys; behavior is narrowly scoped to start() with regression coverage.

Overview
start() now deep-copies caller state and startIntent synchronously, before the first await on program load, so post-call mutations cannot alter the initial checkpoint or start-intent idempotency hash.

Oversized initial state still fails closed with FK_I_CHECKPOINT_CAPACITY at snapshot time (before store writes). Two R04 regression tests assert persisted state and idempotent replay stay tied to the values at call time.

Reviewed by Cursor Bugbot for commit 452ac38. Bugbot is set up for automated code reviews on this repo. Configure here.

…wait

start() copied caller-owned State and startIntent only after
loadInteractiveProgram resolved. That await yields even when the loader
is already settled, so a caller could change both objects before the
Checkpoint and startIntentHash were created. Copy both with the existing
bounded canonical snapshot first, and preserve the initial-State capacity
error. Later Store writes use those copies.

Includes the R04 regression tests from PR #17.
@rockyshi1993
rockyshi1993 marked this pull request as ready for review November 12, 2026 05:24
@rockyshi1993
rockyshi1993 merged commit 606d055 into main Nov 12, 2026
3 of 10 checks passed
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.

1 participant