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>
104 lines
5.1 KiB
Markdown
104 lines
5.1 KiB
Markdown
# 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 in
|
|
`tools/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:
|
|
|
|
1. The railiance01 booked price is unknown, so no option has a recurring cost,
|
|
no saving exists, and no payback can be computed.
|
|
2. 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.
|