Skip to content

Run the MARY GENERATED-statements job through the Batch API with thinking off, under $0.25 per run and $15 per month


Run the MARY GENERATED-statements job through the Batch API with thinking off, under $0.25 per run and $15 per month

Section titled “Run the MARY GENERATED-statements job through the Batch API with thinking off, under $0.25 per run and $15 per month”

Date: 2026-10-09 Status: closed Supersedes: docs/decisions/2026-10-08-mary-governance-generated-statements-render.md (partial — voids only the cost ceilings in ruling 3, $1.00 per run and $40 per month; terms 1–7 and rulings 1, 2, 4 and 5 stand) Superseded-by: none — current MR-compliance: MR-4, MR-7, MR-9

2026-10-08-mary-governance-generated-statements-render.md (closed, countersigned 2026-10-09, 83496e6d) admitted the GENERATED band. Ruling 3 set a ceiling of $1.00 per run and $40 per month. FLIGHT judged $40 a month excessive on 2026-10-09 and asked for $10–15 at most. Ruling 3’s own sizing called its figure an estimate that the build PR’s first-run token counts would replace. Nothing has run yet, so this document resizes the ceiling from the same measurement, with the request shape fixed so that the estimate holds.

Cost basis, measured 2026-10-09 against the live snapshot. The live snapshot (2db47489, 06:39Z) is 95,151 bytes of minified JSON, and prompts/mary-governance-diagnose/prompt.xml is 8,729 bytes. At about 3 bytes per token, that is roughly 32k input tokens a run. The output is at most five statements of up to 280 characters each, about 1.5k tokens. The snapshot schedule (41 */6 * * *) gives about 120 runs a month. The 3 days of history so far (2026-10-07 to 10-09) add one manual dispatch per scheduled run, so 120 is a floor.

Request shape on claude-opus-4-8Per run120 runs/month
Synchronous, thinking off≈ $0.20 ($0.16 in + $0.04 out at $5 / $25 per M)≈ $24
Synchronous, thinking on (ruling 3’s basis)≈ $0.30–0.60≈ $36–72
Batch API, thinking off≈ $0.10 ($0.08 in + $0.02 out at $2.50 / $12.50 per M)≈ $12

Input is about 80% of the cost. On claude-opus-4-8, thinking is off unless the request enables it, so the decision that matters is to keep it off. Message Batches bill at half the synchronous rate and return within 24 hours, usually within minutes. The band never waits on a model (D3 R-6, term 2), so the delay costs nothing that the page shows.

  1. Ceilings. The per-run ceiling is $0.25. The monthly ceiling is $15. They replace ruling 3’s $1.00 and $40.
    • The per-run ceiling is a repo variable read by the job, the same mechanism term 6 already uses, under the name MARY_DIAGNOSE_COST_CEILING_USD. Unset still means no call, and the job stores state (e) with the reason “no cost ceiling set”.
    • The monthly ceiling is the spend limit on the dedicated Anthropic workspace that ruling 2 created, set in the Anthropic console. When it binds, the API refuses the call and the job stores state (e) with that reason for the rest of the month.
  2. One batch per run id. The job submits each run’s single request as a one-request Message Batch with custom_id set to the snapshot run id. It polls until the batch ends. A batch that ends without a result (errored, canceled or expired) is stored as state (e) with that reason. It is not resubmitted, matching term 6’s “not retried”. Cost is computed and recorded at batch rates.
  3. Thinking off, output bounded. The request does not enable thinking and sets max_tokens to 4096. At batch rates that caps output at about $0.05 a run. The prompt already requires the whole output to be one strict JSON object. Any other output is refused by the verifier’s envelope check (state (d)), not repaired.
  4. Estimate before submitting. Before submitting, the job counts the request’s input tokens with the token-counting endpoint, which has no charge. It adds max_tokens at the batch output rate. If the total exceeds the per-run ceiling, it does not submit, and it stores state (e) with the reason “estimated cost over ceiling”, giving both figures.
  5. The eval runs on the job’s own request shape. Term 7 still gates the first render. The bin/eva eval pass recorded in eva-hq #109 ran through the claude CLI, not this request shape. So the build PR also runs the eval cases through the job’s own request path (model, thinking off, max_tokens) and records the result. Citation precision must be 100%, and the clean fixture must return zero statements.

