feat(portfolio): fold in RAILIANCE-WP-0016 apps-pg evidence
First delegated evidence from RESOURCE-WP-0003-T04 to land. railiance-platform
delivered apps-pg capacity, utilization, consumers, and the apps-pg-dbbytes-v1
allocation driver, and correctly delivered no EUR.
- data/resources/apps-pg.json: real capacity; allocation unattributed -> shared
under apps-pg-dbbytes-v1; second consumer vergabe-teilnahme registered
- data/control-cycle/apps-pg-2026-09-base.json: first operational control-cycle
record in the repository
- examples/control-cycle/apps-pg-*.json retired; the invented fixture collided
with the real record's identifier
- data/portfolio-coverage-2026-08-14.json: gap marked delivered with three
residual unknowns still open
The real evidence exposed a design gap in the T05 schema: v0.1 required a number
for every cost field, so recording genuine usage without a booked cost meant
inventing one. Schema 0.2 permits null costs, null unattributed_eur, a technical
unattributed_share, and null measurements. Null is unknown, never zero; an
unknown component makes the total null rather than the sum of the known parts;
and the comparator classifies unknown amounts as data_quality instead of
computing a variance. Existing 0.1 records are not rewritten.
apps-pg is now measured (idle at 5.8% of volume) and attributed, and remains
unpriced: delivered technical evidence does not create a booked cost.
86 tests pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 09:36:57 +02:00
|
|
|
import json
|
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
|
|
|
import sys
|
|
|
|
|
import unittest
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
sys.path.insert(0, str(Path(__file__).parents[1] / "tools"))
|
|
|
|
|
from control_cycle import compare
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def record(kind="forecast", resource_class="storage"):
|
|
|
|
|
result = {
|
|
|
|
|
"record_id": f"test:{kind}", "record_type": kind,
|
|
|
|
|
"resource_id": "resource:test", "resource_class": resource_class,
|
|
|
|
|
"period": "2026-09", "usage_proxies": {"stored_gb": {"value": 100, "unit": "GB-month"}},
|
|
|
|
|
"costs": {"currency": "EUR", "infrastructure": 10, "internal_labor": 60, "external_labor": 0, "total": 70},
|
|
|
|
|
"allocation": {"method": "direct", "driver": "stored_gb", "method_version": "1", "unattributed_eur": 0},
|
|
|
|
|
}
|
|
|
|
|
if kind == "actual":
|
|
|
|
|
result["forecast_ref"] = "test:forecast"
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ControlCycleTest(unittest.TestCase):
|
|
|
|
|
def test_same_mechanism_supports_required_resource_classes(self):
|
|
|
|
|
for resource_class in ("storage", "cluster_compute", "shared_platform_service"):
|
|
|
|
|
forecast = record(resource_class=resource_class)
|
|
|
|
|
actual = record("actual", resource_class)
|
|
|
|
|
actual["usage_proxies"]["stored_gb"]["value"] = 120
|
|
|
|
|
result = compare(forecast, actual)
|
|
|
|
|
self.assertEqual(resource_class, result["resource_class"])
|
|
|
|
|
self.assertEqual("demand", result["usage_proxies"]["stored_gb"]["category"])
|
|
|
|
|
|
|
|
|
|
def test_explicit_attribution_and_cost_split_are_preserved(self):
|
|
|
|
|
forecast, actual = record(), record("actual")
|
|
|
|
|
actual["costs"].update(infrastructure=12, internal_labor=90, total=102)
|
|
|
|
|
actual["variance_attribution"] = {"costs.infrastructure": "model", "costs.internal_labor": "labor"}
|
|
|
|
|
result = compare(forecast, actual)
|
|
|
|
|
self.assertEqual("model", result["costs"]["infrastructure"]["category"])
|
|
|
|
|
self.assertEqual(30, result["costs"]["internal_labor"]["error"])
|
|
|
|
|
|
|
|
|
|
def test_rejects_wrong_forecast_reference(self):
|
|
|
|
|
forecast, actual = record(), record("actual")
|
|
|
|
|
actual["forecast_ref"] = "test:other"
|
|
|
|
|
with self.assertRaisesRegex(ValueError, "immutable forecast"):
|
|
|
|
|
compare(forecast, actual)
|
|
|
|
|
|
|
|
|
|
def test_missing_proxy_is_data_quality_error(self):
|
|
|
|
|
forecast, actual = record(), record("actual")
|
|
|
|
|
actual["usage_proxies"] = {"cpu_hours": {"value": 4, "unit": "vCPU-hour"}}
|
|
|
|
|
result = compare(forecast, actual)
|
|
|
|
|
self.assertEqual("data_quality", result["usage_proxies"]["stored_gb"]["category"])
|
|
|
|
|
|
|
|
|
|
|
feat(portfolio): fold in RAILIANCE-WP-0016 apps-pg evidence
First delegated evidence from RESOURCE-WP-0003-T04 to land. railiance-platform
delivered apps-pg capacity, utilization, consumers, and the apps-pg-dbbytes-v1
allocation driver, and correctly delivered no EUR.
- data/resources/apps-pg.json: real capacity; allocation unattributed -> shared
under apps-pg-dbbytes-v1; second consumer vergabe-teilnahme registered
- data/control-cycle/apps-pg-2026-09-base.json: first operational control-cycle
record in the repository
- examples/control-cycle/apps-pg-*.json retired; the invented fixture collided
with the real record's identifier
- data/portfolio-coverage-2026-08-14.json: gap marked delivered with three
residual unknowns still open
The real evidence exposed a design gap in the T05 schema: v0.1 required a number
for every cost field, so recording genuine usage without a booked cost meant
inventing one. Schema 0.2 permits null costs, null unattributed_eur, a technical
unattributed_share, and null measurements. Null is unknown, never zero; an
unknown component makes the total null rather than the sum of the known parts;
and the comparator classifies unknown amounts as data_quality instead of
computing a variance. Existing 0.1 records are not rewritten.
apps-pg is now measured (idle at 5.8% of volume) and attributed, and remains
unpriced: delivered technical evidence does not create a booked cost.
86 tests pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 09:36:57 +02:00
|
|
|
class UnknownCostTest(unittest.TestCase):
|
|
|
|
|
"""Schema 0.2: a cost the authoritative repository has not supplied is
|
|
|
|
|
unknown, not zero, and must not produce a fabricated variance."""
|
|
|
|
|
|
|
|
|
|
def test_unknown_cost_reports_status_rather_than_an_error_figure(self):
|
|
|
|
|
forecast, actual = record(), record("actual")
|
|
|
|
|
forecast["costs"].update(infrastructure=None, total=None)
|
|
|
|
|
actual["costs"].update(infrastructure=None, total=None)
|
|
|
|
|
result = compare(forecast, actual)["costs"]["infrastructure"]
|
|
|
|
|
self.assertEqual("unknown", result["status"])
|
|
|
|
|
self.assertNotIn("error", result)
|
|
|
|
|
|
|
|
|
|
def test_unknown_cost_is_a_data_quality_gap_not_a_price_movement(self):
|
|
|
|
|
forecast, actual = record(), record("actual")
|
|
|
|
|
actual["costs"].update(infrastructure=None, total=None)
|
|
|
|
|
actual["variance_attribution"] = {"costs.infrastructure": "provider_price"}
|
|
|
|
|
result = compare(forecast, actual)["costs"]["infrastructure"]
|
|
|
|
|
self.assertEqual("data_quality", result["category"])
|
|
|
|
|
|
|
|
|
|
def test_known_components_still_compute_beside_an_unknown_one(self):
|
|
|
|
|
forecast, actual = record(), record("actual")
|
|
|
|
|
forecast["costs"].update(infrastructure=None, total=None)
|
|
|
|
|
actual["costs"].update(infrastructure=None, internal_labor=90, total=None)
|
|
|
|
|
result = compare(forecast, actual)["costs"]
|
|
|
|
|
self.assertEqual("unknown", result["infrastructure"]["status"])
|
|
|
|
|
self.assertEqual(30, result["internal_labor"]["error"])
|
|
|
|
|
|
|
|
|
|
def test_one_sided_unknown_does_not_subtract_against_a_missing_amount(self):
|
|
|
|
|
forecast, actual = record(), record("actual")
|
|
|
|
|
actual["costs"].update(infrastructure=None, total=None)
|
|
|
|
|
result = compare(forecast, actual)["costs"]["infrastructure"]
|
|
|
|
|
self.assertEqual("unknown", result["status"])
|
|
|
|
|
self.assertEqual(10, result["forecast"])
|
|
|
|
|
self.assertIsNone(result["actual"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class OperationalRecordTest(unittest.TestCase):
|
|
|
|
|
"""The first real apps-pg record, folded in from RAILIANCE-WP-0016."""
|
|
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
|
path = Path(__file__).parents[1] / "data" / "control-cycle" / "apps-pg-2026-09-base.json"
|
|
|
|
|
self.record = json.loads(path.read_text())
|
|
|
|
|
|
|
|
|
|
def test_usage_is_known_while_infrastructure_cost_is_not(self):
|
|
|
|
|
costs = self.record["costs"]
|
|
|
|
|
self.assertIsNone(costs["infrastructure"])
|
|
|
|
|
self.assertIsNone(costs["total"])
|
|
|
|
|
self.assertEqual(30.0, costs["internal_labor"])
|
|
|
|
|
self.assertTrue(self.record["usage_proxies"])
|
|
|
|
|
|
|
|
|
|
def test_total_is_not_the_sum_of_the_known_parts(self):
|
|
|
|
|
costs = self.record["costs"]
|
|
|
|
|
known = costs["internal_labor"] + costs["external_labor"]
|
|
|
|
|
self.assertNotEqual(known, costs["total"])
|
|
|
|
|
self.assertIsNone(costs["total"])
|
|
|
|
|
|
|
|
|
|
def test_shared_overhead_is_recorded_as_a_share_before_any_eur_exists(self):
|
|
|
|
|
allocation = self.record["allocation"]
|
|
|
|
|
self.assertEqual("apps-pg-dbbytes-v1", allocation["method_version"])
|
|
|
|
|
self.assertIsNone(allocation["unattributed_eur"])
|
|
|
|
|
self.assertEqual(0.948, allocation["unattributed_share"])
|
|
|
|
|
|
|
|
|
|
def test_absent_recovery_objectives_are_null_not_optimistic_defaults(self):
|
|
|
|
|
constraints = self.record["service_constraints"]
|
|
|
|
|
self.assertIsNone(constraints["rpo_minutes"]["value"])
|
|
|
|
|
self.assertIsNone(constraints["rto_minutes"]["value"])
|
|
|
|
|
|
|
|
|
|
def test_record_cites_the_authoritative_platform_evidence(self):
|
|
|
|
|
self.assertIn("RAILIANCE-WP-0016", self.record["evidence"])
|
|
|
|
|
self.assertEqual("high", self.record["uncertainty"]["level"])
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
if __name__ == "__main__":
|
|
|
|
|
unittest.main()
|