Skip to content

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):

text
┌─────────────────────────────────────────────┐
│        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 ​

PropertyLayerPortable / cryptographic?
Policy allow/denyControl planeNo, operational
Hierarchical budgets + reservationControl planeNo, operational (v1)
Gateway path enforcementControl plane / opsNo, Claim 4 non-claim
Signed Charge AuthorityProtocolYes
Preflight single-use consumeProtocolYes (trusted channel)
QZR receipt bindingProtocolYes

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 ​

text
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 reservation

SpendPolicy (commercial object) ​

Not a new crypto schema. Hashed for binding into existing policy_digest:

json
{
  "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.

MethodPathRole
POST/api/control/v1/decidePolicy + budget → decision; optionally issue CA v1
POST/api/control/v1/executeDecide → issue CA v1; then use existing /billing/preflight before vendor call
POST/api/control/v1/reconcileSettle reservation against actual charge
POST/api/control/v1/reservations/:id/releaseRelease unused reservation
GET/api/control/v1/budgetsList budget accounts
GET/api/control/v1/subjectsList spend subjects
GET/api/control/v1/policiesList policies
GET/api/control/v1/decisionsRecent allow/deny decisions
POST/api/control/v1/policiesUpsert policy
POST/api/control/v1/budgetsUpsert budget account
POST/api/control/v1/subjectsUpsert 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 ​

js
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 ​

PieceLocation
Boundary docprotocol/docs/machine-spend-control-plane.md
Policy / budget / decideprotocol/packages/spend-control/
SDK control + spendprotocol/packages/sdk/control.js
DB migrationverifier-api/.../migrations/035_spend_control_plane.sql
API runtimeverifier-api/src/services/spendControlRuntime.js
Routesverifier-api/src/routes/control.js → /api/control/v1
Gatewayprotocol/packages/gateway/
Reconcileprotocol/packages/reconcile/
Testsprotocol/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 older demo: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) ​

AreaSupported nowPilot / limitedNot yet
OpenAI chat / responses via gatewayYes——
Anthropic as second provider—Yes, scoped pilotGeneral adapter pack
Streaming completions——Rejected in gateway v0.1
Billing-data ingestion for reconcileDemo + provider usage exportsCustomer-specific connectorsFull warehouse connectors
DeploymentSDK (L1), gateway (L2–L3)Customer VPC + egress (L4)—
Shared durable store for multi-instancePostgres reservation pathRequired for multi-replica pilots—

P4 adversarial hardening (permanent) ​

AttackDefense
Authorize cheap model, forward expensiveFreeze outbound body + digest; re-check vs CA fields before proxy
Client retry duplicates provider callIdempotency-Key / X-QuantZK-Idempotency-Key store
Upstream timeout after dispatchEXECUTION_UNKNOWN, hold reservation; open reconciliation case (do not RELEASE)
Streaming / interrupted token burnstream=true rejected in v0.1
Secret exfiltrationRedact + assert upstream key never in responses/errors

P5 reconciliation ​

Four values, never collapse:

ValueMeaning
AUTHORIZEDMax exposure from Charge Authority / control decision
EXPECTEDDeterministic tariff × normalized usage
OBSERVEDProvider-reported usage (tokens, etc.)
BILLEDInvoice / 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:

ViewAnswers
OverviewSettled / authorized / blocked / discrepancies / execution-unknown + protected value
AgentsBudget, reserved, settled, remaining, blocked attempts, open cases
ReconciliationQueue ranked by status; always shows AUTHORIZED / EXPECTED / OBSERVED / BILLED
DecisionsALLOW/DENY with reason, subject, vendor, model, requested exposure
EvidenceAuthority / 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 ​

NameRole
QuantZKCompany / platform
QuantZK ControlCommercial product, AI Spend Firewall
Charge AuthorityProtocol primitive, what was authorized
QZREvidence protocol, what happened / was charged
VDIBroader proof architecture

Enforcement levels (control strength ≠ crypto claim) ​

None of these become: “QZR proves no bypass occurred.” Claim 4 remains intact.

LevelNameStatement
1SDK-controlledQuantZK prevents callback execution when the control decision fails (qzk.spend).
2Gateway-controlledQuantZK prevents forwarding through the protected gateway when authorization fails.
3Credential-isolatedProtected upstream credentials are available only to the QuantZK gateway.
4Egress-restrictedDeployment 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:

python
client = OpenAI(
    api_key=os.environ["QUANTZK_WORKLOAD_TOKEN"],
    base_url="http://127.0.0.1:8787/v1",
)
PropertyStatement
Packageprotocol/packages/gateway (@quantzk/gateway)
RoutesPOST /v1/chat/completions, POST /v1/responses, GET /health
Credential boundaryAgent never receives OPENAI_API_KEY; gateway injects it upstream
On DENYHTTP 403; upstream is not called
ProtocolStill issues frozen Charge Authority v1 + existing preflight
Non-claimDoes 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:

MeaningDefinition
RequestedAgent wants exposure of N micros
ReservedN micros removed from currently available budget
AuthorizedCharge Authority v1 allows execution under constraints
SettledActual consumption recorded against the reservation

Control-plane state machine ​

text
REQUESTED
    │
    ▼
EVALUATING
    │
 ┌──┴────┐
 ▼       ▼
DENIED  RESERVED
          │
          ▼
      AUTHORIZED   (CA v1 issued)
          │
          ▼
       PREFLIGHT
          │
     ┌────┴─────┐
     ▼          ▼
 REJECTED    EXECUTING
                │
          ┌─────┼──────────┐
          ▼     ▼          ▼
       FAILED  EXECUTION  COMPLETED
               UNKNOWN
          │     │          │
          ▼     ▼          ▼
       RELEASE  HOLD     SETTLE
                (recon)     │
                            ▼
                         RECEIPT

On 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.

QuantZK Control docs: gateway, reconciliation, and optional portable evidence.