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:
tegwick 2026-08-14 09:28:44 +02:00
parent 54dd45c926
commit 2c2a6073ff
63 changed files with 4662 additions and 69 deletions

View file

@ -0,0 +1,54 @@
# PostgreSQL backup demand and cost model — 2026-08-10
## Observed baseline
A read-only query against `platform-pg-1` at `2026-08-10T15:54:12Z` measured
39,573,871 bytes across connectable databases. `pg_stat_wal` reported
19,744,568 bytes since `2026-08-10T13:37:53Z`, an extrapolated 0.208 GB/day.
The cluster is less than one day old, so this is a seed observation rather than
a representative trend. No credential value was read or recorded.
The governed requirements are a 30-day recovery window, daily physical base
backup, continuous WAL archive, one monthly restore drill, and a complete exit
calculation. The scenario inputs live in
`data/demand/platform-audit-storage.json` and deliberately floor demand above
the tiny initial observation:
| Scenario | Initial DB | Monthly growth | WAL/day | Restore egress | Labor/month |
| --- | ---: | ---: | ---: | ---: | ---: |
| low | 1 GB | 5% | 0.25 GB | 1 GB | 0.5 h |
| base | 5 GB | 10% | 1 GB | 5 GB | 1 h |
| high | 20 GB | 20% | 5 GB | 20 GB | 2 h |
The conservative stored-byte formula is `30 × current database size + 30 ×
daily WAL`. It does not claim compression savings. Operator labor is valued at
€60/hour; provider-specific labor floors capture relative operational effort.
The exit event adds full stored-byte egress plus four operator hours.
Run `make forecast` for all 12 months, scenarios, and providers. A `null` total
is intentional: it means a required price is unknown and prevents an unknown
from silently becoming free.
The catalog also includes self-managed Garage on 13 Host Europe/Hetzner VMs
and managed AWS, Azure, Google Cloud, and STACKIT price points. See
`RESOURCE-WP-0002-expanded-storage-comparison-2026-08-10.md` for assumptions
and topology warnings.
Calculator rows split `monthly_infrastructure_eur` from
`monthly_internal_labor_eur` and split internal setup labor from external setup
services. The top-level `comparison_320gb` array provides a normalized running
cost at 320 GB using the base request and restore pattern.
## Initial comparison
- Scaleway Standard Multi-AZ is fully calculable at €0.01606/GB-month, with
75 GB/month free egress then €0.01/GB. Prices exclude tax.
- Hetzner is calculable while usage remains inside its €6.49 monthly minimum,
which includes 1 TB storage and 1 TB egress. Excess unit prices still need to
be captured before high-growth or exit usage crosses the included quota.
- Host Europe cannot be calculated until it confirms that the historical S3
Cloud Storage product is currently orderable and supplies a current quote.
Because labor dominates this very small workload, selection should emphasize
restore compatibility, independent failure domain, encryption, and exit proof
before sub-euro storage differences.

View file

