Add consent block support for agreement workflows (v0.4.0) - #100
Merged
Conversation
Introduce a dedicated BEGIN NOSTR CONTRACT block so a signatory's consent is an explicit, intentional act rather than a side effect of replying (every reply is signed for chain-of-custody, so a signature alone cannot mean assent). - New block type + END tag in the armor vocabulary (Section 2.1). - Extend per-level signature coverage to include the CONTRACT block (level(L) = body || recipients || contract), fixed body->recipients->contract order (Section 4.2). - Define the consent block: fields (agreement H, signer), the document hash H (over level-1 body+recipients, excluding contracts to avoid self-reference), and ordering as content (not a trailer), one per level (Section 11.3). - Rewrite Signing Round / Completion / Verification to key off verified CONTRACT blocks over H, dedup by pubkey, and treat CONTRACT-less replies as comments (Sections 11.4-11.6); handle originator-as-signatory. - HTML rendering for agreements: status banner + green consent panels vs muted comment sections, with non-colour-dependent labels (Section 6.2.6). - Backward compatibility note: older clients ignore CONTRACT and see a plain signed reply (Section 12). Bumps spec to 0.4.0-draft.
…ly privacy roadmap - Rename the consent block CONTRACT -> CONSENT throughout (BEGIN/END NOSTR CONSENT, level(L) consent term, HTML rendering, completion/verification). CONSENT names the act, avoids colliding with 'agreement' (which SIGit and this spec both use for the whole container), and matches SIGit verbiage (signer/viewer roles are already identical). Also drop the '(Contract)' parenthetical from the Agreement Message heading. - Add Section 11.7 'Relation to SIGit' mapping our model onto SIGit's (keys<->RECIPIENTS, meta<->H, prevSig/docSignatures<->nested signatures, Sign event<->CONSENT block) and noting the email-native vs relay+Blossom transport difference. - Note the planned Nostr-only agreement transport (fold in SIGit's NIP-59 gift-wrap/Blossom privacy model) in Section 10.9; emphasize the consent semantics are transport-independent.
This was referenced Jun 13, 2026
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.
Summary
This PR introduces explicit consent tracking for multi-recipient agreement workflows in the Nostr-Mail protocol. It adds a new
CONSENTarmor block type that allows signatories to declare binding consent to a specific agreement document, separate from ordinary signed replies or comments.Key Changes
BEGIN NOSTR CONSENT/END NOSTR CONSENTarmor delimiters to declare explicit consent to an agreementagreement(document hash) andsigner(pubkey)H: Defined asSHA-256(body_1 || recipients_1)computed over the originating message only, fixed for the agreement's lifetimelevel(L) = decode(body_L) || canonical(recipients_L) || canonical(consent_L)Notable Details
Hdeliberately excludes CONSENT blocks to remain fixed and prevent self-referencehttps://claude.ai/code/session_016YN7L4j4K4nqnfbdu6Lsgm