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>
5 KiB
Portfolio reporting and operating cadence
make portfolio-report renders the current portfolio view from
tools/portfolio_report.py. The report is derived entirely from committed
evidence: resource records in data/resources/, the latest
data/portfolio-coverage-*.json, and the optimization cases in
data/optimization/. Nothing in it is typed by hand.
What the report answers
| Section | Question |
|---|---|
coverage |
Which service groups are represented, and which evidence gaps are still delegated and to whom. |
lifecycle |
How many resources sit in each lifecycle state, and whether any lacks an owner. |
utilization |
Provisioned versus observed capacity per metric, flagged idle, normal, or saturated; and which resources cannot be measured at all. |
cost |
Which resources carry price evidence, which do not, and which have no allocation method so their cost reaches no consumer. |
renewals |
Contract dates inside the 90-day horizon, and resources with no recorded dates at all. |
risks |
Concentrated failure domains, unpriced resources, unattributed cost, idle and saturated capacity. |
optimization |
Open cases, their per-option verdicts, and the named evidence blocking each one. |
next_actions |
The smallest set of evidence that would unblock the most decisions, addressed to the repository that owns it. |
Not forcing false precision
Two rules the report holds to, because the alternative is a number that looks authoritative and is not:
known_monthly_spend_eurisnull, not0. No booked cost has reached this repository, and six of seven resources carry no price evidence. Summing what happens to be known would report a portfolio spend an order of magnitude below reality. The figure stays unknown untilfin-hubdelivers booked facts underdocs/fin-hub-resource-control-contract-v0.1.md.- Unattributed cost is a list, not a spread. Four resources have allocation
mode
unattributed. Their cost is not divided across consumers by a plausible default; they are named, and the allocation driver is owed by the repository that owns the resource.
Resources that cannot be measured appear in utilization.unmeasured with the
reason, rather than being silently omitted from the ratios.
Cadence
| Rhythm | When | Inputs | Consumers | Output |
|---|---|---|---|---|
| Monthly observation | First week, for the closed month | Monthly actual records from delegated telemetry; booked costs from fin-hub |
resource-control | tools/control_cycle.py variance per resource; a new optimization case where variance is attributed to demand, price, or allocation rather than data quality |
| Monthly portfolio report | With the observation | Resource records, coverage, optimization cases | Human operator; owning repositories | make portfolio-report; the next_actions list is re-sent to the repositories named in it |
| Quarterly calibration | End of quarter | Three months of variance | resource-control; fin-hub |
Forecast revisions per docs/forecast-actual-control.md — revisions, never overwrites; refreshed provider prices in every open case |
| Pre-renewal review | At least 60 days before the earliest renews_on or cancel_by |
Contract evidence, utilization, open cases | Human financial authority | A renewal case, decided while cancellation is still possible |
| Event-driven | Sustained variance beyond threshold, an incident exposing a failure domain, or a workload request | The triggering evidence | Owning repository | A case of the matching type per docs/optimization-cases.md |
Reading the current report
As of 2026-08-14 an operator asking the four questions this cadence exists to answer gets these answers, and the honest ones are the useful ones:
- Material spend? Unknown, and explicitly so. Only the proposed backup
storage carries price evidence. Every other resource is waiting on
RAIL-HO-WP-0008andFIN-WP-0004. - Idle or saturated capacity?
railiance01and thereef-railiancek3s cluster are idle on every measured metric — 14 percent CPU, 37 percent memory. Nothing is saturated. Five resources cannot be measured at all. - Forecast error? Not yet computable. The control-cycle mechanism is proven on paired examples, but no operational actual observation exists, so there is no variance to report and none is fabricated.
- Approaching commitments? None visible — and that is itself the finding: six active resources have no renewal or cancellation date recorded, so the cancellation window cannot be respected for any of them.
- Next evidence-backed action? The
next_actionslist, led by the seven delegated workplans that own the missing evidence.
The single largest structural risk the report surfaces is concentration: six of
seven resources share host:railiance01, including the backup storage's own
intended protection target. That is the standing argument for placing backup
storage outside the Host Europe failure domain, and it is visible in the report
rather than only in prose.