@ -0,0 +1,106 @@
# Expanded object-storage comparison — 2026-08-10
This adds self-managed S3-compatible storage and four large-cloud price points
to the managed-provider comparison. All recurring totals include operator labor
at €60/hour. Taxes are excluded. USD prices use the 2026-08-10 ECB reference
rate of 1 EUR = 1.1555 USD.
## Self-managed reference architecture
Garage is the reference open-source implementation. It has an S3-compatible
API and is designed for distributed deployments. Garage explicitly says its
single-node quick-start has no redundancy and must not be used in production.
CNPG/Barman compatibility remains a live preflight requirement.
The initial fixed-size estimates use locally attached storage:
- Host Europe: 8 vCPU, 16 GB RAM, 400 GB NVMe at €37.99/month including 19%
VAT, normalized to €31.92 net per node. Network traffic is flat-rate.
- Hetzner: CX53, 16 vCPU, 32 GB RAM, 320 GB local SSD at €29.49/month plus
€0.50 IPv4, net per node. The June 2026 price adjustment is used.
Replication consumes the extra nodes; it does not multiply usable capacity.
All nodes at one provider/location still share provider and site failure risk.
| Topology | Infrastructure/month | Internal labor/month | Running total at 320 GB | Internal setup | External setup | Usable ceiling | Assessment |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | --- |
| Host Europe, 1 node | €31.92 | 2 h / €120 | €151.92 | 8 h / €480 | not quoted | 400 GB | no redundancy; not production |
| Host Europe, 2 nodes | €63.85 | 3 h / €180 | €243.85 | 12 h / €720 | not quoted | 400 GB | replicated, but poor failure/quorum shape |
| Host Europe, 3 nodes | €95.77 | 4 h / €240 | €335.77 | 16 h / €960 | not quoted | 400 GB | production candidate; single provider/site risk |
| Hetzner, 1 node | €30.09 | 2 h / €120 | €150.09 | 8 h / €480 | not quoted | 320 GB | no redundancy; not production |
| Hetzner, 2 nodes | €60.18 | 3 h / €180 | €240.18 | 12 h / €720 | not quoted | 320 GB | replicated, but poor failure/quorum shape |
| Hetzner, 3 nodes | €90.27 | 4 h / €240 | €330.27 | 16 h / €960 | not quoted | 320 GB | production candidate; single location risk |
These sizes cover the base scenario's first month (180 GB), but not its month
12 estimate (458 GB). The calculator therefore returns `null` once the fixed
capacity is exceeded. A larger Host Europe 800 GB node tier or Hetzner Volumes
would be required; obtain account quotes before treating that expansion as a
decision price. Hetzner also documents that its Volumes are already replicated
across three physical servers, which means combining three Garage replicas with
three replicated Volumes would buy nested redundancy at additional cost.
## Managed object-storage price points
Azure Blob and Google Cloud Storage are Barman-supported object stores but are
not S3-compatible APIs. AWS and STACKIT are direct S3 API comparisons. The
following table fixes stored volume at **320 GB**, uses the base request pattern
(2,500 writes and 1,000 reads/month), and includes one 5 GB restore drill. This
puts elastic per-GB products, Hetzner's bundled minimum, and Garage's fixed
capacity on the same running-cost basis.
| Service | Infrastructure at 320 GB | Internal labor/month | Running total at 320 GB | Internal setup | External setup |
| --- | ---: | ---: | ---: | ---: | ---: |
| Scaleway Standard Multi-AZ | €5.14 | 1 h / €60 | **€65.14** | none | €0 assumed |
| Hetzner Object Storage | €6.49 | 1.5 h / €90 | **€96.49** | none | €0 assumed |
| AWS S3 Standard, Frankfurt | €6.80 | 1.5 h / €90 | **€96.80** | 4 h / €240 | €0 assumed |
| STACKIT Object Storage Premium-EU01 | €8.52 | 1.5 h / €90 | **€98.52** | 4 h / €240 | €0 assumed |
| Google Cloud Storage Standard, Frankfurt | €6.05 | 2 h / €120 | **€126.05** | 6 h / €360 | €0 assumed |
| Azure Blob Hot ZRS, Germany West Central | €6.72 | 2 h / €120 | **€126.72** | 6 h / €360 | €0 assumed |
Cloud request costs are negligible here; operator effort and egress assumptions
matter more. Azure/GCP egress figures are explicit planning estimates rather
than captured retail meters, so they must be refreshed in an account calculator
before decision approval.
"Internal setup" values the federation's own implementation time at €60/hour.
"External setup" means paid consulting, vendor professional services, or a
contractor. No such service is assumed for managed self-service onboarding. It
is **not quoted**, rather than zero, for Garage because an external security or
operations review may be prudent and no scope or rate has been obtained.
The apparent difference between the earlier €62.89 Scaleway total and the
normalized €5.14 infrastructure figure is reconciled in
`docs/forecast-actual-control.md`: €62.89 is 180 GB infrastructure (€2.89) plus
€60 labor, while €5.14 is infrastructure alone at 320 GB. The comparable 320 GB
total is €65.14.
## Interpretation
Self-management does not win at this workload once even two hours/month of
patching, monitoring, certificate handling, upgrades, disk replacement,
capacity management, and restore support are valued. Three-node Garage costs
roughly €330€336/month plus €960 setup labor and still shares a provider/site
failure domain. It may become attractive if the platform wants the capability
for broader workloads, can amortize operations across them, or deliberately
values open-source control above the cost difference.
For this backup alone, Scaleway remains the lowest modeled managed option.
STACKIT is especially interesting as a sovereign three-AZ S3-compatible
alternative: its documentation now states automatic replication across all
three availability zones, versioning, lifecycle rules, server-side encryption,
bucket policies, and Object Lock.
## Primary sources
- Host Europe VM pricing: https://www.hosteurope.de/Server/Virtual-Server/
- Hetzner June 2026 pricing: https://docs.hetzner.com/general/infrastructure-and-availability/price-adjustment/
- Hetzner Volume replication: https://docs.hetzner.com/cloud/volumes/overview/
- Garage single-node warning: https://garagehq.deuxfleurs.fr/documentation/
- AWS S3 price list: https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonS3/current/eu-central-1/index.json
- AWS egress/free allowance: https://aws.amazon.com/ec2/pricing/on-demand/
- Azure retail pricing API: https://learn.microsoft.com/en-us/rest/api/cost-management/retail-prices/azure-retail-prices
- Google Cloud Storage pricing: https://cloud.google.com/storage/pricing
- STACKIT storage pricing: https://www.stackit.de/de/preise__trashed/cloud-services/iaas/stackit-storage/
- STACKIT object-storage capabilities: https://docs.stackit.cloud/de/products/storage/object-storage/basics/introduction/
- STACKIT network pricing: https://www.stackit.de/de/preise__trashed/cloud-services/iaas/stackit-network/
- ECB daily FX rate: https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml

