Run on Your Cloudflare Account
Provision the native engine, enable a canary repository, separate publication authority and verify durable receipts.
Run these commands from an authorized son-of-anton-review checkout on feat/cloudflare-native. The private-repository and licensing prerequisites in Requirements apply. The source runbook cloudflare-native/DEPLOY.md mixes provisioning instructions with historical deployment receipts; historical IDs and outcomes are not your installation's state.
Engine and operator are separate trees. This procedure deploys cloudflare-native/src/main.js and the key broker. The expanded API lives in son-of-anton-operator-parity/cloudflare/ on feat/greptile-operator-parity; the session UI is in anton-ui-trace-parity. There is no combined command here, and the native ingress hostname does not serve their /operator/api/* routes.
Account and configuration
- Obtain human approval for the target Cloudflare account, spending and infrastructure changes. The checked-in runbook calls for Workers Paid with Containers enabled; have the owner confirm current entitlements and quota.
- Install locked engine dependencies with
npm ciand an approved Wrangler version separately. Provide a working Docker/container-image build environment. - Authenticate with
wrangler loginif needed, then confirm the intended account withwrangler whoami. - Replace the account IDs in both native config files, the App ID in
wrangler.key-broker.jsonc, and the D1/KV IDs after provisioning. Resource names and theKEY_BROKERservice name must match your deployment. - Change the checked-in
GILF_PUBLISH_MODE=liveandCRON_AUTHORITY=livetoshadowbefore deploying. ReplaceCRON_AUDIT_INSTALLATIONSandPR_AGENT_LOOP_SINCE; do not operate on the checked-in estate.
Keep the OMP image_build_context set to "..". Its Dockerfile copies src/, package.json, prompts/ and config/ from the engine root. The configuration also declares a separate Sandbox container application and Durable Object binding. It is not a one-image deployment.
Provision resources
For a new deployment only:
| Resource | Binding | Command |
|---|---|---|
| D1 | DB | wrangler d1 create son-of-anton-review-state |
| KV | DEDUPE | wrangler kv namespace create DEDUPE |
| R2 payload bucket | WEBHOOK_PAYLOADS | wrangler r2 bucket create son-of-anton-webhook-payloads |
| R2 cron artifacts | CRON_ARTIFACTS | wrangler r2 bucket create son-of-anton-cron-artifacts |
| Review queue | REVIEW_QUEUE | wrangler queues create gilf-review-intents |
| Dead-letter queue | DEAD_LETTER | wrangler queues create gilf-review-dlq |
Set the resulting IDs in cloudflare-native/wrangler.jsonc. For an existing deployment, inventory and reuse its state; do not create replacements merely because a probe fails.
Ingress deduplicates delivery IDs with KV. When a raw webhook exceeds 96 KiB and the R2 binding exists, it stores the payload there and queues a reference. The consumer hydrates that reference. R2 is also used for cron artifact bodies; D1 holds the indexes and durable run state.
Fresh database
wrangler d1 execute son-of-anton-review-state --config cloudflare-native/wrangler.jsonc --remote --file cloudflare-native/schema.sql
wrangler d1 execute son-of-anton-review-state --config cloudflare-native/wrangler.jsonc --remote --file cloudflare-native/migrations/002-cron-parity.sqlBoth are required: schema.sql contains the native lease fences, outcomes ledger and trace indexes, but not the cron tables. Migration 002 adds cron_runs, cron_job_state, cron_artifacts and cron_dead_letters.
Existing databases need Upgrading: migration 001 is destructive, and an older publish_leases needs a guarded created_at column addition. CREATE TABLE IF NOT EXISTS cannot upgrade an existing table's columns.
Enable a repository
App installation and review enablement are different. The native adapter sets repository admission from stored repo_configs, previous review history, or autoEnableNewRepos (default false). GILF_REPOS is not read on this path. Even an authorized manual command remains blocked by explicit repository disablement.
After a human selects an installed canary repo, inspect its current setting. Replace OWNER/REPO with its exact full name; do not run the placeholder unchanged.
wrangler d1 execute son-of-anton-review-state --config cloudflare-native/wrangler.jsonc --remote --command "SELECT repo, json_extract(config_json, '$.enabled') AS enabled FROM repo_configs WHERE repo='OWNER/REPO';"During setup, before reviewing that repo, this upsert enables it without replacing other stored config fields:
wrangler d1 execute son-of-anton-review-state --config cloudflare-native/wrangler.jsonc --remote --command "INSERT INTO repo_configs (repo, config_json) VALUES ('OWNER/REPO', json_object('enabled', json('true'))) ON CONFLICT(repo) DO UPDATE SET config_json=json_set(repo_configs.config_json, '$.enabled', json('true'));"Repeat the readback and confirm enabled=1. This is a deliberate policy mutation, not discovery or installation. Do not race it with another policy writer. Existing run policy snapshots are pinned; use a new manual comment for a new attempt after changing settings.
Secrets and model selection
Have the authorized operator enter secret values, never commit or paste them into chat:
wrangler secret put GITHUB_WEBHOOK_SECRET --config cloudflare-native/wrangler.jsonc
wrangler secret put OPENROUTER_API_KEY --config cloudflare-native/wrangler.jsonc
wrangler secret put GITHUB_APP_PRIVATE_KEY --config cloudflare-native/wrangler.key-broker.jsoncOnly the broker holds the native App private key. The main Worker forwards selected model/validation secrets to OMP, which receives scoped broker tokens for GitHub access. Shadow still needs the broker for source access and PR metadata reads.
Set these plain vars in the main config:
| Variable | Setup choice |
|---|---|
GILF_MODEL_PROVIDER | openrouter, preferred over legacy GILF_CODEX_PROVIDER |
GILF_MODEL | Your approved, currently available OpenRouter model |
GILF_OPENROUTER_REQUIRE_FREE | 1 unless paid usage is explicitly approved; the committed value is 0 |
GILF_MODEL_PRICES | Optional accurate JSON price map, USD per million input/output tokens; remove stale values. Unknown OpenRouter prices yield null estimates, not zero. |
GILF_VALIDATION_EXECUTOR | managed-cf-sandbox, with both SDK class export and binding intact |
GILF_PUBLISH_MODE | Explicit shadow for commissioning |
CRON_AUTHORITY | Explicit shadow until scheduler cutover is approved |
Remove GILF_VALIDATION_SHADOW_EXECUTOR for a single-lane canary. If retaining managed-e2b, supply E2B_API_KEY; it is also required when E2B is primary. The committed E2B timeout is 600000 ms. The E2B budget gate only suppresses the shadow selector, and its ledger-read failure forwards the lane unchanged; it is not a hard account-wide spending limit.
Only container-env.js allowlisted vars reach OMP. Swarm/planner, inversion and artifact flags are not forwarded. The default image's Codex command is a failing placeholder, not an authenticated alternative ready to select.
Deploy and connect GitHub
wrangler deploy --config cloudflare-native/wrangler.key-broker.jsonc
wrangler deploy --config cloudflare-native/wrangler.jsoncDeploy the broker first so the main service binding resolves. Confirm both container applications and their intended images, not only the Worker upload.
Configure the App webhook at your main Worker's /github/webhooks URL, using the matching secret, and install it on the selected repos. See Requirements for App permissions and event subscriptions.
# Shell variable for your deployment URL, not an engine configuration key.
export ANTON_ENGINE_URL='https://your-worker.example'
curl --fail-with-body --silent --show-error "$ANTON_ENGINE_URL/health"Ingress returns {"ok":true,"service":"son-of-anton-ingress"}. That endpoint does not test resource bindings. The native fetch handler returns 404 on paths other than health and the webhook; it does not host the dashboard.
Verify a review
Post a new @anton review or @anton rerun comment as an authorized owner/member/collaborator. The consumer resolves a missing head from GitHub. It ignores status and help comments, although the Node server implements those replies.
Inspect the selected canary, not merely the newest unrelated row:
wrangler d1 execute son-of-anton-review-state --config cloudflare-native/wrangler.jsonc --remote --command "SELECT review_key,head_sha,status,json_extract(record_json,'$.skipReason') AS skip_reason,json_extract(record_json,'$.publish.mode') AS publish_mode FROM review_runs WHERE repo='OWNER/REPO' ORDER BY rowid DESC LIMIT 10;"
wrangler d1 execute son-of-anton-review-state --config cloudflare-native/wrangler.jsonc --remote --command "SELECT trace_id,review_key,status FROM review_traces WHERE repo='OWNER/REPO' ORDER BY started_at DESC LIMIT 10;"Using the returned trace ID:
wrangler d1 execute son-of-anton-review-state --config cloudflare-native/wrangler.jsonc --remote --command "SELECT name,status,error FROM review_trace_spans WHERE trace_id='TRACE_ID' ORDER BY seq;"
wrangler tail --config cloudflare-native/wrangler.jsoncRead policy decisions, semantic/validation gaps and applicable spans such as context.graph and publish. There is no invariant that every run has exactly seven successful spans: optional lanes, skips and errors change the result. Shadow suppresses GitHub publication, not model/sandbox execution or state writes. A stored publication status from a recording publisher is not a remote receipt.
For an approved live cutover, first drain competing publishers, then set GILF_PUBLISH_MODE=live, redeploy and trigger a new canary. Confirm actual GitHub review/check IDs at the expected head. Invalid publish-mode values throw; parsing trims and lowercases values, and an absent/blank value defaults to shadow. The shipped config explicitly overrides that default with live.
Cron authority and cadence
CRON_AUTHORITY is separate from review publication. Shadow cron runs can still record observations and artifacts; do not treat shadow as a read-only database mode. Replace installation scope before scheduling audits and stop legacy mutation timers before enabling live cron authority.
| Cron expression | Job |
|---|---|
2-59/15 * * * * | pr-agent-loop |
3-59/15 * * * * | watchdog |
* * * * * | command-bridge |
30 22 * * * and 30 23 * * * | nightly-audit, gated to 23:30 Europe/London |
The nightly handler checks local time so both UTC expressions do not run the audit twice. Prime-watch has a handler but is deliberately unscheduled. Verify actual persisted cron results; an enabled trigger or skipped DST-side event is not proof that the intended audit completed.
Rollback
- Set
CRON_AUTHORITY=shadow, deploy, and let running cron mutations finish. - Repoint the App webhook to the retained Node endpoint and verify the saved URL. Keep replacement workers stopped while accepted native reviews finish.
- Set native
GILF_PUBLISH_MODE=shadow, deploy, and confirm no live native review remains. A config change cannot stop a running container. - Reconcile or redeliver accepted unfinished work before enabling the replacement publisher. Preserve uncertain receipts and dead-letter evidence; do not assume independent D1 and SQLite stores deduplicate each other.
- Restore only the intended Node timers, then verify a real review and scheduled-job execution on that lane.
Retain fallback code, state, secrets and unit definitions until a separate health/rollback review approves removal. Historical retention dates in the source runbook do not prove today's fallback is safe to retire.