# The safe-implementation boundaries

Check each one before you report the work as done.

## 1. The server verifies each approval

The Approval Gate runs in the browser. Its `approval.granted` event says what the person clicked on their screen. It does not prove who clicked or which version they saw, so it cannot authorize a run on its own.

- The server builds the `ActionRequest` and stores it before the gate shows it.
- The server checks each decision: the request id and version match the stored request, the outcome is `granted`, the args were not edited in the browser, and this version has no grant yet.
- The person comes from the server's session. Do not read a user id from the request body.
- The server stores a receipt and returns its id. The browser passes it to the gate as `serverReceiptId`; the gate then reads Verified.
- The run checks the receipt again before it acts (`store.check`), and refuses when the request moved to a new version.

**Check:** send the approve call by hand with `requestVersion` changed. It must be refused (the example answers 409). Send the run call with a made-up receipt id. It must be refused (the example answers 403).

## 2. The server redacts secrets in traces

Tool inputs and outputs carry keys, tokens, passwords and connection strings. Progress Trace shows each tool input at Inspect depth.

- Run each frame through `redactTrace` on the server, before it goes to the browser, the event log or any log file.
- `redactSecrets` catches common shapes: bearer and basic credentials, provider keys (`sk-`, `sk_live_`, `ghp_`, `xoxb-`, `AKIA`), JWTs, PEM private keys, `password=` and `"token": "..."` pairs, and passwords in URLs. Add the app's own secret shapes to it.
- Keep secrets out of `ActionRequest.args` and the plan text: the person sees both, and both go into the log.

**Check:** run the flow, switch the trace to Inspect, and search the page and the stored log for the secret. It must not be there.

## 3. Change only what the task needs

- Add the registry files and the wiring the task asks for.
- Do not reformat files, reorder imports, rename things, upgrade or add dependencies beyond what `shadcn add` installs, or change lint, TypeScript, Tailwind or build settings.
- Do not edit `tokens.css` or the `*-core.tsx` files. Theme through a new CSS file; change behaviour through props.
- If the work seems to need a change to an existing file outside the plan you showed, stop and ask.

**Check:** `git status` and `git diff --stat` list only the files on your plan.

## 4. Leave the demo parts marked

The example route keeps its store in memory and names the person with a stub. Both are fine for a demo and wrong for real work. Keep their comments, and tell the person they need a database for the store and the app's auth for the person.