View file

@ -0,0 +1,71 @@
# Object-storage provider due diligence — 2026-08-10
Status vocabulary: `yes`, `no`, `unknown`, or `test`. `Test` means documentation
is promising but the live CNPG/Barman preflight remains mandatory.
| Requirement | Host Europe Cloud Storage | Scaleway Standard Multi-AZ | Hetzner Object Storage |
| --- | --- | --- | --- |
| Currently orderable for account | unknown — written confirmation required | yes | yes |
| S3-compatible HTTPS / SigV4 | unknown | yes / test | yes / test |
| EU region considered | unknown | Amsterdam `nl-ams` | Nuremberg `nbg1` |
| Different provider from reef-railiance | no | yes | yes |
| Multi-AZ / availability | unknown | yes; 99.9% service availability | unknown; docs describe Ceph and infrastructure redundancy, not a quantified service SLA |
| Published durability | unknown | 99.999999999% | unknown |
| Scoped access key | unknown | yes; bucket policy test required | yes; key defaults to all project buckets, bucket policy required |
| Private bucket | unknown | yes | yes |
| Multipart/list/get/put/delete | unknown | yes / test | yes / test |
| Versioning | unknown | yes | yes |
| Lifecycle expiration | unknown | yes | yes |
| Object lock | unknown | yes; cannot later disable | yes; enable at bucket creation |
| TLS encryption | unknown | yes; enforceable by bucket policy | yes / test |
| Encryption at rest | unknown | yes: SSE-ONE, SSE-C, or SSE-KMS | **no default**; SSE-C is documented |
| Initial 100 GiB without long commitment | unknown | yes, usage-based | yes, hourly base billing |
| Operations pricing | unknown | no separate request charge found; confirm invoice model | PUT/GET/DELETE free |
| Storage / egress pricing | unknown | €0.01606/GB-month; 75 GB egress free, then €0.01/GB | €6.49 minimum includes 1 TB storage and 1 TB egress; excess prices still to capture |
| Cancellation / support terms | unknown | contract review required | contract review required |
| Provider status visibility | unknown | yes | yes |
| CNPG 1.25/Barman compatibility | unknown | test | test |
## Evidence
- Host Europe Backup Storage supports FTP, SCP, SFTP, and rsync, so it is a
secondary logical-copy candidate, not the primary Barman object store:
https://www.hosteurope.de/faq/server/virtual-server/backup-storage/
- Host Europe's S3 claim is currently only backed by an older specification:
https://www.hosteurope.de/download/PVL/Preis_und_Leistungsverzeichnis_CloudStorage_1-0-1.pdf
- Scaleway pricing: https://www.scaleway.com/en/pricing/storage/
- Scaleway capabilities and durability:
https://www.scaleway.com/en/object-storage/
- Scaleway regions/lifecycle/multipart:
https://www.scaleway.com/en/docs/object-storage/concepts/
- Scaleway object lock:
https://www.scaleway.com/en/docs/object-storage/how-to/use-object-lock/
- Hetzner overview, endpoints, quotas, operations, and limits:
https://docs.hetzner.com/storage/object-storage/overview/
- Hetzner supported S3 actions and encryption limitation:
https://docs.hetzner.com/storage/object-storage/supported-actions/
- Hetzner encryption FAQ:
https://docs.hetzner.com/storage/object-storage/faq/general/
- CNPG 1.25 S3-compatible endpoint and lifecycle guidance:
https://cloudnative-pg.io/docs/1.25/appendixes/object_stores/
## Blocking evidence requests
1. Host Europe: ask account support to confirm current orderability, endpoint,
region, SigV4, supported API, versioning/lifecycle, encryption, durability,
availability, price, support, and cancellation terms in writing.
2. Scaleway and Hetzner: obtain account-visible contractual/support terms and
confirm tax treatment. Capture Hetzner excess prices.
3. Run a disposable live preflight for each finalist: private bucket, scoped
positive and negative credentials, multipart CRUD, versioning/lifecycle,
Barman empty-WAL-archive check, and deletion/exit behavior.
## Provisional conclusion
Host Europe is not selectable as primary while current S3 orderability is
unknown. Hetzner fails the current acceptance requirement for provider-managed
encryption at rest unless client-side/SSE-C custody is explicitly accepted.
Scaleway Standard Multi-AZ is therefore the provisional primary, subject to a
live Barman preflight, contract review, and human purchase approval. Hetzner
remains a price comparator; Host Europe Backup Storage or the governed
Nextcloud lane remains the independent logical-copy candidate.

View file