This decision builds nothing.

  • Send the model a smaller input: drop row_index (15,325 bytes; every row carries its own id), register-aging’s per-row commit fields, and projection-drift’s full source lists (4,617 bytes). Not ruled here, and left open. It changes the prompt’s input in eva-hq and needs an eval re-run. Estimated at about $8.5 a month with this decision’s shape. It is the first lever if the $15 ceiling binds.
  • A cheaper model (claude-sonnet-5-5, about $5.6 a month here; claude-haiku-5-5, under $1). Not needed as a decision: ruling 5 already routes any model change through term 7’s eval. The verifier drops what a weaker model gets wrong, so it fails towards fewer statements, not wrong ones.
  • Generate only when the snapshot changed. Rejected for now. The closed decision generates once per run id (D3 R-6), and it never shows an earlier run’s statements in states (d) and (e). Skipping unchanged runs would leave the band UNREAD on most runs.
  • Prompt caching. Rejected. Only the prompt body, about 2.5k tokens, is stable across runs, and runs are 6 hours apart, longer than either cache TTL.
  • claude-opus-5-5. Rejected as a cost lever. It is 20% cheaper per token, but its thinking cannot be disabled, which adds output and costs more than the per-token saving.
  • It does not change the model, where generation runs, the API key, the L2 read, the band’s states (a)–(e), or the verifier. Those are rulings 1, 2, 4 and 5 and terms 1–7, and they stand.
  • It does not trim the prompt’s input or switch models. Both stay open as above.
  • It does not edit the 2026-10-08 decision (MR-7). That document’s ruling 3 is superseded here for its ceilings only.

For code: none from this document. The generation-job PR implements terms 2–5 and records the first runs’ real token counts and costs. If they differ materially from the cost basis above, the PR says so.

For FLIGHT: create the dedicated workspace’s spend limit at $15, and the repo variable MARY_DIAGNOSE_COST_CEILING_USD at 0.25, alongside the MARY_DIAGNOSE_ANTHROPIC_API_KEY secret from ruling 2.

For invariants: none added, modified or repealed.

For downstream consumers (D6): none. eva.consumption.v1 is unchanged.

  • docs/decisions/2026-10-08-mary-governance-generated-statements-render.md (closed 83496e6d; ruling 3 superseded here for its ceilings; term 6 ceiling mechanism; term 7 eval gate)
  • docs/decisions/2026-05-10-smo1-io-org-level-only.md (precedent for a partial Supersedes: line)
  • eva-hq:prompts/mary-governance-diagnose/meta.yml (model: claude-opus-4-8)
  • eva-hq:prompts/mary-governance-diagnose/prompt.xml (8,729 bytes; the strict-JSON output contract)
  • eva-hq:bin/eva (_claude: the eval runs through the claude CLI)
  • mary-wiki:.github/workflows/governance-snapshot.yml (schedule 41 */6 * * *)
  • .github/workflows/irina-cycle.yml (IRINA_CYCLE_COST_CEILING_USD, the skip-when-unset pattern)
  • Subagent: Claude Opus 5.5, 2026-10-09 (drafted; read at petrova efcbd991, eva-hq c67f70fd, live snapshot 2db47489)
  • Human: flight@arno.host, 2026-10-09 — supersedes ruling 3’s ceilings only: $0.25 per run (MARY_DIAGNOSE_COST_CEILING_USD) and $15 per month (workspace spend limit); the job runs as a one-request Message Batch per run id, thinking off, max_tokens 4096, with a pre-submit token-count estimate (terms 1–5).

Countersigned by human:flight@arno.host on 2026-10-09 — box ticked in commit 335889a1 (petrova #550), authored by the human, squashed into e38a3ed9 on main. Terms 1–5 accepted as drafted: $0.25 per run, $15 per month, one-request Message Batch per run id, thinking off, max_tokens 4096, pre-submit estimate, eval on the job’s own request shape. Ruling 3 of 2026-10-08-mary-governance-generated-statements-render.md is superseded for its ceilings only. Status flipped open→closed on 2026-10-09 by an agent as scribe (MR-7).