Critical path — Digital signature feature
Synced verbatim from the repo on every site build. Edit the source file on GitHub (link in the page footer); do not edit the rendered copy here. Use when the diff initiates, observes (webhook), or verifies a legally binding digital signature. Always combine with
auth-protected-action.mdandfile-upload-feature.md(signed documents land in the private bucket).
When to load this path
PRIMARY trigger (load this path as core when):
- A new class implements
SignatureGatewayInterfaceor a new signing template class withKEY+VERSION - A new
SigningRequestaggregate or state-machine transition - A new signature-provider webhook handler (signature-verify-before-parse)
- A new signed-document storage path or
document_sha256computation - A new ADR entry in
decisions.mdfor modality (simple/advanced/qualified)
SECONDARY trigger (load only when no primary path covers the diff already):
- A new
VoterforcanInitiateSigningorcanVerifySignedDocument - A new audit entry on signing events (
audit.send,audit.completed, etc.) - A frontend pre-sign review or post-sign verification component
DO NOT load when:
- The diff only modifies tests
- The diff only modifies
*.md - The “signature” is a hash / HMAC for non-legal purposes (load
payment-endpoint.mdif it’s a webhook signature, or §Security / SE-* otherwise)
Backend
Gateway seam
- DS-001 Every signing operation goes through
SignatureGatewayInterface— no provider SDK imports
Modality
- DS-002 Modality (
simple/advanced/qualified) declared per use case + jurisdiction indecisions.md; never silent downgrade
Templates
- DS-003 Templates as classes with
KEY+VERSIONconstants; old versions retained forever; live edits forbidden - DS-004 Multi-language templates per locale (i18n.md selects variant)
- DS-005 Template binary pinned by hash in
metadata.jsonAND in every signing record
State machine
- DS-006
SigningRequestaggregate enforces state machine; CHECK constraint mirrors states - DS-007 Re-signing creates a NEW SigningRequest; signed documents are immutable
Storage
- DS-008 On completion, signed PDF + audit-trail PDF stored in private bucket (FS-002); system records its own
document_sha256independent of provider - DS-009 Retention exceeds RTBF window for legal documents (gdpr-pii.md Section 17 carve-outs)
Webhooks
- DS-010 Verify provider signature on RAW body BEFORE parsing
- DS-011
processed_signature_webhooksdedup; insert in same DB tx as state change - DS-012 Out-of-order tolerance: handlers check current aggregate state
Sub-processor
- DS-013 Provider declared in
pii-inventory.md(GD-011) at integration time
Audit
- DS-014 Audit entries on send / completed / declined / expired / cancelled / reminder.sent
Privacy of signer data
- DS-015 Signer emails NEVER added to marketing lists — consent ledger says no
Authorization
- DS-016
canInitiateSigningandcanVerifySignedDocumentVoters - DS-017 Verification audit-trail URL is presigned (FS-009/FS-010), TTL ≤ 15 min
Observability
- DS-018 Span attributes: provider / purpose / template_version / modality / signer_count / outcome — NEVER signer email / national ID / contract amounts
- DS-019 Metrics bounded by provider / purpose / modality / outcome / decline_reason / error_class
Secrets
- DS-020
SIGNATURE_PROVIDER_WEBHOOK_SECRETinsecrets-manifest.mdwith rotation; integration tests behind@group signature-real
Hard blockers
- BE-001 Quality gates green
- SC-001 No secrets committed
Frontend (when signing surfaces touch UI)
- DS-021 Signing UI presents the document for review BEFORE sending
- DS-022 Pending-signature UX shows explicit state + timestamps; no silent loading
- DS-023 Signed documents downloaded via presigned URL with
attachmentdisposition - DS-024 Verification surface displays both system
document_sha256AND provider audit-trail link
Coverage map vs full checklist
This path covers these sections of backend-review-checklist.md / frontend-review-checklist.md:
- §Digital signatures — DS-001..DS-020 (Gateway seam, modality, templates, state machine, storage, webhooks, sub-processor, audit, privacy of signer data, authorization, observability, secrets)
- §Sub-processor inventory (carried over) — GD-011 (verified via DS-013: provider declared in
pii-inventory.md) - §Hard blockers — BE-001, SC-001
- §Frontend Signatures — DS-021..DS-024
This path does NOT cover. Load the corresponding checklist section ONLY when the diff touches:
tests/directory (especially@group signature-real) → load §Testing- The private-bucket storage rules in detail (FS-002, FS-009, FS-010) → load
file-upload-feature.md(path) - PII handling for signer fields → load
pii-write-endpoint.md(path) - Migration adding the
signing_requeststable → load §Migrations (DM-*)
What this path does NOT cover
- Authorization →
auth-protected-action.md(mandatory) - The private-bucket storage rules →
file-upload-feature.md - PII fields on the signer →
pii-write-endpoint.md