Document Sign-Off MVP + roadmap MRP mapping - #356
Open
QSchlegel wants to merge 2 commits into
Open
Conversation
…m/hours line The month headings were renumbered on 2026-08-03 (984aa46) so that Month 1 = April, but MRP task cards created before that date still carry bullet text for the following month — the card headed "MRP Month 2" lists the June workstreams. That mismatch has now cost enough time to be worth writing down. - Add an MRP task mapping table at the top: MRP Month N = roadmap Month N = calendar month, for all twelve months, with the on-chain task hashes we have and a note explaining why the cards disagree. - Route each MRP month to the actual merged PRs behind it (April 10, May 3, June 51, July 16), each count linking to the exact GitHub search so any row can be reproduced rather than taken on trust. - Widen "Delivered to date" from May–July to April–July. April's output is infrastructure, so it folds into the existing sections: the preprod environment and real-chain smoke CI (#218, #217) under Testing & CI, and a new transaction-and-signing-integrity through-line under Platform (#217 VKey witness filtering -> #227 invalid-CBOR guard -> #257 Mesh pin + witness verification guard). - Recover two May items the 2026-07-26 audit had missed: the Import Wallet wizard (#259) and the #257 signing fix. - Fix the timeline left stale by the renumbering: April 2026 – March 2027, in ROADMAP.md, the /roadmap page and the SEO description. - Remove the "Quirin + Andre · ~25 h/wk" line from ROADMAP.md and the public roadmap page. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…gn-off Implements PRD-001: a wallet-native, off-chain approval layer where a team binds approval to an exact content hash, inherits the wallet's signer set and threshold, and exports a proof anyone can verify without an account. Two rules carry the feature, and both are enforced server-side rather than in the UI: 1. Version-hash binding. submitSignerAction rebuilds the canonical signed payload from the server's own records and requires a byte-identical match *before* the signature is checked, so a signature collected for one version can never be replayed onto another, and a tampered comment invalidates the submission. Inline content is re-hashed server-side and rejected on mismatch. 2. Threshold inheritance from a frozen snapshot. DocumentSignerSnapshot captures the wallet's signers, threshold and policy hash when the round starts; approval counting reads the snapshot, never the live wallet, so changing wallet membership cannot rewrite a decision already made. Data model (5 models + migration 20260805090000): Document, DocumentVersion, DocumentReview, DocumentSignerSnapshot, DocumentEvent. The migration enables RLS with deny-all PostgREST policies on all five tables, matching the contract in 20260706100000_enable_rls_followup_tables (#332). Router (src/server/api/routers/documents.ts): createDocument, uploadVersion, startReview, submitSignerAction, exportProof, verifyProof, plus the reads the pages need. CIP-8 verification uses Mesh's checkSignature against the signer's address. verifyProof is public on purpose — a counterparty holding the JSON and the file must be able to check it without an account, and it touches no DB. Four routes under /wallets/[wallet]/documents: list, create, detail, and the version review page. Files are hashed in the browser (SHA-256 via WebCrypto); only the digest is sent, so the bytes never leave the signer's machine. src/lib/documents/ is dependency-free apart from node crypto, with the signature check injected into the verifier — the same code can run in an offline verifier with no Mesh install. Uploading a new version supersedes the previous one and starts a fresh round at zero approvals: approval is bound to the hash, not the title. Tests: 28 covering canonicalization, version-hash binding, threshold evaluation and proof verification including tampering, duplicate signers, out-of-snapshot signers and non-canonical payloads. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two independent changes, one per commit — review them separately.
1.
docs(roadmap)— MRP mapping and the April–July windowThe 2026-08-03 renumbering (
984aa46) moved Month 1 to April, but MRP task cards created before that still carry the following month's bullet text — the card headed "MRP Month 2" lists the June workstreams. This writes the mapping down so it stops costing time.ROADMAP.md: MRP Month N = roadmap Month N = calendar month, all twelve months, with the on-chain task hashes we have.April 2026 – March 2027) inROADMAP.md, the/roadmappage and the SEO description; removes theQuirin + Andre · ~25 h/wkline from both.2.
feat(documents)— Document Sign-Off MVP (PRD-001)A wallet-native, off-chain approval layer: bind approval to an exact content hash, inherit the wallet's signers and threshold, export a proof anyone can verify without an account. No chain dependency.
Two rules carry the feature, and both are enforced server-side, not in the UI:
submitSignerActionrebuilds the canonical signed payload from the server's own records and requires a byte-identical match before the signature is checked. A signature collected for one version cannot be replayed onto another, and a tampered comment invalidates the submission. Inline content is re-hashed server-side and rejected on mismatch.DocumentSignerSnapshotcaptures the wallet's signers, threshold and policy hash when the round starts. Approval counting reads the snapshot, never the live wallet — changing wallet membership cannot rewrite a decision already made.Data model —
Document,DocumentVersion,DocumentReview,DocumentSignerSnapshot,DocumentEvent, migration20260805090000_add_document_signoff. The migration enables RLS with deny-all PostgREST policies on all five tables, matching the contract in20260706100000_enable_rls_followup_tables(#332).Router —
createDocument,uploadVersion,startReview,submitSignerAction,exportProof,verifyProof. CIP-8 verification via Mesh'scheckSignatureagainst the signer's address.verifyProofis public on purpose: a counterparty holding the JSON and the file must be able to check it without an account, and it reads nothing from the database.Four routes under
/wallets/[wallet]/documents— list, create, detail, version review. Files are hashed in the browser via WebCrypto; only the digest is sent, so the bytes never leave the signer's machine.src/lib/documents/is dependency-free apart from nodecrypto, with the signature check injected into the verifier — the same code runs in an offline verifier with no Mesh install.Heads-up for the deploy
This adds a migration. Railway's
prestartrunsprisma migrate deploy, so merging topreprodwill apply20260805090000_add_document_signoffto the preprod database on the next deploy. Five new tables, no changes to existing ones.Verification
npx tsc --noEmit— clean (the pre-existingtxScriptRecovery.test.tserrors onpreprodare untouched)npx jest src/__tests__/documentSignoff.test.ts— 28 passing: canonicalization, version-hash binding, threshold evaluation, and proof verification including tampering, duplicate signers, out-of-snapshot signers and non-canonical payloadsnpm run build— passes; all four document routes register as server-rendered/roadmapchecked in a local production build (next devcannot serve SSR in a worktree — Turbopack resolves the whisky WASM to/ROOT/node_modules/…)Not included
PRD-001 is still
status: Draft. Proof export is JSON only — the PDF summary and the public verify page are the M5 half of the MVP.🤖 Generated with Claude Code