Son of Anton Docs
Operator

Operator API

The unmerged parity Worker's route-specific auth, response envelopes, reports and mutation contracts.

Branch boundary

This reference describes son-of-anton-operator-parity/cloudflare/ on unmerged feat/greptile-operator-parity. It is not the public API of the deployed-engine lineage, son-of-anton-review on feat/cloudflare-native. Native ingress serves health and GitHub webhooks, not these operator routes.

The engine's separate Node dashboard exposes GET-only snapshot, PR and trace routes. Its /operator/api/trace?id=... and /operator/api/trace-stats are not parity Worker routes. See Dashboard for the Node surface.

Sources: parity cloudflare/src/worker.js:93-157; engine cloudflare-native/src/ingress.js:264-273, src/operator-dashboard.js:639-687.

Authentication

Send Authorization: Bearer <token>. The parity Worker's token resolver prefers SON_OF_ANTON_<NAME> over legacy GILF_<NAME>, using nullish fallback. An empty canonical value does not fall through to the legacy value. This is not a general ANTON_ alias for engine settings.

Legacy variableAccepted route class
GILF_OPERATOR_READ_TOKENOrdinary operator GET routes, except /operator/api/keys and descendants
GILF_OPERATOR_ADMIN_TOKENKey management including GET; POST queue repair; PATCH repo config; non-GET memory/settings/SCM
GILF_OPERATOR_COMMAND_TOKENPOST command creation
GILF_OPERATOR_BRIDGE_TOKENPATCH command updates; GET command list/detail
GILF_QUEUE_ADMIN_TOKEN/queue/jobs, /queue/stats
GILF_QUEUE_ENQUEUE_TOKEN/queue/enqueue
GILF_QUEUE_WORKER_TOKEN/queue/claim, /queue/ack, /queue/fail, /queue/renew

Missing or mismatched static tokens return 401 with ok: false, error: unauthorized. Token classes are not hierarchical: the admin token is not automatically valid for command creation or ordinary reads. Static service calls can set x-operator-actor; the default is service-admin. This is attribution supplied by the service-token holder, not separate human authentication.

Sources: parity cloudflare/src/env.js:1-9; cloudflare/src/worker.js:27-81,115-135,159-167.

Scoped API keys

Admin-only POST /operator/api/keys accepts name and optional scopes. Allowed scopes are read and memory:write; omitted scopes default to read. Creation returns HTTP 201 with ok, key, token and apiBaseUrl. The anton_ token contains 64 hex characters after its prefix and is returned only on creation. Storage keeps its SHA-256 hash and metadata, including a 14-character display prefix.

A dynamic key with read may GET the snapshot, PR, repos, traces, reports, memory, SCM and Test Lab route families, plus exactly /operator/api/settings/usage. It cannot read general settings, commands, analytics, webhook history or key management through that scope. A memory:write key may make memory mutations except source-integration preview. Scope permission does not create nonexistent routes.

GET /operator/api/keys?q=... lists metadata. POST /operator/api/keys/:id/revoke revokes a key. A revoked or invalid key fails authentication; an authenticated key used outside its route scope receives 403.

Sources: parity src/operator-api-keys.js:31-45,65-112; cloudflare/src/operator-api-keys-api.js:49-75; cloudflare/src/worker.js:117-127.

Read routes and envelopes

There is no universal ok envelope. Snapshot, PR detail and reports have their own schema envelopes; ZIP export is binary. JSON helpers generally set cache-control: no-store.

RouteParametersSuccess shape
GET /healthNone; unauthenticatedok, service: gilf-pr-review-queue
GET /operator/api/snapshotview, q, repo, statusschema: son-of-anton.operator.v1, generatedAt, ttlSeconds: 15, view, data
GET /operator/api/prrepo, numberschema, generatedAt, data containing runs, findings, events and publication ledger
GET /operator/api/reposNoneok, repos
GET /operator/api/webhooksstatus, limitok, deliveries
GET /operator/api/webhooks/:deliveryIdEncoded IDok, delivery
GET /operator/api/analyticsNone requiredok, analytics, including queue projection and at most 100 failure reasons
GET /operator/api/tracesrepo, prNumber or pr, reviewKey, runId, status, limitok, traces
GET /operator/api/traces/:traceIdEncoded IDok, trace, spans as siblings
GET /operator/api/commandsstatus, limitok, commands
GET /operator/api/commands/:idEncoded IDok, command

Snapshot views are pull-requests (fallback), analytics, memory and settings. Pull-request snapshot items are capped at 100. Webhook, trace and command list limits default to 50 and are clamped to 1–100, with noninteger input falling back to 50. Command status filters accept queued, running, succeeded or failed.

Trace summaries expose identity, timing, status and attributes. They do not return top-level cost/token totals or span counts. Those values are available on detail spans, whose fields include spanId, parentSpanId, kind, inputTokens, outputTokens and costUsd. Detail does not expose input/output bodies. Missing trace, webhook or command IDs return 404.

Sources: parity cloudflare/src/review-state-api.js:575-639,641-690,835-923; cloudflare/src/review-trace-queries.js:14-64,73-132; cloudflare/src/worker.js:97-99.

Reports

GET /operator/api/reports accepts each of these parameters at most once. Unknown or duplicate parameters are rejected.

