audit: task-attempt ledger feeds real first-pass/defect/rework rates (gap 3)

- cloud/attempt_ledger.py: separate task_attempts table (not tasks
  columns) with per-attempt rows, MAX+1 attempt_no, append-only
  intent; interrupted rows kept but never counted; is_defect is
  explicit, never inferred from failure; first defect category
  wins; no-ledger tasks stay unknown (None), never backfilled.
  SQLite DDL is CREATE TABLE IF NOT EXISTS (idempotent); PG_DDL
  is the verbatim manual step for production Postgres, kept out
  of POSTGRES_SCHEMA on purpose (migrations coverage untouched).
- cloud/server.py GET /metrics-report: aggregates the ledger
  into compute_metrics records; missing ledger table degrades to
  unknown rates, not an error. Cost dual-column code untouched.
- cloud/metrics.py: docstring only (ledger is now the source);
  compute_metrics logic and all #238 semantics unchanged.
- Tests: 16 ledger tests (store/aggregate/metrics/PG adapter
  evidence) + 3 endpoint tests (real rates, old task beside
  ledger task, interrupted status non-terminal).
This commit is contained in:
host committed 2026-11-03 02:49:25 +00:00
1 parent 238ebbdbd2
commit 0db51f8145
6 files changed
+639 -22

No files matched your search

+9 -8
View File
@@ -4,8 +4,8 @@ Zero third-party dependencies; standard library only. This module
imports no ``cloud.*`` module: it computes over plain record dicts so
the collection logic is testable without a database, and so the
report shape is identical whether the records came from the control
plane (``server._metrics_report``), a test fixture, or a future
attempt ledger.
plane (``server._metrics_report`` reading the attempt ledger), a
test fixture, or a hand-built record list.
Definitions (pinned here, not left to each caller):
@@ -17,12 +17,13 @@ Definitions (pinned here, not left to each caller):
- First-pass green: terminal task whose ``attempts`` == 1 and whose
status is ``completed`` / ``merged``.
- Defect: a task with ``defects`` > 0, where ``defects`` is the count
of failed CI/audit rounds or follow-up rounds for that task. The
current tasks schema has NO attempts/defects column, so a caller
that cannot supply them must pass ``None`` -- and the rates then
come back as ``None`` with ``*_known`` False. An unknown rate is
never reported as 0: 0 would claim "no defects", which is a
decision-grade lie.
of failed CI/audit rounds or follow-up rounds for that task. Since
audit gap 3 these numbers come from the ``task_attempts`` ledger
(``cloud/attempt_ledger.py``: one row per real attempt, aggregated
by the endpoint); a task with no ledger rows must still pass
``None`` -- and the rates then come back as ``None`` with
``*_known`` False. An unknown rate is never reported as 0: 0
would claim "no defects", which is a decision-grade lie.
- Rework: terminal task with ``attempts`` > 1. Same None discipline.
- Per-task cost reuses the #212 dual-column discipline from
``cloud.cost``: priced USD micros and unpriced actual tokens are