Skip to content

fix(store): isolate checkpoint file lists at write boundaries #2341

Description

@DeliciousBuding

Summary

UpsertRunCheckpoint retains and returns the caller's Files backing array. GetRunCheckpoint and snapshot helpers already copy on read, but those copies cannot prevent a writer from changing the stored pre-run evidence after a successful upsert.

Reproduced on b091863506538543203344be8f5bc7aae41cbcc3 with production code unchanged:

  • Input and result mutations change stored path/hash/size/content on Memory, FileStore and SQLiteStore (six backend/access cases).
  • An unrelated settings write followed by a real close/reopen preserves the accidental edits on both durable backends.
  • The real checkpoint-file handler returns changed after save / changed-hash instead of the originally saved evidence, including after replacing an existing checkpoint. These are local deterministic regressions, not a production incident or a real-model E2E claim.

Scope and ownership

One writer in an isolated task worktree. Allowed changes:

  • edge-server/internal/store/store_domain.go: detach the checkpoint file list at the input and result boundary.
  • edge-server/internal/store/checkpoint_ownership_test.go: repository isolation and durable-reopen regressions.
  • edge-server/internal/api/checkpoint_test.go: user-visible preview behavior.

Owner contract: docs/architecture/02-edge-server.md, Checkpoint and restore semantics. No wire interface changes are intended.

Invariants / negative constraints

Preserve metadata, file order, timestamp stamping, upsert replacement, missing-run errors, empty-list return shape and existing read behavior. Do not change persistence error policy, SQL/schema, retention, checkpoint restore/write-back, filesystem access, authorization, deployment or runtime configuration. Do not broaden this into a new storage abstraction or verifier.

Acceptance

  • Reproduce both writer ownership leaks on all three real backends and the real preview handler.
  • The same tests pass after the smallest ownership fix, including File/SQLite close/reopen.
  • Preserve nil/empty writer results and existing checkpoint/read/snapshot behavior.
  • Complete store/API tests on Windows and Linux race; vet/staticcheck; existing lifecycle checkpoint tests.
  • Required PR checks pass; merge, source-only documentation closeout and task branch/worktree cleanup.

Windows reproduction from edge-server:

CGO_ENABLED=0 go test -p 2 ./internal/store ./internal/api -run 'TestRunCheckpointWriteOwnsFiles|TestCheckpointPreviewRetainsSavedEvidence' -count=1 -v

The shell-specific environment assignment is separate on PowerShell. The checked-in regression source and red/green evidence are attached in the comments below. Fixed by #2342; source-only closeout does not imply a runtime rollout.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions