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,46 @@
# ADR 0003 — Operating model disposition (local timer retained)
Accepted: 2026-09-27.
## Context
IR-WP-0007-T03 asks whether continuous uptime is required for Intelligence
Radar's scheduled jobs, and to retain the local timer unless a concrete
requirement justifies a hosted worker and its own live owner workplan.
The current operating model is a user-level systemd timer/service pair
(`ops/systemd/intelligence-radar.timer`, `ops/systemd/intelligence-radar.service`)
invoking `python3 -m intelligence_radar run-due`, which is explicitly
idempotent and safe to invoke repeatedly (`ops/RUNBOOK.md`). `run-due` and the
scheduler already handle missed/late runs and retries (`intelligence_radar/scheduler.py`,
exercised in `tests/test_ingestion_scheduler.py`), so uptime gaps degrade
freshness rather than correctness.
## Decision
Retain the local systemd user timer as the operating model. No hosted worker
is adopted.
## Rationale
- Nothing in this repository's current scope requires sub-day freshness: the
cadence is daily/weekly digests and periodic source captures, not real-time
alerting.
- The scheduler design already absorbs downtime (a laptop asleep, a missed
boot) by running the latest due job on next wake rather than requiring
uninterrupted uptime.
- A hosted worker adds a live infrastructure surface (deployment, credentials,
monitoring, its own on-call) with no offsetting capability gain today, and
would need its own owner workplan to be justified, per this task's own
instruction not to start "another infrastructure programme before the
research evidence is usable."
- The evidence-quality blockers ahead of this project (IR-WP-0005 credential
delivery, IR-WP-0006 billing reconciliation) are unrelated to scheduler
uptime; hosting the scheduler elsewhere would not unblock them.
## Revisit trigger
Reopen this decision only if a concrete requirement appears — e.g. a
downstream consumer needs sub-daily freshness guarantees, or the operator
machine's uptime becomes materially unreliable for the daily/weekly cadence.
Until then this is not tracked as an open task.