Skip to content

test(documents): end-to-end sign-off against a real database and real keys - #386

Merged
QSchlegel merged 1 commit into
preprodfrom
claude/document-e2e
Aug 23, 2026
Merged

test(documents): end-to-end sign-off against a real database and real keys#386
QSchlegel merged 1 commit into
preprodfrom
claude/document-e2e

Conversation

@QSchlegel

Copy link
Copy Markdown
Collaborator

Document Sign-Off had no integration test. Every existing test covers one piece in isolation, and the chain those pieces form — create → draft → publish → freeze the signer set → sign → reach the threshold → export a proof → verify it — had never been executed.

That is exactly where this feature's worst bug lived. sign() rejected every valid signature for as long as the feature existed, and its unit test didn't catch it because it mocked checkSignature — the one thing it was meant to prove.

So this signs with a real key, through the real helper, against a real Postgres. The wallet is seeded with an address whose mnemonic the test holds, which is what makes a genuine CIP-8 signature possible instead of a fixture pretending to be one.

Three cases

  1. The whole lifecycle, ending in verifyProof({ valid: true }) through the public procedure. It also asserts the published contentHash equals sha256 of the bytes the server stored — the claim that makes "what you sign is what was published" true rather than asserted — and that publishing is refused outright when server storage is off.
  2. A forged payload is rejected and the version stays InReview.
  3. A new version supersedes a signed one and resets approvals to zero.

Two bugs I found were mine, and both are worth recording

  • publishDraft creates a version without bumping the draft revision, so my second save presented a stale expectedRevision. Worth knowing before someone builds on the draft API.
  • My first tamper attempt edited prose in the body — and proved nothing, because the payload binds the content hash, not the text. The submission legitimately succeeded. It now tampers with the hash itself, and asserts the string actually changed, so the test can't silently go vacuous again.

On the browser suite

Playwright is not runnable here: globalSetup requires three funded preprod mnemonics, a Blockfrost key and a bootstrapped context, and running it spends real testnet ADA. It is covered by CI — playwright-browser passed on every PR in this batch (#384, #385).

This test plugs into the existing trpc-integration-tests workflow, so it runs on every PR from here.

88 integration tests pass, 1161 unit tests pass, tsc --noEmit clean, next build exit 0.

🤖 Generated with Claude Code

… keys

Document Sign-Off had no integration test. Every existing test covers one
piece of it in isolation, and the chain those pieces form — create, draft,
publish, freeze the signer set, sign, reach the threshold, export a proof,
verify it — had never been executed.

That is exactly where this feature's worst bug lived. `sign()` rejected
every valid signature for as long as the feature existed, and its unit
test did not catch it because it mocked `checkSignature` — the one thing
it was meant to prove. So this test signs with a real key, through the
real helper, against a real Postgres. The wallet is seeded with an address
whose mnemonic the test holds, which is what makes a genuine CIP-8
signature possible instead of a fixture pretending to be one.

Three cases:

- The whole lifecycle, ending in `verifyProof({ valid: true })` through
  the public procedure. It also asserts the published contentHash equals
  sha256 of the bytes the server stored, which is the claim that makes
  "what you sign is what was published" true rather than asserted, and
  that publishing is refused outright when server storage is off.
- A forged payload is rejected and the version stays InReview.
- A new version supersedes the signed one and resets approvals to zero.

Two bugs found writing it were mine, not the product's, and both are worth
recording. `publishDraft` creates a version without bumping the draft
revision, so my second save presented a stale expectedRevision. And the
first tamper attempt edited prose in the body — which proved nothing,
because the payload binds the content HASH, not the text. It now tampers
with the hash itself, and asserts the string actually changed so the test
cannot silently go vacuous again.

Runs in the existing trpc-integration-tests workflow. 88 integration tests
pass, 1161 unit tests pass, tsc clean, next build exit 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
multisig Ready Ready Preview Aug 23, 2026 4:18pm

Request Review

@QSchlegel
QSchlegel merged commit 2dead16 into preprod Aug 23, 2026
8 checks passed
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.

1 participant