resource-control/data/actuals/2026-08.json
tegwick 10b988fa1c feat(wp-0002): complete T07 — control loop on the live backup resource
The backup is procured and proven, so the loop runs on real evidence.

- data/actuals/2026-08.json: first real observation. database 0.6365 GB,
  stored 0.0066 GB over 8 objects, backup success 1/1, restore RTO 1.08 min.
  Five proxies null, each with a named owner in measurement_gaps.
- data/thresholds/platform-audit-storage.json + tools/thresholds.py: budget
  variance, abnormal growth, stale backup, unused commitment. Fail-closed —
  an unmeasured value is reported as unmeasured, never as within.
- financial_exchange.py gains a usage mode emitting technical_usage records to
  fin-hub, with measurement gaps carried through and no infrastructure amount:
  fin-hub owns the booked fact and a null is never sent as 0.00.
- observation schema 0.2 allows null cost and usage proxies; variance.py fails
  closed rather than reporting a 100% favourable variance on a missing amount.
- platform-audit-storage: ordered -> active, commissioned 2026-08-14, on
  operational fact rather than on the purchase.

The optimization case is now approved by the founder. That needed a schema
change: Host Europe never supplied written terms, so options gained
excluded/exclusion_reason. Previously an unevaluable alternative blocked its
case forever, leaving the record claiming no decision while the bucket was in
production. An excluded option keeps its unknowns and must say what would
bring it back.

August produces no variance and should not: the decision forecast starts at
2026-09, so August is a commissioning baseline. Threshold run is 2 within,
1 not applicable, 6 unmeasured, 0 breaches.

Also fixes a pre-existing test failure: reef-storage consumers_actual is now
rapp-postgres, which the assertion still expected to be empty.

136 tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 20:53:12 +02:00

46 lines
2.7 KiB
JSON

{
"schema_version": "0.2",
"record_type": "usage_observation",
"workload": "rapp-postgres/platform-pg",
"cost_attribution_key": "platform:audit-storage",
"provider_id": "scaleway-standard-multi-az",
"created_at": "2026-08-14T18:24:00Z",
"scenario": "observed",
"forecast_ref": "data/forecasts/platform-audit-storage-scaleway-base-2026-08.json",
"rows": [
{
"period": "2026-08",
"database_gb": 0.6365,
"stored_gb": 0.0066,
"wal_gb": null,
"restore_egress_gb": null,
"write_requests": null,
"read_requests": null,
"infrastructure_eur": null,
"internal_labor_hours": null,
"internal_labor_eur": null,
"total_eur": null,
"backup_success_pct": 100,
"restore_rto_minutes": 1.08,
"measurement_gaps": [
"wal_gb: the 8 objects in prefix platform-pg/ hold the first base backup and its WAL together; the T05 evidence does not separate them",
"restore_egress_gb: two scratch restores read from the bucket but bytes transferred were not recorded (owner: resource-control, add to the next drill)",
"write_requests, read_requests: no request metric is exposed to the scoped backup key (owner: resource-control, needs a Scaleway usage export)",
"infrastructure_eur: no invoice for a resource commissioned 2026-08-14; the Scaleway billing API is denied to this key by design (owner: fin-hub, FIN-WP-0004)",
"internal_labor_hours: procurement, credential custody, and two restore drills were performed in this period but no time record was kept (owner: resource-control)"
]
}
],
"evidence": [
"docs/evidence/RESOURCE-WP-0002-T05-restore-2026-08-14.json",
"data/resources/platform-audit-storage.json",
"reef:storage/substrate/object-stores/platform-audit-storage.yaml"
],
"notes": [
"First real observation for this resource. It went live mid-period: bucket created 2026-08-14T16:21:56Z, first backup 2026-08-14T18:14:21Z, so 2026-08 covers roughly four hours of operation, not a month.",
"Backup success is 1 of 1 completed backups, not a month of scheduled runs.",
"restore_rto_minutes is the full-restore wall time of 65 seconds; PITR measured the same 65 seconds on the second attempt after the recovery target was corrected.",
"Observed RPO: archive_timeout is 5 minutes and a WAL segment archived about 2 seconds after pg_switch_wal, so the measured RPO is well inside the 5-minute requirement — but on four hours of evidence.",
"Comparing this period against the 12-month decision forecast will show a very large negative stored_gb error. That is a model artifact, not underuse: the forecast assumes 30 days of retained base backups and WAL at steady state, and this period holds one backup."
]
}