Skip to content

feat(acq): acq snapshot/restore verbs backed by native backend primitives (msb; sbx unsupported) #493

Description

@mogul

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:

  1. 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.
  2. 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

  1. 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.
  2. 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.
  3. Flip the msb capability flag to reflect that acq now surfaces snapshot/restore; keep sbx at unsupported.
  4. 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.

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