/ docsGitHub ↗
Browse documentation
EXPERIMENTAL · LOCAL-FIRST

Evaluate carefully. Live-provider paths are experimental and are not money-grade production infrastructure.

Ledger and authorization records#

Hubu exposes one owner-scoped history model through HTTP, the CLI, and unified MCP. These are read operations: they never authorize, claim, settle, release, correct a posting, or execute a provider request. Provider settlement writes the canonical ledger before history reads it.

Inspect a selected agent's budget#

hubu ledger list --agent-id agt_EXACT_AGENT_ID --budget-id bgt_EXACT_BUDGET_ID --limit 20
hubu ledger list --agent-id agt_EXACT_AGENT_ID --budget-id bgt_EXACT_BUDGET_ID --limit 20 --cursor CURSOR_FROM_PREVIOUS_PAGE

The equivalent endpoint is GET /ledger/transactions with agent_id, budget_id, limit, and optional cursor query parameters. The MCP tool hubu_list_ledger takes the same parameter names. Omit filters for the complete owner ledger, or select agent_id and/or account_id. A budget selection requires its agent explicitly; foreign IDs and mismatched agent/account/budget pairs fail even when there are no transactions. No caller-supplied owner selector is accepted.

Each response has schema_version: "hubu-history-v1", transactions, coverage, and next_cursor. Each transaction retains its canonical ID and exact debit and credit entries, source kind, public agent/account and budget/version IDs when supported by authentic ownership evidence, public authorization record and settlement links, and correction predecessor/original IDs. Costs use a coefficient string, scale and currency: {"amount":"1","scale":3,"currency":"USD"} means USD 0.001. Do not convert these values through floating point.

effective_cost is the original total on an original posting and the corrected total on an adjustment (cost_semantics identifies which). Do not sum original and corrected totals. Entries express the actual signed expense change through account and debit/credit direction. budget_charge_delta is the separate signed control charge exactly as recorded, as {"units":"1000","scale":6}: postings since accounting units use scale 6, and older postings report their whole cents at scale 2. rounding_delta_amount is that charge's difference from the signed expense at scale 18: units × 10^(18 − scale) = expense delta + rounding_delta_amount. A USD 0.001 provider expense now consumes exactly 1,000 units with no rounding, while a USD 0.0000001 expense rounds up to one unit.

budget_charge_delta_cents is a compatibility projection, not the recorded charge: the change in the rounded-up cent total of the row's correction chain. The rows of a chain always sum to the coverage report's cent projection, but the rounding invariant applies to budget_charge_delta, not to this field.

For a selected budget, coverage reports the full-budget consumed amount, recorded signed charges and their difference (unaccounted_consumption), as exact money objects with *_cents projections, plus the pending-hold count, currency, and an owner-wide count of transactions lacking trustworthy budget context. These totals come from the whole budget, not the current page. Budget attribution requires the decision’s actual hold to match both the budget and version; inconsistent historical links remain unassigned. Expired unclaimed holds are projected as expired and excluded from the pending count. Claimed holds remain pending until finalization, including expired claims that require reconciliation; history reads never mutate the stored hold. A valid unused budget has an empty list and zero totals. Owner-wide and agent-wide reads return coverage: null rather than adding unlike currencies or claiming aggregate reconciliation. Unknown historical attribution remains unassigned. Historical wallet reconciliation is explicitly incomplete; wallet atomicity and remaining legacy wallet validation are deferred in HUB-210.

Discover authorization records#

hubu spend authorizations --agent-id agt_EXACT_AGENT_ID --status settled --limit 20
hubu spend authorizations --account-id aga_EXACT_ACCOUNT_ID
hubu spend show --authorization-id PUBLIC_DECISION_UUID

GET /spend/authorizations accepts agent_id, account_id, status, limit, and cursor. Unified MCP exposes hubu_list_authorization_records with those same fields. The list returns schema_version, authorization_records, and next_cursor. The show response returns schema_version and authorization_record. These are read-only, computed lifecycle views; Gongbu owns durable orchestration. Discovery selects the latest authorization revision for each independent agent-scoped operation. Two provider operations remain two authorization records even if they came from one higher-level task; a safe task_reference correlates their common task ID. Denied-request history is intentionally excluded.

Statuses are needs_approval, authorized, claimed, settled, released, expired, reconciliation_required, and unknown. Missing historical authorization outcome evidence is shown as unknown, never inferred as allowed. decision reflects the latest authorization outcome, including human approval; the immutable initial policy evaluation is separately policy_decision.

An authorization record shows the public decision identity, authorized maximum, currency, trusted provider/billing identity when known, hold and budget version, claim lease timestamps and terminal status, receipt with exact provider cost and rounded budget charge, linked ledger transaction IDs, and reconciliation outcome and evidence references. Release does not invent a receipt or expense posting.

GET /spend/authorizations/show?authorization_id=PUBLIC_DECISION_UUID and MCP hubu_get_authorization_record inspect a known public authorization record. Trusted HTTP/CLI callers may alternatively look up agent_id plus their existing private operation_key:

hubu spend show --agent-id agt_EXACT_AGENT_ID --operation-key EXISTING_PRIVATE_KEY

This read does not generate an operation key. MCP accepts only authorization_id for lookup; it neither accepts nor returns private operation keys. Query values use standard URL percent encoding. Do not put trusted private-key lookup URLs in shared screenshots or shell evidence; use the public authorization record ID for sharing.

Pagination, evidence and compatibility#

Both list endpoints order newest first by creation timestamp and immutable ID. The default page size is 50; the maximum is 100. Return next_cursor unchanged with the same filters. Cursors bind the owner, resource kind and query filters, and carry a first-page upper bound; changing filters requires a new first page. Newer postings do not displace subsequent ledger pages. Each request uses one SQLite snapshot for postings, authorization records, receipts and balances. Pages are not a persistent historical snapshot: authorization record statuses, newly backfilled older records and budget totals can change between requests. Restart from the first page to refresh. Store the schema version and cursor with dogfood evidence.

Public projections never serialize raw stored metadata, operation keys, authorization tokens, provider credentials, pricing JSON or capability-bearing artifact URLs. Arbitrary source, purpose, provider-request, artifact, pricing and reconciliation strings become stable SHA-256 evidence references with redacted: true; they support correlation without becoming a credential or a fetchable artifact URL. Provider/billing display identities come only from the trusted scope catalog. Missing-evidence labels are allowlisted. This API does not offer raw-secret retrieval or artifact download.

GET /ledger remains the original wallet-only compatibility response. The existing CLI hubu ledger list and MCP hubu_list_ledger now use the canonical history response so they also show external-provider settlement. Consumers of the old CLI table or old MCP wallet shape must adopt hubu-history-v1 JSON.

Implementation: public projections, consistent owner snapshot, CLI, and unified MCP adapter.

The governance lifecycle evidence foundation defines storage for future automatic-decision, human-intervention and recovery observability. Its schema alone does not add production capture or extend these public history reads.

Edit this page on GitHub ↗Canonical source: docs/ledger-history.md