Append-only ledger

The most recent bid. Sourced from the ledger.

Provespend writes a tamper-evident row to this ledger for every auction the agent touches. Updates and deletes are rejected at the API — the only verb accepted is POST. The panel on the right fetches the latest row live, so the demoable claim matches the production posture.

Schema
append-only
Update/delete
rejected
Seed rows
3 channels
audit.provespend.app
append-only

Loading the latest decision…

What one row carries

The live row on this page resolves to the schema BidDecision in prisma/schema/decisions.prisma. Same vocabulary as the explainability page's reference table, so the demoable copy and the production schema stay in lockstep.

  • occurredAtUTC timestamp of the auction evaluation.
  • channelMeta, Google, TikTok, LinkedIn, or programmatic.
  • campaignThe named campaign that owned the spend.
  • ruleIdThe named policy rule that fired (e.g. meta_roas_floor).
  • spendCentsSpend × 100 — integer, never float.
  • policyVersionWhich policy.yaml version the decision was evaluated against.
  • decisionBID, HOLD, or ROTATE.
  • rationaleThe signal and threshold from the policy file that produced the decision.

Endpoints

append-only
  • GET/api/decisions?limit=1Returns the most recent ledger row (limit 1..50, newest first).
  • POST/api/decisionsAppends one row. Validates channel/decision against the zod contract.
  • PATCH/api/decisions405 — the ledger is append-only. Update is rejected at the API.
  • PUT/api/decisions405 — the ledger is append-only. Replace is rejected at the API.
  • DELETE/api/decisions405 — the ledger is append-only. Delete is rejected at the API.

The seed fills three realistic rows on first boot (Meta, Google, TikTok) and stays idempotent on every subsequent boot via createMany({ skipDuplicates: true }) against the @@unique(occurredAt, channel, campaign, ruleId) natural key.