# Spool agent instructions

## Run it locally

Follow the public first-run instructions:

Use Node 22 or later and git, on macOS, Linux or Windows with WSL2. Install Node from https://nodejs.org/en/download if needed; it must already be on PATH to start rer. Install public rer once per computer with `curl -fsSL https://runeditrun.com/install.sh | sh` or `npm install -g @runeditrun/rer`. rer then supplies the declared Node 22.20.0 and pnpm 10.12.4 pins. The public first-run path matches `/run`:

```sh
git clone https://github.com/just-every/run-spool.git spool
cd spool && rer dev
```

In an existing checkout, run `rer dev`. It installs dependencies and prepares the owner when needed. `rer install` and `rer setup` remain available separately. Use `rer describe` for supported maintenance commands; export before destructive reset and import only into an empty destination.

Fresh `rer dev` chooses `owner@spool.test` for the documented `spool` folder (`owner@<sanitized-folder-name>.test` elsewhere) without prompting, including with non-TTY input, and preserves an existing owner. Explicit `rer setup` prompts for missing required answers only with interactive stdin and without `--json` or `--non-interactive`. Otherwise use a private JSON file such as `{"OWNER_EMAIL":"you@example.com"}` at the ignored `.rer/local/setup-answers.json`, mode `0600`, and run `rer setup --answers .rer/local/setup-answers.json --non-interactive` from the Spool checkout. The path must be relative and contained inside that checkout; absolute paths, traversal, symlinks and shared hard links are refused. Saved answers are reused. Do not put addresses or secrets in shell arguments. Setup applies local migrations, claims or preserves the one owner, opens the owner without email and stops its temporary app.

Dev stays in the foreground with TTY output; non-TTY output returns once ready and leaves it running in the background. `--foreground` and `--detach` override this choice. Stop it with `rer dev --stop` (or Ctrl+C in the foreground). It prints its health-ready URL, `RER_SIGNED_IN` and a private `RER_OPEN` link for this computer. Local development reads **Spool Dev**; `rer demo` reads **Spool Demo** and uses disposable `.rer/demo` state with sample data. Mail is silently suppressed; there is no injected bar or mailbox viewer. Never share `RER_OPEN`: its `rer-dev` fragment value gates owner sessions and dev agent reads, including requests through proxies or tunnels. Reset retires the gate. `--as member` and `--as signed-out` select another local persona.

With rer dev v2 (pinned rer 0.2.25), dev-minted ingest and deploy grants work against the local entry without the private dev gate. Ingest can only send events to its project; deploy can only register releases and upload maps for its project. Read-only dev agent grants still require the gate. Privately extract only the `rer-dev` fragment value from `RER_OPEN` into `SPOOL_DEV_KEY` for trusted local agent CLI/MCP use; the CLI sends `x-rer-dev-key` only to loopback. Invoke the CLI by its absolute path inside the Spool checkout when working from an app repository. Never give the gate to a browser app or embed it in SDK configuration, source, shared files or build output. Browser capture needs its exact origin allowed, plus its ingest key. The deployed entry refuses every dev-minted grant. Sign in there and create fresh grants for that installation. Private archives must never export project grants, including dev-minted grants. See docs/capture.md for scopes and docs/WITH-YOUR-AGENT.md for private agent setup.

Stop dev before deploy, verify, reset or data transfer. Reset is destructive to the displayed local installation inventory. Export reads a stopped local installation; import requires an empty destination and creates no owner or project grants. Fresh browser restore is available from `/setup` before project creation; browser-downloaded private archives need `chmod 600` before CLI import. Hosted removal is `rer deploy --remove --yes` (add `--environment <name>` to select the deployed environment; default `production`) from the original deploying checkout with its retained private deployment receipt. Use the deploy dry run to build and validate locally; it makes no provider request. Run `rer describe` for other supported commands and flags.

## Product and source boundaries

Spool is a local-first JavaScript, Python and Go evidence product with one owner identity and isolated projects. `src/**` is authoritative. Retained Base and family source records provenance; never regenerate or re-export product code over the application. Keep lowercase API and asset paths, package scope/name, seed ID, and edition/source identities stable.

Every private API handler must enforce the current owner session or its exact project grant itself, including direct transport calls; a route guard alone is insufficient. The HTTP dispatcher in `src/base/dispatch.ts` selects handler ownership but does not authenticate requests or catch failures. Keep actual Worker handlers and named exports in `src/server.ts`. Keep secrets in server-only modules. There are no private TanStack Start server functions; if one is added, use a server-only module and a dynamic import inside its handler, then prove unauthenticated direct transport is rejected.

First-owner setup claims the native owner through Base operator-auth at `/auth/bootstrap` with the private setup token, then uses the private one-click local owner entry. An already claimed installation keeps its owner; migration `0004_operator_auth.sql` provides the `oa_bootstrap` claim ledger. Preserve the one-owner policy and single setup model. Managed first-owner claim and editor integration live in `src/editor`. Keep the signed claim route before the auth dispatcher and preserve its additive claim ledger. The optional editor config must recheck native owner authority; project grants cannot authorize it. Do not add a second secret, identity, or setup manifest model.

Scrub allowed event fields before persistence and review outbound evidence for residual personal data. Ingest grants authorize only their project ingest path. Agent grants are read-only and exact-project scoped. Owner writes require same-origin checks. Keep browser-origin policy project-scoped and preserve its ingest-only use. No captured telemetry executes commands or invokes external models.

Owner archives include private maps and browser-origin policy but exclude owner sessions and project credential grants. Restore requires an empty destination and does not create an owner or grants; preserve native archive v1/v2 compatibility and the shared Base portability engine. Retention is manual: preserve the visible cutoff, occurrence tombstones and deduplication horizon. BASE-DATA-003 owner-only project erasure is implemented on Base main's erasure helper (see docs/PROJECT-ERASURE.md); preserve every cascade, anonymised audit, receipt, restore-fence, five-minute and UI requirement in CONTRACT.md and ACCEPTANCE.md, and declare any new project table in `src/domain/erasure/declaration.ts`. Never report retention as completed project erasure. Source-map storage remains bounded to 20 flat maps of 256 KiB per project; R2 or warehouse storage is a future measured choice.

Setup, dev, verify and deploy dry run are local operations. Never infer deployment, provider, team, complete-capture or release acceptance from local source checks or tests. Actual owner-account deployment requires separately authorized account inputs and mail sender configuration. See [TARGET.md](TARGET.md), [CONTRACT.md](CONTRACT.md), [ACCEPTANCE.md](ACCEPTANCE.md), [OPERATIONS.md](OPERATIONS.md) and [HANDOVER.md](HANDOVER.md) for current boundaries and evidence.

Spool declares its own fonts (self-hosted Zilla Slab, IBM Plex Sans and IBM Plex Mono) in `public/fonts/fonts.css`, linked by `src/base/font-head.ts`. Both are product-owned and outside the Base copy records; the root head, the landing, docs and sign-in pages, and native `/auth/*` documents (through `fontDocumentResponse`) share them, while tokens and components live in `public/theme/spool.css`, so a Base refresh must not bring back Base's Outfit default.

`scripts/delivery/base/packaging.json` is product-owned policy over the pinned Base exporter. Regenerate the setup digest and producer workflow when policy or manifest bytes change.
