# Resource-control review of fin-hub results Date: 2026-08-11 Reviewer: `resource-control` / Codex Reviewed repository: `fin-hub` Reviewed commits: `d2b9bc4^..2895077` Primary workplans: `FIN-WP-0002`, `FIN-WP-0004`, `RESOURCE-WP-0003` State: changes requested before accepting the v0.1 exchange contract ## Conclusion The fin-hub result is directionally strong, but the v0.1 resource-cost exchange contract is not yet ready for approval. Its authority matrix correctly separates booked financial facts in fin-hub from resource identity, technical usage, allocation evidence, forecasts, and optimization in resource-control. The client-attribution and engagement-margin work is a useful foundation. Accounting-integrity and schema gaps remain. In particular, existing reports can combine incompatible currencies and environments, changed CSV imports can duplicate booked cost, and the SQLAlchemy and SQLite engagement-price paths do not enforce the same invariants. The exchange envelopes also need exact money, correction, and record-type semantics before implementation. Verification on 2026-08-10: - fin-hub worktree was clean at review time; - `uv run pytest -q` passed: 33 tests, one dependency deprecation warning; - a diagnostic reproduced EUR and USD service rows being combined into one EUR-labelled total. ## Findings and implementation pointers | Severity | Finding | Required task | | --- | --- | --- | | High | Service reporting groups by `service_id` and month without preserving currency and environment dimensions. | `FIN-WP-0004-T07` | | High | CSV import identity is based on path and mtime; a changed or forced import appends the same booked rows again. | `FIN-WP-0004-T08` | | Medium | SQLAlchemy and SQLite engagement-price paths enforce different attribution, currency, amount, period, and revision invariants. | `FIN-WP-0004-T09` | | Medium | Booked-cost envelope does not define net, tax, gross, credit, refund, correction, decimal precision, or rounding relationships. | `FIN-WP-0004-T02` | | Medium | The common planning envelope's single `amount` is insufficient for infrastructure, labor, setup, usage, allocation, and savings evidence. | `FIN-WP-0004-T03` | | Low | fin-hub's canonical `INTENT.md` does not yet express booked-cost authority, client reporting, or the resource-control boundary. | `FIN-WP-0004-T01` | | Low | Workplan lifecycle language and frontmatter status disagree. | `FIN-WP-0004-T01` | `FIN-WP-0004-T05` remains the acceptance gate: the first round trip must prove that a cost is booked once, projected to resource-control, joined to technical evidence, and returned as planning or variance evidence without becoming a second financial fact. ## Detailed findings ### 1. Currency and environment mixing `src/fin_hub/coupling/ops_hub.py` keys service buckets only by `service_id` and monthly totals only by month. A diagnostic with a EUR production row and a USD development row for the same service produced one EUR-labelled total. Service aggregation must use at least: ```text service_id × environment × currency month × currency ``` Unattributed and attributed reports must expose the same dimensional rules and reconciliation totals. ### 2. Duplicate booked cost on changed imports `src/fin_hub/services/ledger.py` treats `(source_path, source_mtime)` as import identity and inserts every row from every newly observed file version. This is file-delivery deduplication, not financial-fact idempotency. A corrected file or forced import can inflate burn, attributed cost, and margin. Each booked row needs a stable `financial_fact_id`, source-document and source-line identity, content fingerprint, and explicit append-only correction/reversal relationship. Duplicate delivery must leave totals unchanged. ### 3. Divergent engagement-price invariants The SQLite command path validates attribution components, period, currency, non-negative amount, source, and the current revision. The SQLAlchemy `EngagementPrice` model does not enforce equivalent rules and can persist a key that disagrees with its dimensions or an invalid price/revision state. Both persistence paths should use the same domain validator and database constraints, with concurrency-safe uniqueness for the current price basis. ### 4. Monetary contract semantics The booked-cost schema must define whether credits are signed, whether gross equals net plus tax, where discounts apply, how refunds/reversals work, how unknown tax is represented, and which precision and rounding rule applies. Exchange money should use decimal strings or integer minor units, not binary floating-point numbers. ### 5. Record-specific planning schemas The common envelope may stay small, but `forecast`, `allocation`, `usage`, `optimization`, and `commitment_candidate` each need a concrete schema. Infrastructure cost, internal labor, external services, setup cost, recurring cost, technical units, allocation shares and residual, and expected savings must not be overloaded into one ambiguous `amount`. ### 6. Canonical intent and lifecycle alignment `INTENT.md` should reciprocate the boundary already recorded in resource-control: fin-hub owns booked financial facts, budgets, commitments, burn, runway, and viability signals; it consumes resource-control projections without becoming authoritative for resource identity or technical allocation. The workplan should no longer describe itself as proposed after its frontmatter is active. Joint review remains incomplete until these review results are incorporated and linked by both repositories. ## Decisions recommended for v0.1 - Keep client and infrastructure attribution identifiers in distinct, versioned namespaces under one common envelope. - Native service and workload identity stays with its owning repository. Resource-control may issue an explicitly scoped portfolio surrogate only where no native authority exists. - Rename resource-control `actual` records to `usage_observation` or `cost_observation`; reserve “booked actual” for fin-hub facts. - Each producer owns its outbound schema. The shared contract pins compatible versions and reconciliation rules; transport is selected after the backup round trip validates the model. ## Approval condition Approve the authority boundary in principle. Keep `FIN-WP-0004-T01` in progress until the contract incorporates this assessment. Do not mark the v0.1 exchange accepted until `FIN-WP-0004-T02`, `T03`, `T07`, `T08`, and `T09` are complete and `T05` demonstrates an idempotent reconciled round trip.