Seal an incident
Sealing makes a permanent, checkable record of an AI incident case outside RepoOps. It sends ids, times, hashes and a pseudonymous developer handle to Evidence Rooms, which keeps the bundle privately and publishes the record on aisourceoftruth.com, or to the registry alone, which keeps only the bundle's hash. It never sends a name, an email address, prompt text or a note.
Watch it
Transcript
The walkthrough is silent. These are its captions, in order. Every value it shows is illustrative.
- 0:00Ids, times, hashes and a pseudonymous handle leave the machine
- 0:06Never a name, an email address, prompt text or a note
- 0:12RepoOps signs only statements about the bytes it sent
- 0:18The seal is stored on the case, with the registry link
- 0:24Run it again and only the guardrail goes. Both records are append-only.
The values in this video are illustrative; no real seal has been recorded yet. The fields and their order are the ones the seal-incident command sends.
How to
An AI incident case on the desktop app, and the settings for one destination on the machine that runs RepoOps. Sealing is off until they are set.
For Evidence Rooms: ROOMS_ORIGIN, ROOMS_PARTNER_KEY and ROOMS_SIGNING_JWK, a private P-256 key. For the registry alone: AISOT_REGISTRY_CLIENT_ID, AISOT_REGISTRY_CLIENT_SECRET, AISOT_REGISTRY_KEY_ID and AISOT_REGISTRY_SIGNING_JWK. Rooms wins when both sets are present.
- Register the Rooms signing key once.
Run
repoops seal-incident --register-key. It answers with the key id Rooms now knows. The registry needs no step here: its publisher key is registered on aisourceoftruth.com. - Read what would leave before anything does.
Run
repoops seal-incident <caseId> --dry-run. It prints the plan and sends nothing: the incident id, time and severity; the bundle's name, sha256 and size; the commit, the PR, the session id, the sha256 of the prompt, the model and the developer handle; and the agent trace's hash and turn count. Add--pr owner/repo#nfor the pull request that shipped the change, because a case does not record it. - Seal the case.
Run the same command without
--dry-run, or open the case page, choose Case record, then Evidence, and send Seal to an outside record, with the pull request field filled in if you have it. Each body is checked for names and email addresses before the first request. - Read the seal on the case.
The command prints the bundle sha256, the Rooms case and the registry link. On the case, the Outside record row says where and when it was sealed and links the registry record, and the timeline gains a sealed on entry.
- Send a guardrail after the fact.
Once the case records its remediation (the lesson, guard and fix PR), run the command again, or send Seal to an outside record once more: the Seal row says this Rooms case can still send its guardrail. On Evidence Rooms only the guardrail goes. A second bundle never does, because both services are append-only and would refuse it.
Use cases
An incident counsel or an auditor will ask about
- Situation
- A change an agent wrote caused an outage, and the case traces it to a commit, a PR and a session.
- You do
- Seal the case to Evidence Rooms with the PR named.
- You see
- Rooms holds the bundle and the agent trace as signed items in a room you can share, and aisourceoftruth.com holds a record of it nobody can quietly edit later.
An evidence pack with no case
- Situation
- You exported an evidence pack from another machine and want it on the record.
- You do
- Run repoops seal-incident --pack <file> --incident-id <id> --occurred-at <iso>, with --commit, --session or --model if you know them.
- You see
- The pack is the bundle. A pack that contains an email address is refused the same way a case is.
Expected outcome
Next step: The message names the missing setting, never a value. Set it on the machine that runs RepoOps and restart the app.
Next step: A body held an email address or a name the case holds. Look for it in the notes or a pack you passed; --developer takes a handle, never a name or an email.
Next step: It was sealed on the registry, or this machine now points at the registry. Only an Evidence Rooms seal can take a later guardrail.
Next step: Rooms has the case and has not published the registry record yet. Run the command again later; it sends no second bundle.
What else to consider
What leaves the machine
The incident id, time and severity; the bundle, a fixed projection of the case (base64 to Rooms, its sha256 only to the registry); the commit; the PR ref you pass; the session id; the sha256 of the prompt, read locally; the model; a developer handle; and, to Rooms only, the agent trace in the Agent Trace format, with per-turn token and tool counts and no tool arguments or prompt text. The case title goes to Rooms only, for its case name.
Never sent: a person's name, an email address, prompt text, notes, the free-text remediation action, the assignee, or attribution reasons.
The developer handle is pseudonymous, not anonymous
The handle is dev_ plus 16 hex characters derived from the email hash the case holds. It joins one person across incidents without naming them, but anyone who holds a candidate email can compute its hash and then the handle. Pass --developer with your own handle to send that instead.
Signing
On Evidence Rooms the first call carries no signatures. Rooms answers with upload statements naming its new case, and RepoOps signs each one only after checking that it names that case and the exact hash and size of the bytes it sent. On the registry RepoOps signs the exact body bytes with the registered publisher key. Secrets go out as headers or the token body and are never printed, logged or stored, and each origin must be https, except a loopback address.