ParameterValues/defaults
repoowner/name
author, team, qText, at most 300 characters; repo has the same length limit
from, toValid YYYY-MM-DD; inclusive UTC; from must not follow to
granularityday (default), week, month
severityP0, P1, P2, P3, info, unknown
statusopen, addressed, not_reobserved, unknown
securityall (default), true, false, unknown
page1–100000, default 1
pageSize1–100, default 25

The response has schema: son-of-anton.reports.v1, filters/options, summary, comparison, series, rankings, coverage, notes and paginated findings, reviewed PRs and comments. A preceding-period comparison is generated only when both date bounds are explicit. Findings return nullable location fields; the API does not invent line numbers when the producer omitted them.

“Addressed” requires a resolution claim plus recorded evidence; a finding disappearing from a later review is not by itself a fix. Preserve the report's notes when interpreting metrics.

Source loading is bounded: 10000 runs, 10000 heads, 2000 configs, 30000 ledger rows, 30000 traces, 30000 findings, 1000 findings per run, 2000 per PR, and 20 MiB input. Exceeding a report bound returns 413 rather than a silently partial source report. Source history is primarily narrowed by repository; a shorter date interval does not necessarily avoid a source-history limit.

GET /operator/api/reports/export uses the report filters and returns a ZIP, with a 20 MiB export bound. Do not parse it as JSON. Report errors use error and code (report_error or report_too_large), not a universal ok: false shape.

Sources: parity cloudflare/src/review-reports-api.js:4-6,42-132,145-179,309-354.

Command creation and updates

The API persists command events; it does not run reviews inside the request handler. A bridge/consumer must process them. A 202 response means queued command, not completed review.

All routes below have prefix /operator/api:

RouteAccepted body fields
POST /commands/requeueEither reviewKey or repo plus number; optional variant, reason, actorId, commandId
POST /commands/retry-publishreviewKey, optional reason, actorId, commandId
POST /commands/replay-webhookdeliveryId, optional force, reason, actorId, commandId
PATCH /commands/:idstatus, optional startedAt, completedAt, error, result

For a parity Worker URL in BASE and a configured command token:

curl --fail-with-body -sS "$BASE/operator/api/commands/requeue" \
  -H "Authorization: Bearer $GILF_OPERATOR_COMMAND_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: operator-review-request-123' \
  --data '{"repo":"owner/name","number":123,"reason":"operator_force_review"}'

Use a new idempotency key for each intended new command. The header takes precedence over body commandId. The handler validates the request, then returns an existing ID as HTTP 200 with created: false; a new command returns 202 with created: true. It does not compare an existing command's payload with the new payload. Concurrent creation is not implemented as a single upsert.

Transitions allow the same status, queued to running, and running to succeeded or failed; other transitions return 409. A processed/succeeded webhook needs force: true to replay. sync-repositories commands cannot be updated through the generic PATCH route; they are owned by the native live cron bridge.

Sources: parity cloudflare/src/review-state-api.js:328-387,423-445,934-940.

Repository configuration and queue repair

PATCH /operator/api/repos/:encodedRepo accepts enabled, branches, validation, model, alerts and reason. Encode owner/name as one path segment, such as owner%2Fname.

  • branches: include, exclude string lists.
  • validation: provider in local, crabbox, e2b, shadow; codeChangesOnly boolean. This is the legacy config schema, not the native executor-name list.
  • model: provider, model, fallbackProvider, fallbackModel, reasoningEffort.
  • alerts: telegram boolean and target string.

Unknown fields are rejected. Acceptance into parity storage is not proof that an unmerged native deployment consumes the field.

POST /operator/api/queue/requeue-dead accepts jobKey, resetAttempts, reason, actorId. POST /operator/api/queue/release-lease accepts jobKey or receiptId, force, reason, actorId. These repair the parity Durable Object queue, not native Cloudflare Queue messages. The handler performs repair before recording its audit event; the two are not atomic.

Sources: parity cloudflare/src/review-state-api.js:254-294,525-572; cloudflare/src/queue-do.js:282-318.

Memory, settings, SCM and Test Lab

FamilyImplemented routes under /operator/api
MemoryGET /memory/integrations; POST /memory/integrations/preview; GET,POST /memory/contexts; GET,PATCH,DELETE /memory/contexts/:id; GET,POST /memory/clusters; PATCH,DELETE /memory/clusters/:id; GET /memory/knowledge; GET,PUT /memory/knowledge/document
SettingsGET,PATCH /settings; GET /settings/audit?q&limit&offset; GET /settings/usage?from&to
KeysGET,POST /keys; POST /keys/:id/revoke
SCMGET /scm; POST /scm/sync; DELETE /scm/alerts/:id
Test LabGET /test-lab; GET /test-lab/:id

Memory document GET uses repo and path query parameters; PUT passes its update in JSON. Memory context/cluster deletes and SCM alert dismissal require a body containing revision. SCM sync accepts an empty JSON object and returns 202 with a command. Test Lab details and limits are in Test Lab.

Sources: parity cloudflare/src/review-memory-api.js:48-118; cloudflare/src/review-policy-api.js:48-63; cloudflare/src/operator-api-keys-api.js:49-75; cloudflare/src/scm-api.js:23-41; cloudflare/src/test-lab-api.js:314-342.

The BFF's current command and queue token routing has integration mismatches documented in Dashboard. Use the route-specific backend contract above rather than assuming every UI action is already functional. No live API request was made during this source audit.

On this page