Summary
Add neutral acq snapshot / acq restore verbs that wrap a backend's native snapshot/restore primitive, so an agent's full context (process + memory + disk state) survives a planned reboot / recreate, and host resource bindings (vsock, volume, port) are re-plumbed at restore time. This replaces the earlier application-level, manifest-driven tar approach entirely.
Only backends whose native primitive supports stateful restore with host-resource rebinding are supported. msb qualifies today; sbx does not and is stubbed as unsupported.
Motivation / evidence
The trigger was an "agent sessions restored empty" report. Root cause: an application-scoped backup (the in-flight, unmerged Paseo backup/restore work in GSA-TTS/agentic-coding-patterns) snapshotted only $PASEO_HOME, while OpenCode stores transcripts in ~/.local/share/opencode/opencode.db (XDG_DATA_HOME) — outside that tree. Restored agent records pointed at session ids the new sandbox had never seen.
Investigating the fix surfaced two facts:
- No in-VM process/memory state survives
acq stop/reboot today — only sandbox config, ports, and mounted repos. So agent context is structurally lost on recreate.
- The vsock/SSH-agent forwarding route is create-time only (ADR-0021): the
--vsock route is never re-derived on resume, so after a host reboot the forwarded agent endpoint is dead and the only remedy today is acq rm + recreate.
Both are solved by the same msb primitive: msb snapshot create --full captures disk + memory + execution + device state (with a --guest-flush quiesce control), and msb restore <snap> --name <new> --vsock PATH:PORT[/stream|/dgram] --volume … --port … reactivates it while re-binding host resources at restore time. Restore is therefore both the context-recovery mechanism (P1) and the vsock/SSH re-plumb point (P2).
Why native, not a manifest
A hand-rolled, per-application manifest+tar layer would have to re-implement quiesce/WAL correctness, capture only disk-level state (never live process/memory), and could not re-plumb host transports. The native primitive does all of this, is already shipping in msb, and needs no new host-side script surface. The manifest track has been closed as superseded (GSA-TTS/agentic-coding-patterns#430, #431, #432, and the associated skill/workflow #428, #429).
Backend support policy
acq already declares per-backend capability flags (e.g. ACQ_BACKEND_SUPPORTS_SNAPSHOTS, currently 0 on both backends by choice, not inability) and gates optional adapter functions with command -v acq_backend_<fn> (as it already does for acq_backend_start, which is deliberately undefined on sbx).
- msb — supported.
msb snapshot create --full (local) + msb restore --vsock/--volume/--port. Full stateful restore with host-resource rebinding.
- sbx — unsupported / stubbed. sbx's
sbx template save/load is a disk-only, snapshot→template→fresh-boot model on the local runtime (memory/microVM checkpoint is --cloud-only), and it does not re-bind host vsock/volume/port on restore. It does not meet the stateful-restore contract, so acq exposes it as an explicit "not supported on this backend" stub rather than a degraded path. (No half-measures: a partial/disk-only degrade was considered and rejected.)
- smolvm / ppp — unknown. Treated as unsupported until a spike confirms a qualifying primitive.
Proposal
- Add
acq snapshot <sandbox> and acq restore <sandbox-name> [snapshot-name] verbs to the dispatch. acq itself re-plumbs host-resource bindings at restore: it re-derives the current SSH-agent --vsock route and asks msb to inherit validated source-local volume/port resources. Users do not pass --vsock, --volume, or --port to acq restore.
- Add
acq_backend_snapshot / acq_backend_restore to the adapter contract; implement for msb; leave undefined (or an explicit unsupported stub) for sbx; gate with command -v so unsupported backends fail clean with a clear message.
- Flip the msb capability flag to reflect that acq now surfaces snapshot/restore; keep sbx at unsupported.
- Have
acq restore re-derive the --vsock route so SSH signing survives reboot/recreate (closes the ADR-0021 gap) — tracked as a dedicated sub-issue.
Non-goals
- No application-level manifest/tar layer (superseded).
- No degraded/disk-only path on backends lacking stateful restore — unsupported means stubbed.
- Copy-on-write forking (
msb restore --forked, msb branch) is out of scope.
Acceptance
- On msb, agent context (including OpenCode session history) survives
acq snapshot → acq restore and acq recreate, and SSH signing works after restore without manual resource rebinding.
- On sbx,
acq snapshot/acq restore fail clean with an explicit "unsupported on this backend" message.
Sub-issues
All in GSA-TTS/agentic-coding-quickstart:
Superseded and closed in GSA-TTS/agentic-coding-patterns (manifest/tar track): #428, #429, #430, #431, #432.
Summary
Add neutral
acq snapshot/acq restoreverbs that wrap a backend's native snapshot/restore primitive, so an agent's full context (process + memory + disk state) survives a planned reboot / recreate, and host resource bindings (vsock, volume, port) are re-plumbed at restore time. This replaces the earlier application-level, manifest-driven tar approach entirely.Only backends whose native primitive supports stateful restore with host-resource rebinding are supported. msb qualifies today; sbx does not and is stubbed as unsupported.
Motivation / evidence
The trigger was an "agent sessions restored empty" report. Root cause: an application-scoped backup (the in-flight, unmerged Paseo backup/restore work in
GSA-TTS/agentic-coding-patterns) snapshotted only$PASEO_HOME, while OpenCode stores transcripts in~/.local/share/opencode/opencode.db(XDG_DATA_HOME) — outside that tree. Restored agent records pointed at session ids the new sandbox had never seen.Investigating the fix surfaced two facts:
acq stop/reboot today — only sandbox config, ports, and mounted repos. So agent context is structurally lost on recreate.--vsockroute is never re-derived on resume, so after a host reboot the forwarded agent endpoint is dead and the only remedy today isacq rm+ recreate.Both are solved by the same msb primitive:
msb snapshot create --fullcaptures disk + memory + execution + device state (with a--guest-flushquiesce control), andmsb restore <snap> --name <new> --vsock PATH:PORT[/stream|/dgram] --volume … --port …reactivates it while re-binding host resources at restore time. Restore is therefore both the context-recovery mechanism (P1) and the vsock/SSH re-plumb point (P2).Why native, not a manifest
A hand-rolled, per-application manifest+tar layer would have to re-implement quiesce/WAL correctness, capture only disk-level state (never live process/memory), and could not re-plumb host transports. The native primitive does all of this, is already shipping in msb, and needs no new host-side script surface. The manifest track has been closed as superseded (
GSA-TTS/agentic-coding-patterns#430,#431,#432, and the associated skill/workflow#428,#429).Backend support policy
acq already declares per-backend capability flags (e.g.
ACQ_BACKEND_SUPPORTS_SNAPSHOTS, currently0on both backends by choice, not inability) and gates optional adapter functions withcommand -v acq_backend_<fn>(as it already does foracq_backend_start, which is deliberately undefined on sbx).msb snapshot create --full(local) +msb restore --vsock/--volume/--port. Full stateful restore with host-resource rebinding.sbx template save/loadis a disk-only, snapshot→template→fresh-boot model on the local runtime (memory/microVM checkpoint is--cloud-only), and it does not re-bind host vsock/volume/port on restore. It does not meet the stateful-restore contract, so acq exposes it as an explicit "not supported on this backend" stub rather than a degraded path. (No half-measures: a partial/disk-only degrade was considered and rejected.)Proposal
acq snapshot <sandbox>andacq restore <sandbox-name> [snapshot-name]verbs to the dispatch. acq itself re-plumbs host-resource bindings at restore: it re-derives the current SSH-agent--vsockroute and asks msb to inherit validated source-local volume/port resources. Users do not pass--vsock,--volume, or--porttoacq restore.acq_backend_snapshot/acq_backend_restoreto the adapter contract; implement for msb; leave undefined (or an explicit unsupported stub) for sbx; gate withcommand -vso unsupported backends fail clean with a clear message.acq restorere-derive the--vsockroute so SSH signing survives reboot/recreate (closes the ADR-0021 gap) — tracked as a dedicated sub-issue.Non-goals
msb restore --forked,msb branch) is out of scope.Acceptance
acq snapshot→acq restoreandacq recreate, and SSH signing works after restore without manual resource rebinding.acq snapshot/acq restorefail clean with an explicit "unsupported on this backend" message.Sub-issues
All in
GSA-TTS/agentic-coding-quickstart:acq snapshot/acq restoreverbs +acq_backend_snapshot/acq_backend_restoreadapter functions (msb)acq restorere-derives the msb--vsockroute (SSH signing survives reboot)Superseded and closed in
GSA-TTS/agentic-coding-patterns(manifest/tar track):#428, #429, #430, #431, #432.