@ -0,0 +1,25 @@
# RESOURCE-WP-0003 delegated evidence workplans — 2026-08-11
## Result
Every owned gap from the initial portfolio discovery now points to a live,
repository-local work record. Resource-control retains the inventory,
forecast, actual-observation, allocation, and optimization contract; source
repositories retain authority for infrastructure and workload evidence; and
fin-hub retains booked financial facts.
| Evidence owner | Workplan | State Hub workplan ID | Interface outcome |
|---|---|---|---|
| railiance-infra | `RAIL-HO-WP-0008` | `7122657f-87c8-46b5-a725-a1af1ba0af12` | Host identity, lifecycle, commercial and host-capacity evidence |
| railiance-cluster | `RAIL-BS-WP-0014` | `ea6ec98a-0d65-4afa-b6c5-6e7ed34011ac` | Cluster capacity, utilization, storage/failure-domain and allocation evidence |
| railiance-forge | `RAILIANCE-WP-0002` | `72f935a5-d921-48a4-96e4-2365556c7374` | Forgejo demand, utilization, labor/SLO and allocation evidence |
| railiance-platform | `RAILIANCE-WP-0016` | `49084fb8-de63-4f32-a4a9-3a42d4e708ac` | apps-pg utilization, recovery, labor and consumer evidence |
| coulomb-social | `CSOC-WP-0005` | `00de1578-6150-40d3-b193-e852666ed945` | Workload forecasts, observations, objectives and labor evidence |
| rapp-qonto | `RAPP-QONTO-WP-0002` | `25b3b715-9a56-499e-a85c-a09ebd9bbb79` | Scale-to-zero usage, external service cost inputs and labor evidence |
| fin-hub | `FIN-WP-0004-T04..T06` | `67b6de6c-4820-4478-9789-f50260204c27` | Budgets/constraints, forecast-to-actual loop and generalized attribution |
The authoritative machine-readable mapping is
`data/portfolio-coverage-2026-08-11.json`. State Hub synchronization completed
without failures. Its warnings concern pre-existing fleet prefix collisions,
unregistered legacy task prefixes, and missing optional DoR metadata; none
prevented registration of these plans.

View file

@ -0,0 +1,64 @@
# RESOURCE-WP-0003 fin-hub contract preflight
Date: 2026-08-11
Resource-control task: `RESOURCE-WP-0003-T02`
Fin-hub tasks: `FIN-WP-0004-T01`, `T02`, `T03`, `T07`, `T08`, `T09`
Fin-hub commit: `0034330`
## Result
Resource-control accepts the authority and schema boundary in the joint v0.1
contract. Fin-hub's remediation was reviewed against the timestamped
assessment and its full suite passed:
```text
46 passed, 1 third-party deprecation warning
```
Resource-control's suite passed after adding its producer-owned schema,
forecast exporter, booked-cost consumer validation, and reconciliation seam:
```text
13 passed
resource-control declarations: valid
```
## Cross-repository check
The live immutable backup forecast
`data/forecasts/platform-audit-storage-scaleway-base-2026-08.json` was processed
through both implementations using:
- resource-control `tools/financial_exchange.py::forecast_records`; and
- fin-hub `fin_hub.services.exchange::ingest_resource_forecast`.
Observed result:
```json
{
"producer_consumer_records": 12,
"idempotent_store_rows": 12,
"payloads_equal": true,
"booked_cost_gate": "awaits attributable provider fact"
}
```
Replaying the same forecast did not add rows. All canonical record payloads
matched, including IDs, periods, cost breakdown, attribution, assumptions, and
provenance reference.
## Residual acceptance gate
This preflight proves the planning direction; it is not evidence of purchased
storage or actual spend. `FIN-WP-0004-T05` remains waiting until
`RESOURCE-WP-0002` produces a real provider financial fact attributable to
`platform:audit-storage`. That round trip must then demonstrate:
1. exactly one authoritative booked fact in fin-hub;
2. a non-ledger projection consumed by resource-control;
3. a join to the immutable forecast and technical observation;
4. infrastructure-cost variance with the financial fact ID preserved; and
5. duplicate delivery and any correction leaving effective totals correct.
Synthetic records remain suitable for automated contract tests but cannot
satisfy this operational gate.

View file

@ -0,0 +1,36 @@
# RESOURCE-WP-0003 generalized control cycle — 2026-08-11
## Result
`RESOURCE-WP-0003-T05` generalized the backup-specific forecast-to-actual
method into a provider-neutral portfolio contract.
The implementation consists of:
- `schemas/resource-control-cycle.schema.json` for immutable forecast and
actual records;
- `tools/control_cycle.py` for resource-neutral comparison and controlled
variance attribution;
- six paired examples covering storage, fixed cluster compute, and a hybrid
shared PostgreSQL service;
- tests for the three resource classes, immutable forecast binding, explicit
cost attribution, and fail-closed data-quality handling;
- updated operating guidance in `docs/forecast-actual-control.md`.
## Boundary with fin-hub
Actual records carry `booked_cost_refs`; resource-control does not reproduce
the ledger fact. Fin-hub message `d33f2452-8dc6-4249-a3d2-84fda938103a`
confirmed explicit `financial_fact_id -> resource_id` binding, budget and
constraint signals, and generalized exchange health. The first operational
backup round trip remains correctly gated on `RESOURCE-WP-0002` procurement;
that does not invalidate these illustrative contract fixtures.
## Verification
- `make test`: 25 tests passed and declarations validated.
- All three example pairs completed through `make control-cycle`.
- `git diff --check`: clean.
The examples are intentionally marked illustrative. Their values must not be
reported as actual consumption or booked cost.

