Files
sand-boxer/docs/ttl.md
tegwick df658e7ef9 feat: TTL enforcement and operational hardening (SAND-WP-0009)
Add TTL parser, expires_at on create, extend_ttl and expire/reap APIs,
activity-core integration doc, repo classification, registry refresh,
HTTP parity, and 69 tests.
2026-06-24 12:44:04 +02:00

65 lines
1.6 KiB
Markdown

# Time-to-live (TTL)
Disposable-by-default sandboxes — SAND-WP-0009.
## Semantics
Each ready sandbox has:
| Field | Meaning |
|-------|---------|
| `ttl` | Active duration string (e.g. `4h`) |
| `expires_at` | UTC timestamp when the sandbox should be reaped |
On `create`, TTL comes from `SandboxCreateRequest.ttl` or the profile
`ttl.default`, capped at `ttl.max`. Anchor is `ready_at`.
Duration format: positive integer + unit — `s`, `m`, `h`, `d` (e.g. `30m`, `4h`).
## extend_ttl
Extend a live sandbox (`ready` or `active`):
```bash
sandboxer extend-ttl <sandbox_id> --duration 2h
```
HTTP: `PATCH /v1/sandboxes/{id}/ttl` with `{"duration": "2h"}`.
Extension adds to the current `expires_at` (or now if already past). Total lifetime
from `ready_at` cannot exceed profile `ttl.max`.
## expire / reap
TTL reap is distinct from host inventory `reap-stale`:
| Command | Purpose |
|---------|---------|
| `sandboxer expire` | Sandboxes past `expires_at` or profile `ttl.idle_reap` |
| `sandboxer reap-stale` | Orphan host resources vs store inventory |
```bash
sandboxer expire # dry-run (default)
sandboxer expire --apply # mark expired, destroy
```
HTTP: `POST /v1/sandboxes/expire?apply=true`
Flow on `--apply`:
1. Transition to `expired` (State Hub milestone)
2. `destroy` (idempotent teardown)
## Profile fields
```yaml
ttl:
default: 4h
max: 24h
idle_reap: null # optional; reap when updated_at + idle_reap elapsed
```
## activity-core
Scheduled jobs should invoke `sandboxer expire --apply` (or HTTP equivalent).
See `docs/integrations/activity-core.md`.