Skip to content

feat(testkit-settlement): B06 Privy and Arc sponsor evidence - #41

Merged
SuPuHe merged 2 commits into
developfrom
milestone/b06-sponsor-evidence
Sep 8, 2026
Merged

SuPuHe merged 2 commits into
developfrom
milestone/b06-sponsor-evidence

Conversation

@selezenart

@selezenart selezenart commented Sep 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds the B06 sponsor evidence bundle: a fail-closed verifier for the Privy
authorization boundary and the Arc Testnet settlement rail, a CLI that publishes
a sanitized report, an evidence index, and the handoff document.

The live Arc Testnet run already happened and is recorded on develop
(docs/settlement/LIVE_EVIDENCE.md, status LIVE_RUN). B06 re-verifies that
record rather than executing another payment: a second live settlement would
spend testnet funds to prove nothing the recorded run does not already prove.

Verify with one command:

pnpm --filter @oneshot/testkit-settlement evidence:b06

Scope and acceptance criteria

  • The change is limited to the stated milestone or issue.
  • Acceptance criteria are listed and satisfied.
  • No unrelated cleanup is included.
Task Result
B06.1 Privy evidence: policy scope, denials with zero settlement, no bypass PASS
B06.2 Arc evidence: request identity bound to hash, block, Transfer log, explorer PASS
B06.3 Ambiguity: lost response reconciles to the original transaction PASS
B06.4 Mainnet readiness without a mainnet transaction PASS
B06.5 Sanitization audit over the published bundle PASS
B06.6 Qualification input with NOT VERIFIED where proof is absent PASS

Handoff artifact: docs/settlement/B06_SPONSOR_EVIDENCE.md.

Product and security invariants

  • Tenant isolation remains fail-closed.
  • Sponsor authorization, auditability, and daily caps remain enforced where applicable.
  • Recipients cannot modify sponsor controls or access sponsor-only data.
  • No secret, token, production identifier, or personal data is committed or pasted into review prompts.
  • Any non-applicable invariant is explained below.

Invariant notes:

  • One intent, at most one settlement: enforced as an assertion over the
    recorded evidence. The recovery record must show exactly one settlement and
    zero replacement submissions, and a tampered counter fails the bundle.
  • UNKNOWN without blind retry: the drill must show UNKNOWN reconciling
    to the original transaction through a read-only lookup.
  • No new external effects: this milestone adds no settlement path. The
    verifier reads recorded evidence and repository state only.
  • Money: amounts are compared as bigint from canonical integer strings.
  • Secrets: the published bundle is held to the arc-adapter redaction
    contract at every level, including scalars nested in arrays and the query
    string of an allowlisted URL.

Test matrix cases selected: Privy denial, lost payment response, same request
twice. Each is asserted in both directions — the recorded evidence passes, and a
tampered record fails.

Note on the redaction allowlist

Two public fields trip the adapter's generic rules: token_contract matches the
token key-name pattern, and explorer_url embeds the 32-byte transaction
hash. Both are load-bearing — drop them and the bundle no longer proves which
asset moved or where to verify it.

packages/arc-adapter/src/redaction.ts is deliberately not modified. The
exemption lives in B06 with a per-field shape check: token_contract must be an
EVM address, explorer_url must be an https URL with no embedded credentials
and is still scanned for credential patterns with the transaction hash stripped.
No other caller of the shared contract is affected.

Validation

Commands and results:

pnpm --filter @oneshot/testkit-settlement build: PASS
pnpm --filter @oneshot/testkit-settlement lint: PASS
pnpm --filter @oneshot/testkit-settlement test: PASS (120 tests, 64 new)
pnpm --filter @oneshot/testkit-settlement evidence:b06: PASS (5/5 sections; Privy QUALIFIED, Arc QUALIFIED, The Graph NOT VERIFIED)
pnpm lint: PASS
pnpm typecheck: PASS
pnpm test: PASS (50 files, 669 tests; base was 47 files, 605 tests)
pnpm check:generated: PASS
pnpm validate:fixtures: PASS
markdownlint-cli2 and prettier over changed paths: PASS

Independent review evidence

Gate A — exact candidate tree before push

Three rounds. Round three is the tree that was pushed.

Round 1 — 83d9e8091f8fe093bfdac83681187560ba1504b9 — VERDICT: FAIL

One blocking finding, since fixed: the sanitization walk recursed into arrays
but returned early for scalar elements, so a PEM key or JWT nested in an array
passed the audit while the same value under a scalar key failed. A hole in a
security-enforcing check. Fixed, and the fix is asserted by tests in the failure
direction.

Round 2 — 1f9f5ed88d25ae9cc18c7ad2ed4f809f72247cbc — VERDICT: PASS

No blocking findings. Three non-blocking, all fixed rather than carried:
receipt validation stopped at "non-null object"; checkMainnetReadiness read
the compile-time profile so the enabled and carries-values directions were
unassertable; and evidence:b06 ran the compiled output without building. The
reviewer's residual risk about token_contract accepting any short public value
is closed by requiring an EVM address shape.

Round 3 — the reviewed and pushed tree

  • Base commit SHA: 0291b684e187557e13c47869359cbab445ee4148

  • Candidate tree SHA: e9f89504866075b50201814f4a5da0d494c29028

  • Candidate commit SHA: 310daf16703957650e6422420fddedc3b627ab59

  • Reviewer tool: free-pi-cli

  • Reviewer model: deepseek-v4-flash

  • Verdict: VERDICT: PASS

  • Findings or residual risks: no blocking findings. Three non-blocking, carried:

    1. parseReceipt validates receipt-level fields but not each log entry's
      shape; a malformed log still exits non-zero rather than producing a listed
      failure.
    2. The branch base is the merge-base with current develop; there is no file
      overlap with the commits merged since.
    3. arc.transfer-identity-recorded passes conditionally because the published
      bundle carries no raw receipt. Capturing a sanitized receipt would let the
      bundle exercise verifyReceipt end to end.
  • The reviewed tree equals the committed tree.