View file

@ -0,0 +1,81 @@
# RESOURCE-WP-0003 initial portfolio discovery
Date: 2026-08-11
Task: `RESOURCE-WP-0003-T03`
Coverage data: `data/portfolio-coverage-2026-08-11.json`
## Result
The first real portfolio slice contains seven inventory records:
| Resource | Owner | Role |
| --- | --- | --- |
| `resource:hosteurope:railiance01` | `railiance-infra` | provider compute host |
| `resource:railiance:reef-railiance:k3s` | `railiance-cluster` | shared single-node Kubernetes runtime |
| `resource:railiance:forgejo` | `railiance-forge` | Helix Forge source/package infrastructure |
| `resource:railiance:apps-pg` | `railiance-platform` | shared application database service |
| `resource:tenant:coulomb:coulomb-social` | `coulomb-social` | Coulomb reference-tenant application |
| `resource:tenant:friendly:binky:rapp-qonto` | `rapp-qonto` | representative tenant workload |
| `resource:platform:audit-storage` | `resource-control` | proposed backup storage |
Helix Forge does not itself operate production infrastructure; its repository
scope explicitly delegates runtime operation. Its current infrastructure
coverage is therefore the shared Forgejo service and its underlying cluster
and host, not a fictional Helix Forge server.
## Live substrate observation
A read-only observation of `railiance01` and the reef-railiance Kubernetes API
at `2026-08-11T09:05:25Z` confirmed:
- one Ready k3s control-plane/etcd node on `railiance01`;
- 4 allocatable vCPU, approximately 15.62 GiB allocatable memory, 183.06 GiB
allocatable ephemeral storage, and a 110-pod limit;
- node usage of 564m CPU and 5,975 MiB memory at observation time;
- a 192.69 GiB root filesystem, 66.77 GiB used;
- active Forgejo and Coulomb Social deployments with one ready replica each;
- active `apps-pg` with one ready CNPG instance and a 10 GiB volume;
- a healthy `rapp-qonto` Knative Service with min-scale 0 and max-scale 1;
- a continuously running Qonto egress proxy; and
- all discovered persistent volumes using `local-path`, therefore sharing the
host failure domain.
No credential values or secret-bearing resources were read or recorded.
## Source authority
- `railiance-cluster` owns the k3s runtime and publishes the substrate profile.
- `railiance-apps` supplies current Forgejo and Coulomb Social deployment
values; `railiance-forge` is the declared forge-operation owner.
- `railiance-platform` owns the shared applications PostgreSQL definition.
- `coulomb-social` owns tenant and application behavior.
- `rapp-qonto` owns the Binky tenant binding, resource requests, Knative
package, and runtime requirements.
- the live operating system and Kubernetes API supplied timestamped capacity
and workload-state evidence.
## Material findings
The portfolio currently has one physical/virtual host and one Kubernetes node.
Compute, local persistent storage, databases, Forgejo, Coulomb Social, and the
tenant workload therefore share one provider/host failure domain. The planned
ThreePhoenix HA work remains backlog; the inventory does not describe its
target three nodes as current capacity.
The active cluster has significant point-in-time headroom, but a single CPU and
memory sample is not a utilization history and cannot support rightsizing.
Commercial identifiers, booked server price, renewal dates, operations labor,
and shared allocation methods remain unknown.
Each gap has an authoritative repository owner in the coverage data. Creating
live delegated work records for those gaps is `RESOURCE-WP-0003-T04`; this
discovery does not silently assign implementation through prose.
## Verification
```text
20 tests passed
resource-control declarations: valid
all inventory relationships resolve
git diff --check: pass
```

View file

@ -0,0 +1,104 @@
# 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.

View file

