Hand Usage and Governance data to FinOps
Halro does not push directly to an external FinOps platform. An administrator creates and verifies local exports on the Halro host, then transfers the approved artifacts through a trusted deployment-owned channel.
What the two data sets answer
Section titled “What the two data sets answer”| Data product | Default location | Contains | Cannot answer |
|---|---|---|---|
| Usage export | <data_dir>/usage/manifest.json and partitions | Attempt, token, actual/estimated cost, Project, Work Unit, Run, Route, Deployment, Provider, price snapshot | Whether the Work Unit ultimately succeeded |
| Governance export | <data_dir>/governance/export/gex_.../ | work_units.ndjson, runs.ndjson, outcomes.ndjson, outcome_definitions.ndjson, manifest | Actual Attempt cost |
Run rows carry budget ceilings, not spend. Join Usage Attempts by stable project_id, work_unit_id, and run_id; never sum Run budgets as actual cost.
1. Generate and verify the Usage export
Section titled “1. Generate and verify the Usage export”At usage.parquet_interval, settled Attempts are written under <data_dir>/usage/. usage.export_format chooses Parquet or NDJSON only for new partitions. Manifest schema 6 records last_sequence, each file’s path/format/schema/min-max sequence/row count/SHA-256, and file token/known-cost totals.
To refresh immediately, stop Halro and run:
./halro usage compact --config ./config.yaml./halro usage verify --config ./config.yamlThese offline commands authenticate Accounting Ledger and reconcile it to partitions. Never hand off a batch with missing, duplicate, or extra rows. Copy every partition referenced by the manifest—not the manifest alone—to immutable staging, then verify digests, counts, and totals.
2. Trigger the Governance export
Section titled “2. Trigger the Governance export”Governance export is an Admin mutation endpoint:
POST /admin/api/v1/governance/exportCookie: <authenticated administrator session>X-CSRF-Token: <CSRF token returned for that session>Origin: <origin matching admin.external_origin>It requires administrator role, valid session, same-origin validation, and CSRF. Read-only Admin and Gateway Keys cannot trigger it. Do not put an administrator password, Session Cookie, or TOTP seed into cron, CI, or FinOps pipelines.
The current Console has no export button. On your own authenticated Admin origin, a controlled administrator may execute this fixed same-origin code in browser developer tools:
const sessionResponse = await fetch('/admin/api/v1/session', { credentials: 'same-origin' });if (!sessionResponse.ok) throw new Error(`session: ${sessionResponse.status}`);const session = await sessionResponse.json();const exportResponse = await fetch('/admin/api/v1/governance/export', { method: 'POST', credentials: 'same-origin', headers: { 'X-CSRF-Token': session.csrf_token },});const exportResult = await exportResponse.json();if (!exportResponse.ok) throw new Error(JSON.stringify(exportResult));console.log(exportResult);Do not paste untrusted browser scripts. The response reports a local server directory; it does not download files. A successful export contains manifest.json plus four NDJSON data files. Manifest v1 records generation time, Accounting/Governance watermarks, and each data set’s schema, format, path, SHA-256, and row count.
3. Form one currently verifiable handoff batch
Section titled “3. Form one currently verifiable handoff batch”There is no atomic “export both” action. For close or one-time acceptance:
- Pause new work and wait for Requests, Runs, and Outcomes to reach an explainable state.
- Keep Halro online, trigger Governance export, and save its ID and directory.
- Stop Halro and confirm it released the data directory.
- Run
usage compactandusage verify. - Freeze both manifests and every referenced file; compute a handoff batch ID.
- Transfer over a trusted channel into immutable raw storage; verify before joining by stable IDs.
- Produce financial aggregates only after verification, joining, and completeness checks pass.
If traffic cannot pause, the snapshots have different cutoffs: handle them as an incremental batch marked partial. Local copy time is not a shared cutoff.
4. Do not compare the two sequence numbers directly
Section titled “4. Do not compare the two sequence numbers directly”Governance accounting_watermark.sequence covers the complete Accounting Ledger, including Work Unit/Run lifecycle events. Usage last_sequence is only the highest exported Attempt sequence. Closing a Run after the last Attempt advances the former but not the latter. Therefore usage.last_sequence < governance.accounting_watermark.sequence does not mean cost is missing, and another Usage export may never make them equal. Use each sequence for its own increments/debugging; cross-product completeness needs Usage reconciliation, manifest checks, stable-ID joins, resource terminal state, and the report’s completeness reason.
5. Propagate partial and unknown
Section titled “5. Propagate partial and unknown”Do not produce “complete cost/success” when Usage verify fails, files/counts/digests mismatch, a Work Unit is open, Attempts are pending/inflight, an Outcome is provisional or missing, cost is unknown, stable IDs do not join, or online exports lack a controlled cutoff.
Preserve cost_completeness, outcome_completeness, and reason. partial means known-incomplete; unknown means completeness cannot currently be determined. Neither means zero, failure, or success. Keep cost_estimated separate from Provider-reported cost. These fields are built-in Summary semantics, not fields on every Governance NDJSON row; external FinOps must compute the same maturity rules with reasons or ingest an explicitly time-stamped Admin Summary.
6. Import, idempotency, and reconciliation
Section titled “6. Import, idempotency, and reconciliation”Use “Governance export ID + both manifest digests” as the import idempotency key:
- Preserve raw exports and manifests unchanged.
- Validate paths, SHA-256, schema, format, and row counts.
- Import Project, Work Unit, Run, Definition, Outcome, and Attempt detail first.
- Build Project, business group, Definition version, and time-window aggregates afterward.
- Reimporting the same batch must add no Attempts or cost.
- Reconcile Project/Work Unit/Run/Attempt counts and known, estimated, and unknown cost.
SHA-256 detects content changes but not source identity. Authenticate transport or add an organizational signature/MAC. Never export Provider Credentials, Gateway Keys, prompts, responses, captured failure bodies, or Admin sessions.
7. Acceptance checklist
Section titled “7. Acceptance checklist”- Governance export is triggered only by an administrator session and read only from the restricted server directory.
- Usage compact/verify ran while stopped and reports no missing, duplicate, or extra rows.
- Both manifests and all data files verify; raw partitions are immutable.
- Duplicate import adds no cost; unknown/estimated cost is not converted to
$0. - Multiple Runs and all Attempts for one Work Unit produce one final business result.
- Provisional, partial, unknown, and missing-Outcome states remain visible.
- Transfer contains no prompt, response, credential, session, or captured failure body.
- Automation requirements remain an external orchestration boundary; Admin sessions are not service accounts.