resource-control/docs/evidence/RESOURCE-WP-0003-portfolio-reporting-2026-08-14.md
tegwick 2c2a6073ff 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>
2026-08-14 09:28:44 +02:00

74 lines
4 KiB
Markdown

# RESOURCE-WP-0003 portfolio reporting and cadence — 2026-08-14
## Result
`RESOURCE-WP-0003-T07` established the portfolio view and the operating cadence.
The implementation consists of:
- `tools/portfolio_report.py` — coverage, lifecycle, utilization, cost,
renewals, risks, open optimization cases, and next actions, derived entirely
from committed evidence;
- `docs/portfolio-operating-cadence.md` — monthly observation, monthly report,
quarterly calibration, pre-renewal review, and event-driven triggers, each
with named inputs, consumers, and outputs;
- `make portfolio-report`;
- 22 tests in `tests/test_portfolio_report.py`, including a suite that renders
the real committed portfolio rather than fixtures.
Nothing in the report is typed by hand. It reads `data/resources/`, the latest
`data/portfolio-coverage-*.json`, and `data/optimization/`, and it re-validates
every record it reads.
## Not forcing false precision
T07 requires reporting missing evidence and unapportioned cost rather than
forcing false precision. Two decisions carry that requirement:
- **`known_monthly_spend_eur` is `null`, never `0`.** Six of seven resources
carry no price evidence and no booked cost has arrived from `fin-hub`.
Summing the one priced resource would report a portfolio spend roughly an
order of magnitude below reality while looking authoritative. The field stays
unknown, accompanied by a note stating how many resources are unpriced.
- **Unattributed cost is a list of resources, not a spread.** Four resources
have allocation mode `unattributed`. They are named, with the repository that
owes the allocation driver; their cost is not divided across consumers by a
plausible default.
Resources whose capacity cannot be measured appear in `utilization.unmeasured`
with the reason, rather than being dropped from the ratios and thereby
flattering the portfolio average.
## What the current report tells an operator
T07 is done when an operator can identify material spend, idle or saturated
capacity, forecast error, approaching commitments, and the next evidence-backed
action. Against the portfolio as committed on 2026-08-14:
| Question | Answer |
|---|---|
| Material spend | **Unknown, explicitly.** Only the proposed backup storage carries price evidence; the rest waits on `RAIL-HO-WP-0008` and `FIN-WP-0004`. |
| Idle capacity | `resource:hosteurope:railiance01` and `resource:railiance:reef-railiance:k3s`, idle on every measured metric at 14 percent CPU and 37 percent memory. Five resources are unmeasurable. |
| Saturated capacity | None. |
| Forecast error | **Not yet computable.** The control-cycle mechanism is proven on paired examples, but no operational actual observation exists, so no variance is reported and none is fabricated. |
| Approaching commitments | None visible within 90 days — and the finding is that six active resources have **no** renewal or cancellation date at all, so no cancellation window can be respected. |
| Next action | The `next_actions` list: seven delegated workplans, the booked-cost dependency on `fin-hub`, and six missing contract-date records, each addressed to its owner. |
## Structural risk surfaced
The risk section reports concentration mechanically rather than in prose: six of
seven resources share `host:railiance01` and five share `cluster:reef-railiance`.
That includes every workload the proposed backup storage exists to protect,
which is the standing argument against same-provider placement recorded in
`opt:platform-audit-storage:2026-08`. Thresholds are explicit in the tool —
idle at or below 35 percent, saturated at or above 85 percent, renewal horizon
90 days, failure-domain concentration above two resources.
## Boundaries held
The report reads; it does not write to any other repository. Every unknown it
prints is attributed to the repository or authority that owns it, and the
`next_actions` list is the message sent back to those owners on the monthly
cadence. No booked financial fact is reproduced here; spend remains
`fin-hub`'s authority under
`docs/fin-hub-resource-control-contract-v0.1.md`.