@ -0,0 +1,71 @@
# RESOURCE-WP-0003 portfolio model v0.2
Date: 2026-08-11
Task: `RESOURCE-WP-0003-T01`
Schema: `schemas/resource-inventory.schema.json`
## Result
The inventory model is generalized from a storage purchase record into a
managed-infrastructure portfolio record. Version 0.2 represents:
- provider-managed elastic storage;
- self-managed services hosted on rented capacity;
- Kubernetes or other shared capacity;
- shared platform services; and
- future compute, network, database, managed-service, and license records.
The existing proposed Scaleway backup resource was migrated as the only
authoritative inventory record. The Garage, Kubernetes-capacity, and ingress
records live under `examples/portfolio/`, carry `record_scope: example`, and
contain explicit example evidence. They are schema proofs, not claims about
live infrastructure.
## Model decisions
- Resource identity uses the stable `resource:` namespace independently of
provider-native identifiers.
- Lifecycle separates proposed, ordered, commissioning, active, suspended,
retiring, retired, and rejected states.
- Provider-managed, self-managed, and shared-capacity management models are
explicit.
- Capacity is a set of typed dimensions and distinguishes provisioned, usable,
allocated, observed, limiting, and unknown values.
- Ownership supports multiple workloads, optional tenant identity, and a
dedicated, shared, or unattributed allocation mode.
- Shared allocations require a driver and versioned method. Unknown allocation
remains explicit rather than receiving an invented key.
- Relationships express hosting, composition, dependency, replacement,
capacity consumers, and backup placement without embedding another
repository's graph authority.
- Requirements and evidence carry their kind, reference, observation date,
and authoritative source.
- Exit path is mandatory for every resource class.
## Semantic controls
`tools/portfolio.py` adds controls not conveniently expressed as shape alone:
- valid lifecycle transitions;
- ordered lifecycle dates;
- commissioned dates for operational resources;
- order evidence for operational provider-managed resources;
- allocation-key and shared-driver consistency;
- unique capacity metric/kind dimensions;
- prevention of self-relationships; and
- unmistakable example evidence.
Verification:
```text
18 tests passed
resource-control declarations: valid
git diff --check: pass
```
## Next use
`RESOURCE-WP-0003-T03` should now discover real portfolio records for Helix
Forge, Coulomb Social, shared Railiance services, and one representative tenant
workload. It must replace example assumptions with source evidence and preserve
unknown values where authority is not yet available.

View file

@ -0,0 +1,74 @@
# 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`.

View file

@ -0,0 +1,47 @@
# fin-hub ↔ resource-control contract v0.1 — resource-control ratification
Status: authority and schema boundary accepted on 2026-08-11
Fin-hub implementation reviewed: commit `0034330`
Workplans: `RESOURCE-WP-0003-T02`, `FIN-WP-0004`
The jointly reviewed contract is maintained in fin-hub at
`docs/fin-resource-authority-contract-v0.1.md`. This record is the
resource-control-side ratification and identifies the artifacts for which this
repository is authoritative.
## Authority
- fin-hub owns booked financial facts and corrections, tax and currency
treatment, budgets, commitments, burn, runway, and viability signals.
- resource-control owns resource identity and lifecycle, technical usage,
allocation evidence, demand and cost forecasts, and optimization evidence.
- workload and platform repositories remain authoritative for native workload
identity, service requirements, provisioning, operation, and source
telemetry.
- neither repository approves contracts, executes payment, or turns planning
evidence into booked spend.
## Artifacts
- `schemas/planning-evidence.schema.json` is the authoritative
resource-control outbound schema.
- `tools/financial_exchange.py forecast` converts the existing immutable
monthly backup forecast into canonical `ForecastEvidence` records.
- `tools/financial_exchange.py reconcile` validates fin-hub booked-cost
projections and compares attributable infrastructure cost by accounting
period. Booked facts are referenced projections here, never a second ledger.
- `schemas/monthly-resource-observation.schema.json` uses
`usage_observation` for technical observations. “Booked actual” is reserved
for fin-hub facts.
Fin-hub owns its outbound `BookedCostEvidence` executable schema. This
repository validates the contract fields and arithmetic it consumes, but does
not redefine financial authority.
## Acceptance boundary
The 12-row `platform:audit-storage` forecast can complete an idempotent
planning-evidence preflight before procurement. `FIN-WP-0004-T05` and the
operational round trip remain open until an attributable provider charge or
credit exists. Fixture or synthetic money may test the seam but cannot satisfy
that evidence gate.

View file

