feat(portfolio): complete RESOURCE-WP-0003 T06 optimization cases and T07 reporting
T06: optimization-case schema, fail-closed evaluator, cadence and decision template. Every option including the baseline must present all ten decision fields; one unknown blocks the comparison. Validated on the storage case (Hetzner computes and loses to Scaleway by EUR 29.14/month on operator labour; Host Europe blocks on four named gaps) and on the non-storage reef-railiance k3s rightsizing case (low utilization is real, but nothing is costable while the railiance01 price is unknown). T07: portfolio report over coverage, lifecycle, utilization, cost, renewals, risks, open cases, and next actions, derived only from committed evidence. Portfolio spend is reported null rather than as a partial sum, unattributed cost is a named list rather than a spread, and unmeasurable resources are reported rather than dropped. RESOURCE-WP-0003 is finished; both cases remain blocked_on_evidence against live delegated records in other repositories. RESOURCE-WP-0002 is untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
54dd45c926
commit
2c2a6073ff
63 changed files with 4662 additions and 69 deletions
27
data/demand/platform-audit-storage.json
Normal file
27
data/demand/platform-audit-storage.json
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"schema_version": "0.1",
|
||||
"workload": "platform-pg",
|
||||
"cost_attribution_key": "platform:audit-storage",
|
||||
"currency": "EUR",
|
||||
"retention_days": 30,
|
||||
"base_backups_per_day": 1,
|
||||
"monthly_restore_drills": 1,
|
||||
"observation": {
|
||||
"observed_at": "2026-08-10T15:54:12Z",
|
||||
"database_bytes": 39573871,
|
||||
"wal_bytes": 19744568,
|
||||
"wal_stats_reset": "2026-08-10T13:37:53Z",
|
||||
"extrapolated_wal_gb_per_day": 0.208,
|
||||
"source": "read-only pg_database_size and pg_stat_wal query on platform-pg-1"
|
||||
},
|
||||
"scenarios": {
|
||||
"low": {"initial_database_gb": 1, "monthly_database_growth_pct": 5, "wal_gb_per_day": 0.25, "restore_egress_gb": 1, "write_requests_per_month": 1000, "read_requests_per_month": 500, "operator_hours_per_month": 0.5, "operator_hourly_eur": 60},
|
||||
"base": {"initial_database_gb": 5, "monthly_database_growth_pct": 10, "wal_gb_per_day": 1, "restore_egress_gb": 5, "write_requests_per_month": 2500, "read_requests_per_month": 1000, "operator_hours_per_month": 1, "operator_hourly_eur": 60},
|
||||
"high": {"initial_database_gb": 20, "monthly_database_growth_pct": 20, "wal_gb_per_day": 5, "restore_egress_gb": 20, "write_requests_per_month": 12000, "read_requests_per_month": 5000, "operator_hours_per_month": 2, "operator_hourly_eur": 60}
|
||||
},
|
||||
"notes": [
|
||||
"Observed workload is less than one day old; scenario floors intentionally dominate the raw sample.",
|
||||
"Storage forecast assumes 30 retained daily base backups plus 30 days of WAL and is conservative because it does not model compression or Barman's exact point-of-recoverability deletion timing.",
|
||||
"Provider exit is modeled as one full stored-byte egress event and is reported separately from recurring monthly cost."
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue