--- id: RESOURCE-WP-0005 type: workplan title: "Build the resource procurement facility" domain: financials repo: resource-control status: ready owner: grok topic_slug: railiance created: "2026-08-14" updated: "2026-08-14" related: - RESOURCE-WP-0003 - RESOURCE-WP-0004 - FIN-WP-0004 origin: residual origin_ref: RESOURCE-WP-0004 state_hub_workstream_id: "0c710416-e469-45a7-b007-d08ff3210c04" --- # RESOURCE-WP-0005 — build the resource procurement facility ## Goal Turn `docs/TermsOfResourceProcurement.md` V0.1 into an **operational facility** in this repository: executable entity register, terms parameters, association on every cost-bearing record, delivered-cost and transfer-price calculation, monthly settlement statements, credit-state evaluation, and the signals `fin-hub` and Railiance operations need. This is the implementation residual of `RESOURCE-WP-0004`, which published the terms. The facility must be usable for a monthly close before any entity bank account exists: statements and credit state are computed from committed evidence; payment recognition stays `unknown` until `fin-hub` projects a payment. ## Boundaries - `resource-control` owns the register, the arithmetic, the statements, and the consumption-mode signal. - `fin-hub` owns booked provider cost, recognized payments, tax, and any later posting of internal settlement. This workplan does not create a second ledger. - Railiance platform repos enforce `restricted` consumption. This workplan publishes the signal; it does not throttle a cluster. - Human financial authority opens accounts, changes P1–P12, and waives limits. The facility stores the resulting parameters, not the conversation. - Schema changes stay compatible with `docs/fin-hub-resource-control-contract-v0.1.md`. New fields are additive. Unknown remains explicit; no silent default to Railiance or Binky. - Money is EUR, two decimal places, round-half-even, matching `tools/financial_exchange.py`. ## Facility shape When this workplan is finished, an operator can: ```text make test make settlement PERIOD=2026-08 make portfolio-report ``` and get, from committed evidence: - one settlement statement per consuming entity that has a charge, credit, interest, or open balance; - `open` or `restricted` consumption mode and the next month's allowance (`max(0, 50.00 − monthly_interest)` at the default limit); - transfer prices at cost plus 20 % except Railiance self-use at cost; - a report that names unattributed cost instead of spreading it. The three worked examples in Terms § 15 are executable fixtures. ## T01 — Entity register and terms parameters ```task id: RESOURCE-WP-0005-T01 status: todo priority: high state_hub_task_id: "f8df895b-9959-4bb2-958e-f2444b558aac" ``` Publish the six financial entities and the V0.1 parameter table as versioned data, not only as prose. Expected shape (refine as needed): - `data/entities/register.json` — `entity:binky`, `entity:frontier`, `entity:railiance`, `entity:netkingdom`, `entity:helixforge`, `entity:coulomb`; display name; role (`umbrella`, `provider`, `consumer`); default credit limit; non-secret `account_ref` (null until banking exists); status. - `data/terms/procurement-v0.1.json` — P1–P15 from Terms § 14, including markup 0.20, payment term 10 days, interest 0.05 per year, credit limit 1000.00, restricted cap 50.00. Record `terms_version: "0.1"`. - Schemas and validator coverage so an unknown entity ID or a parameter set that does not match the published terms fails closed. Done when `make test` loads the register and the V0.1 parameter file, rejects an unknown `entity:` id, and the numeric parameters match Terms § 14 exactly. ## T02 — Associate every cost-bearing schema ```task id: RESOURCE-WP-0005-T02 status: todo priority: high state_hub_task_id: "5a18a74a-db07-4ab6-8bb5-ed4321ab7e11" ``` Add `financial_entity_id` (consuming entity) and `procuring_entity_id` (default `entity:railiance`) to: - `schemas/resource-inventory.schema.json` - `schemas/planning-evidence.schema.json` - `schemas/resource-control-cycle.schema.json` and to the semantic validators in `tools/`. Historical records that cannot yet be tagged carry an explicit unattributed gap, never a guessed entity. A new cost-bearing record is invalid if it has neither a consuming entity nor an explicit gap. Shared resources keep `procuring_entity_id: entity:railiance` and produce per-consumer shares each tagged with a `financial_entity_id`. Done when validators reject an untagged new record, accept an explicit gap, accept all six entity IDs, and existing tests still pass after additive schema changes. ## T03 — Backfill the live portfolio ```task id: RESOURCE-WP-0005-T03 status: todo priority: high state_hub_task_id: "14d450fb-e1f2-4443-a284-4439579f3709" ``` Tag every record in `data/resources/` from source evidence: | Record | Procuring | Consuming / allocation | | --- | --- | --- | | `coulomb-social-production` | `entity:railiance` | `entity:coulomb` | | `binky-rapp-qonto` | `entity:railiance` | `entity:binky` | | helix-forge workloads | `entity:railiance` | `entity:helixforge` | | Railiance host, cluster, forge, apps-pg | `entity:railiance` | Railiance self-use and/or shared allocation; unattributed where no driver exists | | proposed backup storage | `entity:railiance` | the entity that will bear the transfer price, or an explicit gap | Do not invent allocation drivers to make shared cost look attributed. Update `examples/` only where they are schema proofs, and keep `record_scope: example` unmistakable. Done when every live inventory record has a procuring entity and either a consuming entity, a shared allocation that yields per-entity shares, or an explicit unattributed gap, and `make test` passes. ## T04 — Transfer-price and credit-state engine ```task id: RESOURCE-WP-0005-T04 status: todo priority: high state_hub_task_id: "4d2c87f7-6e50-4696-a041-e8502e9fab38" ``` Implement the V0.1 arithmetic as a library used by settlement, forecasts, and tests. Parameters come from the T01 terms file, not from literals scattered in tools. Required calculations: - `transfer_price = delivered_cost × (1 + markup)` for every consumer except Railiance; - `transfer_price = delivered_cost` for `entity:railiance`; - overdue after statement date + 10 calendar days; - `interest = overdue × 0.05 / 12` at month-end close (simple, monthly); - payment waterfall: interest first, then principal; - `consumption_mode = restricted` iff `outstanding ≥ credit_limit`; - `new_transfer_charges_allowed = max(0, 50.00 − interest_this_month)` when restricted, else unconstrained by this facility; - credit headroom `max(0, credit_limit − outstanding)`. Unknown delivered-cost components stay `null`. A transfer price is issued only for the known portion; the unknown remainder is labelled, never filled with zero. Done when fixtures for Terms § 15.1–15.3 assert: - Coulomb ordinary month: transfer 240.00, due +10 days, headroom 760.00, mode `open`; - same statement unpaid: interest 1.00 on 240.00; - Helixforge at 1000.00 overdue: interest 4.17, allowance 45.83, max new delivered cost 38.19, mode `restricted`. ## T05 — Monthly settlement statements ```task id: RESOURCE-WP-0005-T05 status: todo priority: high state_hub_task_id: "cf55645b-b3ef-4cc4-ab51-23bdf5ff3af1" ``` Define a settlement-statement schema and emit one statement per consuming entity that has a charge, credit, interest, or open balance for period `M`. Minimum contents (Terms § 10.1): entity, period, `terms_version`, statement date, due date, line items (`resource_id`, usage summary, delivered-cost components, markup, transfer price), known-cost total, unknown remainder, prior outstanding, recognized payments (projection from `fin-hub`, else unknown), interest, new charges, new outstanding, credit limit, headroom, consumption mode, next-month allowance if restricted, non-secret pay-to / pay-from `account_ref`. Wire `make settlement PERIOD=YYYY-MM` into the monthly cadence in `docs/portfolio-operating-cadence.md`. Railiance self-consumption is recorded at cost and does not generate a payment instruction. Until bank accounts and booked payments exist, statements still emit; payment recognition is `unknown` and credit state is reported, not pretended settled. Done when the three § 15 scenarios can be produced as statements from fixtures, `make settlement` runs against the repo, and a period with no consumers emits nothing rather than invented zeros. ## T06 — Entity views on forecasts, variance, and the portfolio report ```task id: RESOURCE-WP-0005-T06 status: todo priority: medium state_hub_task_id: "b8baa250-f189-4ae7-a4a6-5b09a199c1dd" ``` Estimates and expense evaluations show delivered cost, transfer price, and effect on the consuming entity's credit headroom. The portfolio report gains an entity section: charges, unattributed residuals, `open` / `restricted` state, and missing price evidence — still refusing to print a fake `known_monthly_spend_eur` of 0. Forecasts remain immutable. A new terms version does not rewrite a historical transfer price; the statement and forecast record the terms version that produced them. Done when `make portfolio-report` lists each financial entity, names unattributed resources, and a forecast fixture includes transfer price and headroom without becoming booked spend. ## T07 — Fin-hub and Railiance handoff, plus the close runbook ```task id: RESOURCE-WP-0005-T07 status: todo priority: medium state_hub_task_id: "d91a2ffd-7557-4a9a-a846-e6449b037eec" ``` This repository does not book settlement or throttle workloads. Publish the join keys and artifacts the neighbours need, then hand off: - to `fin-hub`: proposed transfer-charge and credit-state records; how recognized internal payments will join (`financial_fact_id`, entity, period); confirmation that this is not a second ledger. Spawn or update a fin-hub work record; do not register it by hand in the hub. - to Railiance operations: the consumption-mode signal (`open` | `restricted`, remaining transfer-price allowance, period). Enforcement of new orders and elastic usage lives there. Committed provider contracts are flagged, not auto-cancelled (OQ-2). Write `docs/resource-procurement-facility.md` as the operator runbook: monthly close steps, what remains unknown without bank accounts, how a human waiver is recorded, and which repo owns each failure mode. Done when the runbook exists, the outbound artifact shapes are documented next to the fin-hub contract, and live work records exist in the owning repos (or an intake with `origin: residual` if those repos cannot take the work this session).