@ -0,0 +1,123 @@
# Forecast-to-actual resource control
## Why the €2.89, €5.14, €62.89, and €65.14 figures differ
They describe two volumes and two cost scopes:
| Figure | Stored volume | Scope | Calculation |
| --- | ---: | --- | --- |
| €2.89 | 180 GB | infrastructure only | 180 × €0.01606 |
| €62.89 | 180 GB | infrastructure + internal labor | €2.89 + 1 h × €60 |
| €5.14 | 320 GB | infrastructure only | 320 × €0.01606 |
| €65.14 | 320 GB | infrastructure + internal labor | €5.14 + 1 h × €60 |
The older €62.89 estimate was not “storage without elastic cost”; it already
included the €60 monthly operator allowance. The normalized table introduced a
different stored volume and showed infrastructure separately. Future reports
must always label both `stored_gb` and cost scope.
## Control records
A forecast is a timestamped, immutable record of what was believed at decision
time. The initial base forecast is
`data/forecasts/platform-audit-storage-scaleway-base-2026-08.json`. Do not edit
it after actual evidence exists. If assumptions change, create a new forecast
with a new creation date and retain the prior one so forecast accuracy remains
auditable.
After every billing month, record a technical `usage_observation` under
`data/actuals/`. Authoritative booked financial facts come from fin-hub and
are joined by reference; resource-control does not originate a second booked
actual.
The required cost and usage proxies are:
- database size and provider stored bytes;
- WAL volume;
- write and read requests;
- restore-test egress;
- infrastructure invoice cost;
- internal operations hours and valued labor cost;
- total attributable cost;
- backup success, maximum observed RPO, and restore RTO when measured.
Provider stored bytes are intentionally distinct from logical database size.
They expose base-backup retention, WAL, compression, versioning, incomplete
multipart uploads, and lifecycle behavior. Invoice cost is distinct from the
provider's usage estimator and must reconcile to non-secret billing evidence.
## Error calculation and review
`make variance ACTUAL=data/actuals/YYYY-MM.json` reports signed error and
absolute percentage error for each numeric proxy. Initially review rather than
automatically rewrite assumptions:
- investigate infrastructure cost error above 10%;
- investigate stored-byte or WAL error above 20%;
- investigate any unplanned egress or request-class charge;
- investigate labor error above 1 hour or 25%;
- investigate every backup failure, RPO breach, or restore-RTO regression.
After three comparable months, calculate mean absolute percentage error by
proxy and recalibrate the next forecast. Avoid MAPE where the forecast is zero;
use absolute error and explain the new activity instead. Separate forecast
error from price variance: a bill can differ because usage was wrong, the rate
changed, tax/discount treatment differed, or an unmodeled SKU appeared.
Quarterly provider comparison should use the latest actual trailing three
months, the next 12-month forecast, one monthly restore, an exit event, and
observed—not aspirational—operator labor.
## General portfolio control record
The storage-specific v0.1 observation remains valid for the backup procurement
case. New portfolio controls use
`schemas/resource-control-cycle.schema.json`, whose resource-specific
`usage_proxies` allow the same comparison mechanism to cover storage, VMs or
cluster compute, shared platform services, managed services, and future
resource types without pretending they share the same utilization unit.
Each record separates:
- provisioned and used capacity, with a fixed, elastic, or hybrid model;
- infrastructure, internal labor, and external labor cost;
- booked financial facts, referenced rather than copied from fin-hub;
- allocation method, driver, version, and unattributed residual;
- service constraints and their units;
- low/base/high forecast scenario or observed actual;
- evidence and uncertainty.
Forecast records are append-only. A changed forecast receives a new
`record_id`, creation time, and `revision_of` reference. Actuals must name the
exact original `forecast_ref`; a later revision must never replace the
decision-time baseline when measuring forecast error.
Run a generic comparison with:
```sh
make control-cycle FORECAST=examples/control-cycle/storage-forecast.json \
ACTUAL=examples/control-cycle/storage-actual.json
```
The examples cover storage, `reef-railiance` cluster compute, and the shared
`apps-pg` service. Their numbers are illustrative contract fixtures, not booked
facts. Operational records replace their evidence references after the owner
workplans publish observations.
## Variance attribution
Every material variance is assigned to one of six controlled categories:
- `demand`: the amount of consumed service differed;
- `provider_price`: rate, discount, tax, currency, or billed SKU differed;
- `allocation`: a shared-cost driver or attribution changed;
- `labor`: internal or external effort differed;
- `model`: a formula, assumption, capacity behavior, or omitted component was
wrong;
- `data_quality`: evidence is missing, late, inconsistent, or uses a different
unit.
The comparator defaults usage differences to demand, infrastructure cost to
provider price, and labor fields to labor, while preserving explicit
attribution supplied with the actual. Missing proxies and unit mismatches fail
closed as data-quality errors. Attribution explains an error; it does not
rewrite the forecast.

105
docs/optimization-cases.md Normal file
View file

