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.1 KiB
RESOURCE-WP-0003 optimization cases — 2026-08-14
Result
RESOURCE-WP-0003-T06 established the review cadence, the decision template,
and a fail-closed evaluator for optimization cases, and validated the process
against the backup case and one non-storage portfolio candidate.
The implementation consists of:
schemas/optimization-case.schema.json— baseline and alternatives carry identical decision fields, so a comparison against an undescribed status quo is structurally impossible;tools/optimization.py— comparison, payback, failure-domain delta, verdicts, and decision-state validation;data/optimization/platform-audit-storage-2026-08.json— the storage case;data/optimization/reef-railiance-k3s-2026-08.json— the non-storage case;docs/optimization-cases.md— case types, decision template, cadence, and the loop that returns outcomes to the next forecast;- 25 tests in
tests/test_optimization.py, plus schema and case checks intools/validate.py.
Decision fields
T06 requires every recommendation to show baseline, alternative, one-time cost,
recurring infrastructure and labour cost, utilization, uncertainty,
service-level constraints, failure domains, exit path, and expected payback.
The schema requires all ten on every option, and the evaluator refuses to
recommend while any is null. Payback is computed from one-time cost and
realised monthly saving; it is never asserted.
Recurring cost is split into infrastructure, internal labour, and external labour. This is not cosmetic: in the storage case Hetzner has the lower infrastructure price (EUR 6.49 against EUR 7.35) and is still EUR 29.14 per month more expensive, entirely on operator hours. A comparison on unit price alone would have inverted the result.
Fail-closed behaviour
One unknown anywhere in the compared pair makes the comparison
blocked_on_evidence. Unknowns are null values plus a named unknowns list
that attributes each gap to an owning repository or authority. The evaluator
also refuses invalid decision states: a blocked case cannot be proposed or
approved, a decided case must name approver and approved_on, and a case
with no blockers cannot claim to be blocked.
reject is a cost verdict only. The three-node cluster option raises recurring
cost by design and buys availability instead; that argument belongs to the
deciding authority against a declared service objective, not to the calculator.
Case 1 — opt:platform-audit-storage:2026-08 (storage)
Baseline is Scaleway Standard Multi-AZ, the provisional primary from T02 due
diligence, at month-12 base-scenario demand from tools/cost_model.py.
| Option | Recurring EUR/month | Verdict |
|---|---|---|
| Scaleway Standard Multi-AZ (baseline) | 67.35 | — |
| Hetzner Object Storage | 96.49 | reject (+29.14) |
| Host Europe Cloud Storage | unknown | blocked_on_evidence |
Host Europe is blocked on four named gaps: current S3 orderability for this
account, five price fields, cancellation terms, and correlated-failure
acceptance. It has no known exit path, and it shares provider:host-europe
with the compute host the backup is meant to protect.
This case exercises the process against real cost-model output. It is
deliberately not the procurement decision, which RESOURCE-WP-0002-T03
owns and human financial authority approves. The case state is
blocked_on_evidence and recommends nothing.
Case 2 — opt:reef-railiance-k3s:2026-08 (non-storage)
Baseline is the current single-node k3s on railiance01, with the live capacity observation from T03 discovery: 0.564 of 4 vCPU, 5.83 of 15.62 GiB, 66.77 of 192.69 GiB root filesystem.
Utilization is genuinely low — 14 percent CPU, 37 percent memory — and that is a real rightsizing signal. Every comparison is nevertheless blocked, for two independent reasons the case records rather than works around:
- The railiance01 booked price is unknown, so no option has a recurring cost, no saving exists, and no payback can be computed.
- The utilization figure is a single sample taken on 2026-08-11. Mean usage is
not a sizing basis; peak load over a billing period is owed by
RAIL-BS-WP-0014.
Both alternatives — a smaller single server and the RAIL-BS-WP-0007 three-node
cluster — are recorded with their unknowns attributed to railiance-infra
(RAIL-HO-WP-0008) and railiance-cluster (RAIL-BS-WP-0014).
A case that refuses to conclude is the correct output here, and it is a useful one: it names exactly which evidence would unblock a rightsizing decision, and it is visible in the portfolio report until that evidence arrives.
Boundaries held
resource-control produced both cases and decided neither. Financial
implications reach fin-hub through financial_handoff under
docs/fin-hub-resource-control-contract-v0.1.md; neither case has sent one,
because neither is approved. Implementation is delegated through
decision.delegated_to, which names railiance-infra and railiance-cluster
for the cluster case. outcome.feeds_forecast binds each case to the
control-cycle records that will later show whether it was right.