writ gate
Observe model API traffic from an external agent.
writ gate <file> [flags]The gate is a local model API relay. It sends each admitted model request to the configured provider. It records model turns and provider-reported usage.
The external harness still owns its model loop and its tools. The gate does not enforce tool calls, tool results, tool effects, or remedies.
The provider API key stays in the registrar. The agent receives a run token and the local base URL.
| Flag | Purpose |
|---|---|
--addr <address> |
Set the local address. The default is localhost:8787. |
--set <name>=<value> |
Give a placeholder a value. |
--config <path> |
Use the engagement configuration at this path. |
--idle-timeout <duration> |
End the session after this quiet period. There is no default timeout. |
--allow-partial |
Accept a model-traffic record when the plan contains unsupported clauses. |
The address must resolve to the local machine. The gate does not serve a remote address.
Check coverage first
Section titled “Check coverage first”A writ must contain a grant. The gate cannot enforce any grant. Therefore, a valid writ has partial coverage at this boundary.
Check the plan before you start the gate:
writ plan traffic.yaml --target gateThe plan marks each unsupported grant, result check, effect check, cost bound,
completion check, and remedy. writ gate prints the unsupported rows and stops
unless you add --allow-partial.
Use --allow-partial only when the model-traffic record is sufficient:
writ: model-trafficmandate: "Observe the model traffic for the support task."
grants: - tools: { names: [support.search, support.reply] }
bounds: iterations: 20The gate can enforce the model iteration bound. It records the unsupported
tools grant. It does not apply that grant to the request.
--allow-partial does not make an unsupported clause enforceable. It records
the unsupported path in the issuance entry.
The relay has two fixed operational guards. It stops after 15 minutes. It also
stops after provider-reported usage reaches $1.00 at the configured prices.
It cancels an active provider request at the 15-minute deadline.
These guards are part of the gate process. They do not apply an authored
cost, wall_clock, or remedy clause. Every operational bound response stops
the relay.
Start the gate
Section titled “Start the gate”-
Set the provider API key that the engagement configuration names.
-
Start the gate.
Terminal window writ gate traffic.yaml --allow-partial -
Copy the gate URL and token from standard error.
gate: http://localhost:8787 (anthropic protocol)token: wrt_run_01J9X4... -
Give the URL and token to the agent process.
For an Anthropic client, use the token as the API key. Set the base URL to the printed gate URL.
For an OpenAI client, use the token as the API key. Set the base URL to the
printed URL with /v1 at the end.
The gate replaces the run token with the provider API key. It never sends the run token to the provider.
Request handling
Section titled “Request handling”The gate handles each request in this order:
- It checks the run token.
- It checks the local endpoint.
- It checks the operational session limits.
- It checks that the body is one JSON object.
- It changes the requested model to the configured model.
- For an OpenAI event stream, it requests a usage report.
- It records admission and counts one model turn.
- It sends the request to the provider.
- It relays the provider response.
- It records the provider usage against the admission entry.
The gate leaves tool definitions, tool calls, and tool results unchanged. A tool outside a writ grant still crosses this boundary.
The gate supports normal JSON responses and event streams for the Anthropic Messages protocol and the OpenAI Chat Completions protocol.
Usage records
Section titled “Usage records”The gate records the token counts that the provider returns. It marks the usage check as failed when the report is missing, incomplete, or invalid.
Provider-reported usage is not complete measured cost evidence. The gate plan therefore marks an authored cost bound as unsupported. Do not use a gate record as proof of complete model spending.
The fixed $1.00 operational guard uses the same provider report. Missing usage can make that guard undercount spend. Treat it as a relay safety stop. Do not treat it as proof that the authored cost bound held.
Unsupported controls
Section titled “Unsupported controls”The gate does not do these things:
- It does not remove a tool definition.
- It does not stop a tool call.
- It does not reject a tool result.
- It does not see or verify a tool effect.
- It does not apply an authored remedy.
- It does not apply an authored cost or wall-clock bound.
- It does not apply an organization policy.
Use a native attached writ when its capability plan covers the needed tool
controls. Use writ issue when Writ must own the model loop, tools, verified
worktree effects, and completion checks.
End the session
Section titled “End the session”Press Control-C to end the session. An idle timeout can also end it.
The record ends with gate session ended. An operational limit that halts the
gate gives exit code 1. An unsupported plan or invalid writ gives code 2. A
configuration error gives code 3.
Read the result with writ review <name>.