@ -0,0 +1,105 @@
# Optimization cases — review cadence and decision template
`resource-control` produces optimization cases. It does not approve them and it
does not implement them. A case turns portfolio evidence into a reproducible
comparison; a human or repository authority decides; the owning platform or
workload repository implements; `fin-hub` records the money.
Schema: `schemas/optimization-case.schema.json`.
Evaluator: `tools/optimization.py`. Cases live in `data/optimization/`.
## Case types
| Type | Question it answers |
|---|---|
| `rightsizing` | Is provisioned capacity materially larger or smaller than sustained demand? |
| `consolidation` | Can separate resources share one substrate without breaking failure domains? |
| `commitment` | Does a term or reserved commitment beat on-demand pricing at forecast demand? |
| `renewal` | Should this contract renew, renegotiate, or lapse? |
| `migration` | Should the workload move to different capacity at the same provider? |
| `retirement` | Is this resource still serving anything? |
| `provider_switch` | Should the same service come from a different provider? |
## Decision template
Every option — the baseline included — must present the same fields. The
baseline is a full option, not a footnote, because a comparison against an
undescribed status quo is not a comparison.
1. **Baseline** — what is in place now, on the same terms as every alternative.
2. **Alternatives** — at least one, each independently costed.
3. **One-time cost** — migration, setup, dual-running, and the labour to do it.
4. **Recurring cost** — split into infrastructure, internal labour, and external
labour. A cheaper unit price that doubles operator hours is not a saving.
5. **Utilization** — provisioned and used per capacity metric, with the
observation that supports it.
6. **Uncertainty**`low`, `medium`, or `high`, with the reasons written out.
7. **Service-level constraints** — what the option must still satisfy.
8. **Failure domains** — the evaluator reports which the alternative removes and
which it newly introduces.
9. **Exit path** — how to leave the option. An option with no known exit path is
blocked, not merely riskier.
10. **Expected payback** — computed, never asserted.
### Unknowns are first-class
Any unknown cost, utilization, or exit path is `null`, and each blocking gap is
named in the option's `unknowns` list with the repository or authority that owns
it. The evaluator is fail-closed: one unknown makes the affected comparison
`blocked_on_evidence` rather than optimistic. A case that cannot conclude is a
valid, useful output — it names exactly what evidence would unblock it.
### Verdicts
| Verdict | Meaning |
|---|---|
| `blocked_on_evidence` | A required decision field is unknown. No recommendation. |
| `recommend` | Fully costed and saves more than EUR 5 per month. |
| `no_material_change` | Fully costed, difference within EUR 5 per month. |
| `reject` | Fully costed and more expensive than the baseline. |
`reject` is a cost verdict only. An option that costs more may still be right —
the three-node cluster case buys availability, not savings — and that argument
belongs in `decision.rationale`, made by the deciding authority against a
declared service objective, not by the calculator.
### Decision states
`blocked_on_evidence``proposed``approved` | `rejected``superseded`.
The evaluator enforces the transitions it can check: a case cannot be `proposed`
while any comparison is blocked, cannot be `approved` while blocked, and cannot
be decided without a named `approver` and `approved_on`.
## Cadence
| Rhythm | Trigger | Scope |
|---|---|---|
| Monthly | `cadence` | Review variance from `tools/control_cycle.py`. Open a case where forecast error is attributed to demand, price, or allocation rather than data quality. |
| Quarterly | `cadence` | Re-run every open case against refreshed evidence. Recompute all provider comparisons; a stale price is not evidence. |
| Pre-renewal | `renewal` | Open at least 60 days before `lifecycle.renews_on` or `cancel_by`, whichever is earlier, so cancellation stays possible. |
| On variance | `variance` | Sustained variance beyond the thresholds in `docs/forecast-actual-control.md`. |
| On demand | `request`, `procurement`, `incident` | A workload repository, a procurement decision, or an incident that exposed a failure domain. |
## Closing the loop
An approved case is not finished when it is approved.
1. `financial_handoff` carries the cost attribution key and the reference to
`fin-hub` under the contract in `docs/fin-hub-resource-control-contract-v0.1.md`.
2. `decision.delegated_to` names the repositories that implement. Implementation
detail is theirs; this repository states the interface and the acceptance
evidence only.
3. `outcome.feeds_forecast` names the control-cycle forecast records the decision
changes. The original forecast is never overwritten — a decision produces a
revision, per `docs/forecast-actual-control.md`.
4. `outcome.actual_refs` collects the monthly actuals that later show whether the
predicted saving materialised. A case whose actuals never arrive is an
unverified case, and the next quarterly review should say so.
## Current cases
| Case | Type | State | Why |
|---|---|---|---|
| `opt:platform-audit-storage:2026-08` | `provider_switch` | `blocked_on_evidence` | Hetzner computes and is EUR 29.14 per month dearer than Scaleway at month-12 base demand, on labour rather than storage price. Host Europe has no usable price, no cancellation terms, and shares a failure domain with the host it would protect. The procurement decision itself belongs to `RESOURCE-WP-0002-T03`. |
| `opt:reef-railiance-k3s:2026-08` | `rightsizing` | `blocked_on_evidence` | Observed utilization is 14 percent CPU and 37 percent memory — a real signal from one sample. Nothing can be costed while the railiance01 booked price is unknown, so no payback exists. Blocked against `RAIL-HO-WP-0008` and `RAIL-BS-WP-0014`. |

View file

@ -0,0 +1,74 @@
# 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_eur` is `null`, not `0`.** 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 until `fin-hub` delivers booked facts
under `docs/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-0008` and `FIN-WP-0004`.
- **Idle or saturated capacity?** `railiance01` and the `reef-railiance` k3s
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_actions` list, 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.