resource-control/workplans/RESOURCE-WP-0005-resource-procurement-facility.md
tegwick 24b8b27b40 workplan: RESOURCE-WP-0005 resource procurement facility
Spawn the operational build as a residual of RESOURCE-WP-0004. Finish
the terms workplan (T01 done; T02–T05 cancelled as superseded) and
point the terms document at the facility tasks.
2026-08-14 11:37:29 +02:00

285 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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 P1P12, 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` — P1P15 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.115.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).