AGENTS.md
Rama main · réplica de lectura del repositorio original.
# SecondBox Development Rules
- `Sandbox` is the durable public resource. `Instance` is replaceable compute fenced to one Sandbox generation.
- The control plane is unprivileged. Only separately deployed SecondBox runners may use KVM, Firecracker, TUN/TAP, host cgroups, or host workspace paths.
- The privileged runner container receives the host's `/dev`, including consoles, seats, input, and DRM devices. The runner image must execute `secondbox-runner` directly as PID 1 and must not include or boot a private systemd, agetty, logind, or any process that touches host consoles, seats, or input devices. Such processes can claim the workstation host's VT, seat0, or DRM master and kill its desktop session.
- Runners establish authenticated outbound connections to the control plane. Application API credentials and runner credentials are separate authorities.
- PostgreSQL owns desired state, home assignments, generations, leases, profiles, audit, and reconciliation. Each runner's reflink-capable workspace root owns the Workspaces and Snapshots homed there. Immutable, digest-pinned execution assets are release inputs cached by runners.
- A running Sandbox never relocates. An operator may relocate a stopped, Snapshot-free Sandbox through the explicit relocation Operation; loss of an unbacked home-runner workspace filesystem still loses that Sandbox because PostgreSQL recovery alone is insufficient.
- Workspace persistence is reflink-only and runner-local. Image bytes may stream only through the operator-initiated stopped-Sandbox relocation Operation and are never persisted by the control plane. Do not otherwise stream image bytes, expose local paths, add copy fallbacks, or reconstruct an empty Workspace when local data is absent.
- Only the runner's WorkspaceStore resolves local paths. Compute backends receive an opaque provider-neutral Workspace attachment and must preserve its generation fence and exclusive writer lock.
- Firecracker is the supported production backend on KVM hosts and gVisor the supported backend on Linux amd64 hosts without KVM (Kubernetes nodes included); the Microsandbox backend is experimental. Backends are runner-wide-selected. Keep the provider-neutral compute port and its conformance suite, but do not add placeholder backends or fallback execution.
- Operators create every Profile explicitly or explicitly select release-owned standard bundles in `[standard_resources]`; the control plane has no silent Profile defaults. A Sandbox is pinned to the immutable Profile revision resolved at creation.
- Public contracts use provider-neutral SecondBox domain language. Firecracker, KVM, runner credentials, host paths, storage keys, fencing tokens, and backend references do not enter public schemas.
- Cross-resource references are logical strings. Do not add PostgreSQL foreign keys or CHECK constraints.
- Deployment identity, authority, integration selection, host paths, pinned assets, tenancy limits, and operator-owned retention are always explicit. Application code and static deployment templates must not default them. Deployment tooling derives fixed container-internal listeners and paths from the packaged deployment contract and renders them explicitly for processes; operators configure host publication and source paths. Code-owned tuning constants may expose optional, validated environment overrides. `secondbox-deploy init` may generate secrets and materialize the reviewed development topology, or values explicitly supplied by a production operator; generated authority is written to the manifest or referenced secret files and is never a silent runtime default.
- Do not catch, log, and swallow errors. Implement one intended path and fail explicitly when its prerequisites are absent.
- Keep exported names and error prefixes greppable and domain-specific. Remove replaced code instead of retaining compatibility paths.
- Run `just verify-generated`, `just test`, and the relevant contract, Compose, runner, or Firecracker suite before handoff. Run `just test-scenario` on a qualified host when a change touches the runner protocol, lifecycle reconciliation, or workspace durability.
- Project skills live in `.agents/skills/` (Codex) with symlinks in `.claude/skills/` (Claude). `secondbox-release` owns cutting, publishing, verifying, and retracting releases; `worklog` owns the shared session ledger.
- Read `.worklog/` in the primary worktree (today's UTC file and the most recent earlier file) at session start and append at hand-off, after any release step, and whenever you discover a host or process gotcha. Follow the `worklog` skill; the directory is git-ignored and must never be committed.
- Releases are cut only by pushing a `v*` tag on a merged `origin/main` commit after the release notes landed; `release-tag.yml` qualifies, stages and uploads on the self-hosted release runners and dispatches the publisher. Never run `release-upload` by hand.