Skip to content

fix(ateom): refuse a restore from the pre-per-volume durable layout - #265

Merged
teemow merged 3 commits into
giantswarmfrom
fork/263-refuse-old-layout-restore
Oct 11, 2026
Merged

teemow merged 3 commits into
giantswarmfrom
fork/263-refuse-old-layout-restore

Conversation

@teemow

@teemow teemow commented Oct 11, 2026

Copy link
Copy Markdown
Member

Problem

On the 1.8.0 line (since 1.8.0-rc.6, which carries agent-substrate#2110 through #260), a restore of a gVisor snapshot written in the pre-agent-substrate#2110 layout reports no error and brings the actor up with an empty /data: the Go ADK runtime then fails with no such table: app_states, the claude Harness with Harness runtime execution failed. The old layout keeps every durable-dir volume in one durable-dir.tar, which the restore no longer reads; it skips each missing durable-dir-<volume>.tar as a volume added since the snapshot. A missed snapshot reset therefore loses the sessions' data without a word.

Proposed solution

The carried, upstream-ready commit of agent-substrate#2462 (git cherry-pick -x 11a6bc4f): untarDurableVolumes refuses a restore directory that holds durable-dir.tar before it extracts anything, with FailedPrecondition "snapshot written before the per-volume layout; re-snapshot from a running actor or reset the golden snapshot". The Resume fails and ate-api crashes the actor with that message (handleAteletError: not Unavailable, Canceled or DeadlineExceeded), so it stays CRASHED with the cause instead of running empty. Adapted to the line: the micro-VM hunks are dropped, since the line's micro-VM ateom still writes and reads the single durable-dir.tar (agent-substrate#2283 is after the pin). A second commit adds the FORK.md row.

Acceptance criteria

  • A restore of an old-layout gVisor snapshot fails with the error naming the layout; the actor does not come up with an empty /data.
  • TestUntarDurableVolumesRefusesLegacyLayout restores an old-layout archive (one durable-dir.tar with <volume>/... entries) and asserts the refusal, its code and the untouched volume directory; go test -race ./cmd/ateom-gvisor/ ./cmd/ateom-microvm/ passes. The e2e suite has no way to plant a snapshot written by an older build, so the unit test at the restore boundary is the closest level.
  • Rebase-merged as one commit per change, with its FORK.md row.

Closes #263

This pull request was written by an agent.

Both the gVisor and the micro-VM ateom snapshot each durable-dir volume
as its own durable-dir-<volume>.tar, and a restore skips a volume whose
tar is missing, since it may have been added to the template after the
snapshot. A snapshot written before that layout holds
every volume in the single durable-dir.tar instead, which nothing reads
any more: the restore reports success and the actor comes up with empty
durable volumes, losing its data without an error. A workload that keeps
its state there fails later with unrelated symptoms (a missing database
table, a failed first turn).

Refuse such a restore. A checkpoint no longer writes durable-dir.tar, so
its presence in the restore directory marks the old layout: the restore
now fails with FailedPrecondition, "snapshot written before the
per-volume layout; re-snapshot from a running actor or reset the golden
snapshot", before anything is extracted, and the actor crashes on the
failed Resume instead of running with empty volumes.

Signed-off-by: Timo Derstappen <teemow@gmail.com>
(cherry picked from commit 11a6bc4, agent-substrate#2462;
the micro-VM hunks are dropped: on this line the micro-VM ateom still
writes the single durable-dir.tar, which its restore reads)
@teemow
teemow requested a review from a team as a code owner October 11, 2026 10:22
Signed-off-by: Timo Derstappen <teemow@gmail.com>
Signed-off-by: Timo Derstappen <teemow@gmail.com>
@teemow
teemow merged commit eb73a7f into giantswarm Oct 11, 2026
17 checks passed
@teemow
teemow deleted the fork/263-refuse-old-layout-restore branch October 11, 2026 11:09
teemow added a commit that referenced this pull request Oct 11, 2026
The step from 1.7 to 1.8.1 converts each actor's 1.7-layout durable
snapshot on its first resume (#277) and takes every golden written in an
older layout again on the new workers, a create during the re-take
answering Unavailable and succeeding on retry (#282). It needs no
snapshot reset and no manual step.

The snapshot reset runbook says so and stays the remedy for a corrupted
snapshot store only. The rolling upgrade runbook gains the 1.7 to 1.8
step note with its floor 1.8.1: 1.8.0 refuses a 1.7 restore (#265).
FORK.md's layout row points at the step instead of the reset.

Refs #271, #272
teemow added a commit that referenced this pull request Oct 12, 2026
The step from 1.7 to 1.8.1 converts each actor's 1.7-layout durable
snapshot on its first resume (#277) and takes every golden written in an
older layout again on the new workers, a create during the re-take
answering Unavailable and succeeding on retry (#282). It needs no
snapshot reset and no manual step.

The snapshot reset runbook says so and stays the remedy for a corrupted
snapshot store only. The rolling upgrade runbook gains the 1.7 to 1.8
step note with its floor 1.8.1: 1.8.0 refuses a 1.7 restore (#265).
FORK.md's layout row points at the step instead of the reset.

Refs #271, #272
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.

restore: a pre-#2110 snapshot comes up with an empty /data, not refused

1 participant