IR-WP-0006-T01/T02: billing reconciliation contract and settlement mechanism

Spec and implement external-evidence settlement for pending trial
reservations, so the USD 0.023712 HTTP-401 reservation (and future ones)
can be resolved without fabricating a completed trial or treating a failed
request as zero-charge proof. intelligence_radar.trials.reconcile (+ CLI
reconcile) is write-once under the existing trials lock, rejects unknown
reservations, duplicate/conflicting settlement, cross-campaign references,
invalid amounts and budget overrun, and records reviewer attribution plus
an evidence pointer rather than any secret value. 9 new tests; full suite
(48 tests) and repository check pass. T03 (applying this to the real
reservation) stays blocked on authoritative provider billing evidence.

ADR-0003 closes the IR-WP-0007-T03 uptime question: retain the local
systemd timer, no hosted worker, since nothing here needs sub-day
freshness and the scheduler already tolerates downtime.

Mark IR-WP-0005/0006/0007 workplan status blocked: each still has at
least one task genuinely blocked on an external party (secrets-engine
human approval, authoritative billing evidence, and paid-execution
outcomes respectively) rather than anything actionable in this repo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 8472@bnt-lap001
Assistant-Session: 1cac6b6d-c1a5-4a04-a950-c4febb8d3f67
This commit is contained in:
tegwick 2026-09-27 17:12:13 +02:00
parent 7d03727945
commit 710b2ebbb5
8 changed files with 312 additions and 6 deletions

View file

@ -0,0 +1,89 @@
# IR-WP-0006-T01 — billing evidence and reconciliation contract
Reviewed 2026-09-27 by codex. Specifies how an unresolved trial reservation is
settled from reviewed external billing evidence, without treating absence of
a response as proof of zero cost.
## Inventory: campaign ir-openrouter-pilot-20260913
One append-only `trial-events` record exists for this campaign:
```json
{"budget_usd":"10.00","campaign":"ir-openrouter-pilot-20260913","case_id":"provenance-1",
"created_at":"2026-09-13T21:22:29.301211+00:00","kind":"reserved","model":"anthropic/claude-sonnet-5",
"reserved_usd":"0.023712","run_id":"29a46a1d6c2d9ef6cfce8de6efef75cddcfecee346c1b4babf57119f1a241d71"}
```
It is a `reserved` event with no matching `settled` event — the pending
USD 0.023712 reservation referenced throughout IR-WP-0004/0005/0006. `budget()`
in `intelligence_radar/trials.py` already reports this as `pending_usd`.
There is no mechanism today to settle a reservation except `execute()`, which
requires a live, successful, billed provider call — the wrong tool for a
request that returned HTTP 401 and never authenticated. `HTTP 401 alone is not
zero-charge proof`: no evidence in this repository establishes the provider's
actual charge for that attempt, and none is invented here.
## What counts as billing evidence
Provider-issued evidence of the actual charge (or absence of charge) for a
specific reservation's `run_id`: an OpenRouter activity/billing export,
dashboard screenshot, or admin API response showing the request's cost. It
must be retained as an artifact (content-addressed, like the rest of this
repository's evidence) and referenced by a pointer — a SHA-256 or file path —
never by embedding a credential or raw authenticated response that could carry
a secret. Retrieving that evidence may itself require the admitted read-only
path from IR-WP-0005; this contract does not require the credential, only a
place to record what it produces.
## Matching a reservation to evidence
A settlement targets exactly one `reserved` event, identified by its
`run_id` (content-addressed identity of `campaign + case + request payload`,
already unique and tamper-evident). The settlement is refused unless:
- **the reservation exists** — the `run_id` matches a recorded `reserved`
event (else: unknown reservation);
- **the campaign matches** — the reservation's own `campaign` field equals the
campaign the settlement is filed under (else: cross-campaign reference);
- **no settlement already exists** for that reservation (else: duplicate or
conflicting settlement — settlement is write-once, matching the store's
append-only, content-addressed design);
- **the amount is a valid, finite, nonnegative decimal** (else: invalid
amount);
- **recording it would not push the campaign's committed total (other
settled + other pending + this settlement) past the reservation's own
recorded `budget_usd` ceiling** (else: budget overrun — a discrepancy this
large is escalated for review, not silently written).
## What a settlement records
A `trial-events` entry, `kind: settled`, exactly like a live execution
produces — so `budget()` and `plan()` need no changes to recognize it — but
with `settlement_method: external_evidence`, an `evidence_ref` pointer, the
`reviewer` who attested the match, and the resulting `discrepancy_usd`
(`actual - reserved`, which may be negative, zero, or positive and is always
retained, never discarded). **No `trials` record is created.** Fabricating a
completed model trial (a response, a verification result, a returned model)
to close out a failed request is explicitly excluded — a settlement asserts
only a cost, never a synthetic outcome.
## Reviewer and restart behavior
The reviewer attribution is a plain identifier (human or agent name), not a
credential. Because the settlement check runs under the same file lock as
`execute()` and refuses once a `settled` event exists for the reservation,
re-running the same reconciliation after a partial failure (e.g. process
killed after validation but before write, or after write) is safe: a retry
either completes the original write or is refused as already-settled — never
double-settled, never partially written (the store's `atomic`/`put` primitives
guarantee whole-file, content-addressed writes). Uncertain or partial evidence
(no reviewer, no evidence pointer, non-numeric or missing amount) is refused
before any write, by the same validation used for a first attempt.
## Disposition
This contract and its implementation (`intelligence_radar/trials.reconcile`,
CLI `reconcile`) are specified and tested in this change (IR-WP-0006-T02).
Applying it to the real USD 0.023712 reservation (IR-WP-0006-T03) still
requires authoritative provider billing evidence, which this repository does
not have — that step stays blocked until such evidence exists.