Gate B — exact remote PR head

  • Pull request URL/number: feat(testkit-settlement): B06 Privy and Arc sponsor evidence #41 feat(testkit-settlement): B06 Privy and Arc sponsor evidence #41
  • Remote head commit SHA: 310daf16703957650e6422420fddedc3b627ab59
  • Remote head tree SHA: e9f89504866075b50201814f4a5da0d494c29028
  • Reviewer tool: free-pi-cli
  • Reviewer model: deepseek-v4-flash
  • Verdict: VERDICT: PASS
  • Findings or residual risks: no blocking findings. Three non-blocking, carried:
    1. parseReceipt validates receipt-level fields but not individual log entry
      shapes; a malformed log throws from inside verifyReceipt rather than
      producing a listed failure. Fail-closed either way.
    2. isPublicIdentifier would accept a short JWT-shaped string under a
      hypothetical token_symbol or explorer_host key. Not reachable in the
      current bundle, where token_contract requires an EVM address shape and
      explorer_url requires https plus a content scan.
    3. The OFFLINE_PROTECTED / UNPUBLISHED terminology drift between
      docs/settlement/LIVE_EVIDENCE.md and packages/arc-adapter/src/profiles.ts,
      left to its own change in a base-owned file.

Reviewer evidence: head tree equals the Gate A tree; branch diff is exactly 8
files with no path overlap against the commits merged into develop since the
fork point; the B06 test file was re-run independently on the exact head; all
five mainnet-readiness artifacts and every cited adapter file exist in the head
tree.

Milestone readiness: scope and acceptance criteria PASS, tests and required
checks PASS, security/privacy/secrets PASS, documentation and operations PASS,
ready for human review PASS.

  • Gate B reviewed the current remote head and matches Gate A's approved tree, or a fresh Gate A was run for the changed tree.
  • Agent policy / repository-policy and all applicable CI checks pass.

Risk and rollback

Residual risks:

  • Receipt log entries are not shape-validated; failure is fail-closed but not a
    listed check.
  • The published bundle carries no raw receipt, so chain-level re-verification is
    not exercised on it; the check says so rather than claiming otherwise.
  • Evidence is one recorded run per drill.
  • docs/settlement/LIVE_EVIDENCE.md labels the mainnet profile
    OFFLINE_PROTECTED while profiles.ts and B06 use UNPUBLISHED. Real
    terminology drift in a base-owned file; left for its own change.

Rollback: additive. Reverting the commit removes the evidence module, its CLI,
tests, the index, and the document. Nothing else imports them.

Human merge

  • A human owner has reviewed the evidence and will perform the merge.

Adds a fail-closed verifier for the Privy and Arc sponsor evidence, a CLI
that publishes a sanitized report, an evidence index, and the B06 handoff
document.

The live Arc Testnet run already happened and is recorded in
docs/settlement/LIVE_EVIDENCE.md, so this milestone re-verifies that
record rather than executing another payment. What it checks is the
binding rather than the label:

- Privy denials only count when the broadcast and settlement counters
  were observed at zero, and a drill that omits the amounts it compared
  fails rather than skipping the check.
- The Arc settlement must match the pinned network and token, carry a
  canonical integer amount, and publish an explorer link that is https,
  on an allowed host, and contains the transaction hash on screen.
- The lost-response drill must reach UNKNOWN, reconcile to the original
  transaction, and leave exactly one settlement.
- The mainnet profile must be disabled, unpinned, and carry no chain,
  RPC, explorer, or token value. Readiness is the absence of usable
  values, not a flag.
- Qualification statuses are computed, so any failing section or a
  non-live record downgrades a sponsor to NOT VERIFIED.

The sanitization audit applies the arc-adapter redaction contract at
every level, including scalars nested in arrays and the query string of
an allowlisted URL. Two public fields need a narrow exemption from the
generic rules: token_contract matches the token key pattern, and
explorer_url embeds the transaction hash. Both are load-bearing evidence,
so the exemption lives here with a per-field shape check rather than
widening the shared adapter contract for every caller.
@selezenart
selezenart marked this pull request as ready for review September 8, 2026 21:30
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
oneshot 8ea308b Sep 08 2026, 09:53 PM

Gate B and the following Gate A round found three ways the evidence
engine could report a pass it had not earned.

Receipt validation stopped at the receipt level, so a malformed log
entry threw from inside the adapter instead of producing a listed
failure. Every log is now checked for address, data, logIndex, and a
string topics array.

The public-field allowlist shared one permissive guard, which would have
accepted a short JWT-shaped string under token_symbol or explorer_host.
That guard is gone; each allowlisted field now has its own shape: EVM
address, asset symbol, decimal count, hostname, https URL.

The replay check matched REPLAY as a substring, so a tampered
NOT_REPLAYED would have satisfied a check asserting the opposite. It now
matches REPLAYED or RETURNED_EXISTING_RESULT exactly, with tests for the
tampered spellings.
@SuPuHe
SuPuHe merged commit 48391e4 into develop Sep 8, 2026
4 checks passed
@SuPuHe
SuPuHe deleted the milestone/b06-sponsor-evidence branch September 8, 2026 22:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants