Skip to content

Use case: compliance evidence

Your customer’s auditor asks what your AI agents actually did. Screenshots of a dashboard don’t survive that conversation — the evidence has to be verifiable by someone who does not trust you, on tooling you don’t control. Pangolin Scale seals every run into an exportable bundle whose verification recomputes everything rather than trusting a stored verdict.

  • An exportable evidence bundle per run: the per-item dispatch manifests (references only — secret values never appear), the hash-chained lifecycle log, the signed and anchored Merkle root, and a verification report.
  • An optional RFC 3161 trusted-time token — when a TimestampAuthority is configured, the bundle carries a third-party timestamp attesting when the root existed, independently provable from the operator’s clock (timeTier: tsa-attested). Absent timestamps are self-evidencing — the report openly reads timeTier: asserted rather than overclaiming. Trusted time is a separate dimension and never changes the tamper claim.
  • One-command re-verificationpangolin verify bundle.json replays the hash chain, recomputes the Merkle root, fetches the anchored root from the live anchor, checks the signature, and checks provenance closure (every consumed input ref must be the sealed product of a completed item in the same run). On a clean bundle:
pangolin verify · run_a3f9c2 ✓ TAMPER-EVIDENT
──────────────────────────────────────────────────────────
✓ chain 10 entries, hash-linked, no gaps
✓ root merkle = anchored root
✓ signature true
✓ anchor s3:my-audit-bucket (external-immutable)
✓ handoff 3 input refs accounted for
  • CI-gateable exit codes — a bundle that fails any check exits non-zero, so verification can gate a pipeline or an incident review. --json emits the raw report; --full prints every ledger row.

The report’s claim field is derived, never asserted. tamper-evident is licensed only when the anchor tier is external-immutable or higher and every check passed — any failure, including an unreachable anchor, collapses the claim to tamper-detecting. The default LocalAnchor stores the root in the same store as the log, so it can never earn more than tamper-detecting; the S3ObjectLockAnchor writes the root to S3 Object Lock in COMPLIANCE mode — a separate trust domain that survives a database-side rewrite. The full model, including what each tier does not guarantee, is in Audit & guarantee tiers.

Independent verification — what the auditor needs

Section titled “Independent verification — what the auditor needs”

pangolin verify is deliberately not a pure function of the bundle file: it fetches the anchored root from the live anchor, never the copy embedded in the bundle (a bundle carrying its own trusted root would let a tamperer rewrite the log and the root together). An independent auditor therefore needs two things:

  1. The bundle file.
  2. Read access to the anchor that sealed the run — for the external-immutable tier, the S3 Object Lock location — wired into their own pangolin.config.

For programmatic use, the same check is the verifyBundle(bundle, { anchor }) entry point exported from @quarry-systems/pangolin-orchestrator, so an auditor can re-verify inside their own tooling. The step-by-step flow is in Export & verify an audit bundle.

Any example run ends by assembling and printing the bundle report. The fastest offline path (no Docker, no API key) drives a real orchestrator with a fake executor and asserts the bundle verifies:

Terminal window
pnpm install
pnpm --filter demo-claims-appeals-example test