Skip to content

isb 3.2.0: every sandbox can expire, and isb serve reaps expired ones outside orgs too - #71

Merged
knowsuchagency merged 4 commits into
mainfrom
sandbox-optional-expiry
Oct 26, 2026
Merged

knowsuchagency merged 4 commits into
mainfrom
sandbox-optional-expiry

Conversation

@knowsuchagency

Copy link
Copy Markdown
Contributor

Abandoned sandboxes now clean themselves up. Titan's disk kept hitting 85%: 41 plain sandboxes in incus' default project had no expiry, and isb serve's reaper only looked inside orgs.

What changes

  • expires: on any sandbox spec (24h, 7d, never), plus isb create --expires. It is stored as user.isb.expires_at (unix seconds, or never).
  • Default: 7 days for a plain sandbox. With --org, the org's sandbox_expiry (24h). Applied by the CLI and isb rpc (the Python and TypeScript SDKs) when isb creates the sandbox.
  • A lease: each isb up / create --ensure renews the deadline. It never shortens a later one, and never adds one to an instance that has none.
  • The reaper now takes expired sandboxes in every incus project, plain ones included. It still never touches stack replicas, builds, or anything without the key. Named volumes stay, as with isb rm.
  • isb ls gains an EXPIRES column, and isb expiry NAME --in D | --by D | --never changes it.
  • sandbox_create also reads the spec's expires. Through the daemon, never is still refused and the 30-day cap stays.

Not affected

  • Sandboxes that exist today have no key, so they are never reaped, and an up does not add one.
  • The Rust API, isbx and the stack controller set no default.
  • An isb serve or incus upgrade does not touch existing sandboxes either.

Verified

  • scripts/check.sh: fmt, clippy -D warnings, the tests, docs, the ratchet. SDK types regenerated.
  • 19 host checks against titan's incusd: the default, renewal, never, no shortening, isb plan --exit-code staying quiet, sandboxes from the old isb, and bad values refused.
  • A reaper test in a throwaway VM with its own incusd and isb serve. It reaped expired sandboxes in default and in an org, and kept the never, 7-day and no-deadline ones and the named volume.

Before relying on it

Tool containers that a script recreates (for example sume-cli) need expires: never in their spec.

https://claude.ai/code/session_01SqR3QhYxi5hybLoCwjddgp

… serve

A sandbox spec gains `expires` (`24h`, `7d`, or `never`), and
`isb create --expires`. isb keeps the deadline on the instance as
user.isb.expires_at, and isb serve's reaper now deletes expired sandboxes
in every incus project, plain ones in `default` included, not only orgs.

- Default: 7 days for a plain sandbox, the org's sandbox_expiry with
  --org; applied by the CLI and isb rpc (Python, TypeScript) when isb
  creates the sandbox. The Rust API, isbx and the stack controller set
  none (EnsureOptions::default_expiry is None by default).
- A lease: each isb up / create --ensure renews it, never shortens it,
  and never adds one to an instance without a deadline, so existing
  sandboxes are untouched.
- isb ls shows EXPIRES; isb expiry NAME [--in D | --by D | --never].
- sandbox_create takes the spec's expires too; isb serve still refuses
  never and caps at 30 days.
- Named volumes stay, as with isb rm.
- To stay under the ratchet: ReadyCheck to spec/ready.rs, the name
  helpers to plan/names.rs, update_instance to sandbox/update.rs,
  sandbox_extend to daemon/sandboxes.rs, ls and prune to the CLI's
  instances.rs.

Claude-Session: https://claude.ai/code/session_01SqR3QhYxi5hybLoCwjddgp
# Conflicts:
#	scripts/ratchet.txt
@knowsuchagency
knowsuchagency merged commit 1d5f9d4 into main Oct 26, 2026
20 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