Machine Spend Control Plane
Product: QuantZK authorizes what AI agents and software may spend, enforces those limits on the execution path, reconciles what was consumed, and issues independently verifiable QZR receipts.
Architectural boundary (permanent):
┌─────────────────────────────────────────────┐
│ QUANTZK CONTROL PLANE │
│ policies / budgets / agents / approvals │
│ reservations / dashboards / adapters │
└─────────────────────┬───────────────────────┘
│ issues / consumes
▼
┌─────────────────────────────────────────────┐
│ EXISTING QUANTZK PROTOCOL (frozen) │
│ Charge Authority v1 → meter → QZR-1 → verify│
└─────────────────────────────────────────────┘Do not modify (frozen)
quantzk_charge_authority_v1- Frozen Claims 1–4 (charge-authority-v1-freeze.md)
- QZR-1 committed-value semantics (qzr-1.md §4.4)
execution_intent_digest- Existing
/api/vdi/billing/authorize,/preflight,/attest - Offline QZR verification
Only preflight may produce execution_eligible. A receipt must never retrospectively manufacture MAY_EXECUTE (Claim 4).
Control-plane vs protocol claims
| Property | Layer | Portable / cryptographic? |
|---|---|---|
| Policy allow/deny | Control plane | No, operational |
| Hierarchical budgets + reservation | Control plane | No, operational (v1) |
| Gateway path enforcement | Control plane / ops | No, Claim 4 non-claim |
| Signed Charge Authority | Protocol | Yes |
| Preflight single-use consume | Protocol | Yes (trusted channel) |
| QZR receipt binding | Protocol | Yes |
Reservation lifecycle (reserve → authorize → execute → settle → release) is a control-plane property. Do not claim Charge Authority v1 or QZR-1 proves it. A future CA v2 / budget-reservation protocol MAY lift this later.
60-second flow
IDENTIFY agent/workload
↓
POLICY ENGINE (SpendPolicy)
↓
BUDGET ENGINE (reserve micros)
↓
ALLOW / DENY / REQUIRE_APPROVAL
↓ (if ALLOW)
issue existing Charge Authority v1
↓
existing preflight
↓
EXECUTE (SDK callback or gateway)
↓
meter + reconcile
↓
existing attest → QZR-1
↓
settle / release unused reservationSpendPolicy (commercial object)
Not a new crypto schema. Hashed for binding into existing policy_digest:
{
"policy_id": "spend_policy_engineering_agents",
"version": "1",
"subject": { "type": "agent_group", "id": "engineering-agents" },
"rules": {
"allowed_vendors": ["openai", "anthropic"],
"allowed_models": ["gpt-5.6", "claude-opus"],
"max_per_call_micros": 5000000,
"max_hourly_micros": 50000000,
"max_daily_micros": 250000000,
"currency": "USD"
},
"cost_center": "engineering"
}policy_digest = 0x || SHA-256(JCS(policy)), using the same canonicalization rules as QZR (§5.1: inspired by RFC 8785 / JCS, specialized here).
New API surface (additive)
Preserve all /api/vdi/billing/* routes.
| Method | Path | Role |
|---|---|---|
POST | /api/control/v1/decide | Policy + budget → decision; optionally issue CA v1 |
POST | /api/control/v1/execute | Decide → issue CA v1; then use existing /billing/preflight before vendor call |
POST | /api/control/v1/reconcile | Settle reservation against actual charge |
POST | /api/control/v1/reservations/:id/release | Release unused reservation |
GET | /api/control/v1/budgets | List budget accounts |
GET | /api/control/v1/subjects | List spend subjects |
GET | /api/control/v1/policies | List policies |
GET | /api/control/v1/decisions | Recent allow/deny decisions |
POST | /api/control/v1/policies | Upsert policy |
POST | /api/control/v1/budgets | Upsert budget account |
POST | /api/control/v1/subjects | Upsert subject |
Vendor callback execution lives in the SDK spend firewall (qzk.spend) or the QuantZK Gateway (@quantzk/gateway). HTTP control routes decide and reconcile; they do not proxy provider traffic themselves.
SDK
const decision = await qzk.control.authorize({
agent: 'research-agent-17',
vendor: 'openai',
model: 'gpt-5.6',
estimatedMaxSpendMicros: 2_000_000,
costCenter: 'research',
});
const result = await qzk.spend({
agent: 'research-agent',
vendor: 'openai',
model: 'gpt-5.6',
costCenter: 'research',
estimatedMaxSpendMicros: 2_000_000,
}, async () => openai.responses.create({ ... }));qzk.spend will not invoke the callback unless preflight returns execution_eligible.qzk.authorize / preflight / record / verify remain unchanged.
Bounding admitted cost
An atomic reservation prevents two requests from claiming the same available balance. It protects the budget only when estimatedMaxSpendMicros adequately bounds what the admitted request can consume.
On the protected gateway path, QuantZK should validate that estimate against the request body, allowed model, configured pricing / tariff, output limits, and other billable features before reserving. Multi-instance deployments must share the durable reservation store (Postgres path) so replicas cannot oversubscribe the same budget.
Pilot reconciliation targets should state: percentage of dollars or requests, over which period, against which provider billing records, with what delay, and how missing records / EXECUTION_UNKNOWN remain visible in the measurement.
Implementation map
| Piece | Location |
|---|---|
| Boundary doc | protocol/docs/machine-spend-control-plane.md |
| Policy / budget / decide | protocol/packages/spend-control/ |
SDK control + spend | protocol/packages/sdk/control.js |
| DB migration | verifier-api/.../migrations/035_spend_control_plane.sql |
| API runtime | verifier-api/src/services/spendControlRuntime.js |
| Routes | verifier-api/src/routes/control.js → /api/control/v1 |
| Gateway | protocol/packages/gateway/ |
| Reconcile | protocol/packages/reconcile/ |
| Tests | protocol/test/spend-control.test.js, gateway.test.js, reconcile.test.js |
Status
- Protocol: Charge Authority v1 frozen within QZR-1 Candidate, unchanged.
- Control plane (P1–P3): SpendPolicy, atomic budget reservation,
/api/control/v1/*,qzk.control.authorize/qzk.spend. - Demo:
cd protocol && npm run demo:ai-spend-firewall(and olderdemo:spend-firewall/demo:gateway/demo:reconcile). - Gateway (P4):
@quantzk/gateway, OpenAI-compatible proxy; Levels 2–3 when upstream keys stay on the gateway. Demo:npm run demo:gateway. - Reconciliation (P5):
@quantzk/reconcile, AUTHORIZED / EXPECTED / OBSERVED / BILLED. Demo:npm run demo:reconcile. - Ops dashboard (P6):
/spend, Machine Spend Operations UI (overview, agents, reconciliation queue, decisions, evidence). - Provider compatibility (current): OpenAI Chat Completions / Responses via the gateway. Anthropic (and additional providers) are pilot-scoped second providers, not a published multi-adapter matrix yet. Streaming is rejected in gateway v0.1.
- Not yet: generalized multi-provider adapter pack (P7), portable approval / CA v2.
Compatibility (current)
| Area | Supported now | Pilot / limited | Not yet |
|---|---|---|---|
| OpenAI chat / responses via gateway | Yes | — | — |
| Anthropic as second provider | — | Yes, scoped pilot | General adapter pack |
| Streaming completions | — | — | Rejected in gateway v0.1 |
| Billing-data ingestion for reconcile | Demo + provider usage exports | Customer-specific connectors | Full warehouse connectors |
| Deployment | SDK (L1), gateway (L2–L3) | Customer VPC + egress (L4) | — |
| Shared durable store for multi-instance | Postgres reservation path | Required for multi-replica pilots | — |
P4 adversarial hardening (permanent)
| Attack | Defense |
|---|---|
| Authorize cheap model, forward expensive | Freeze outbound body + digest; re-check vs CA fields before proxy |
| Client retry duplicates provider call | Idempotency-Key / X-QuantZK-Idempotency-Key store |
| Upstream timeout after dispatch | EXECUTION_UNKNOWN, hold reservation; open reconciliation case (do not RELEASE) |
| Streaming / interrupted token burn | stream=true rejected in v0.1 |
| Secret exfiltration | Redact + assert upstream key never in responses/errors |
P5 reconciliation
Four values, never collapse:
| Value | Meaning |
|---|---|
| AUTHORIZED | Max exposure from Charge Authority / control decision |
| EXPECTED | Deterministic tariff × normalized usage |
| OBSERVED | Provider-reported usage (tokens, etc.) |
| BILLED | Invoice / usage-export charge |
Evidence sources carry provenance (gateway_observation, provider_response, provider_usage_api, …) with digest-pinned raw payloads. Statuses: MATCH, OVER_BILLED, UNDER_BILLED, USAGE_MISMATCH, UNAUTHORIZED_USAGE, DUPLICATE_BILLING, EXECUTION_UNKNOWN, …
Non-ZK initially. QZR may later reference reconciliation evidence without changing CA v1.
P6 Machine Spend Operations
Route: /spend (alias /machine-spend).
Surfaces the three layers without new protocol semantics:
| View | Answers |
|---|---|
| Overview | Settled / authorized / blocked / discrepancies / execution-unknown + protected value |
| Agents | Budget, reserved, settled, remaining, blocked attempts, open cases |
| Reconciliation | Queue ranked by status; always shows AUTHORIZED / EXPECTED / OBSERVED / BILLED |
| Decisions | ALLOW/DENY with reason, subject, vendor, model, requested exposure |
| Evidence | Authority / intent digest / provider digest / QZR, audit only |
Language discipline:
MATCH= compared evidence agrees under configured rules, not “provider usage is objectively true.”OVER_BILLED= billed exceeds QuantZK expected under available evidence/tariff, not “provider fraud.”
API helper: GET /api/control/v1/ops/summary?tenant_id=… (control-plane aggregates). The design-partner UI ships with a structured demo snapshot so FinOps flows are operable before live reconcile warehouses exist.
Product naming
| Name | Role |
|---|---|
| QuantZK | Company / platform |
| QuantZK Control | Commercial product, AI Spend Firewall |
| Charge Authority | Protocol primitive, what was authorized |
| QZR | Evidence protocol, what happened / was charged |
| VDI | Broader proof architecture |
Enforcement levels (control strength ≠ crypto claim)
None of these become: “QZR proves no bypass occurred.” Claim 4 remains intact.
| Level | Name | Statement |
|---|---|---|
| 1 | SDK-controlled | QuantZK prevents callback execution when the control decision fails (qzk.spend). |
| 2 | Gateway-controlled | QuantZK prevents forwarding through the protected gateway when authorization fails. |
| 3 | Credential-isolated | Protected upstream credentials are available only to the QuantZK gateway. |
| 4 | Egress-restricted | Deployment network policy restricts direct provider access outside the QuantZK gateway. |
Today’s SDK demo is Level 1. @quantzk/gateway delivers Levels 2–3 when OPENAI_API_KEY is configured on the gateway only.
QuantZK Gateway (P4)
OpenAI-compatible surface so agents switch base_url + QuantZK workload token:
client = OpenAI(
api_key=os.environ["QUANTZK_WORKLOAD_TOKEN"],
base_url="http://127.0.0.1:8787/v1",
)| Property | Statement |
|---|---|
| Package | protocol/packages/gateway (@quantzk/gateway) |
| Routes | POST /v1/chat/completions, POST /v1/responses, GET /health |
| Credential boundary | Agent never receives OPENAI_API_KEY; gateway injects it upstream |
| On DENY | HTTP 403; upstream is not called |
| Protocol | Still issues frozen Charge Authority v1 + existing preflight |
| Non-claim | Does not claim QZR proves no bypass (Claim 4) |
Demo: cd protocol && npm run demo:gateway
Serve: cd protocol && npm run gateway
Four meanings of spend
Never collapse these into one status:
| Meaning | Definition |
|---|---|
| Requested | Agent wants exposure of N micros |
| Reserved | N micros removed from currently available budget |
| Authorized | Charge Authority v1 allows execution under constraints |
| Settled | Actual consumption recorded against the reservation |
Control-plane state machine
REQUESTED
│
▼
EVALUATING
│
┌──┴────┐
▼ ▼
DENIED RESERVED
│
▼
AUTHORIZED (CA v1 issued)
│
▼
PREFLIGHT
│
┌────┴─────┐
▼ ▼
REJECTED EXECUTING
│
┌─────┼──────────┐
▼ ▼ ▼
FAILED EXECUTION COMPLETED
UNKNOWN
│ │ │
▼ ▼ ▼
RELEASE HOLD SETTLE
(recon) │
▼
RECEIPTOn FAILED before upstream dispatch, unused reservation is released. After dispatch, timeouts and interrupted executions become EXECUTION_UNKNOWN: the reservation is held, a reconciliation case is opened, and the budget is not released until the case is resolved.
Legal transitions live in protocol/packages/spend-control/lifecycle.js. Reservation / settle / release are operational. Do not fold them into CA v2 until there is a portability requirement.
Atomic reservation (budget race)
Postgres path: BEGIN → SELECT … FOR UPDATE on budget row + open reservations → compute available → insert or reject → COMMIT.
Memory path: per-account async mutex (withAccountLock / reserveAsync) for concurrent stress; sync reserve remains safe for the single-threaded decideSpend path.
Double settle is idempotent for the same amount; a conflicting retry is rejected.
Next milestone: Pilot-Ready v0.1
P1–P6 delivered the operational product surface. Focus measurement on Control pilots before expanding the platform.
Commercial SKU: QuantZK Control: AI Spend Firewall
Pilot pack: Design partner pilot
Prospect demo: npm run demo:ai-spend-firewall
Halborn: keep frozen CA/QZR assurance separate from control-plane/gateway findings. independent-review-prep.md.
