Skip to content

Add consent block support for agreement workflows (v0.4.0) - #100

Merged
asherp merged 2 commits into
stagingfrom
claude/nostr-mail-cc-contracts-65p6sr
Jun 13, 2026
Merged

Add consent block support for agreement workflows (v0.4.0)#100
asherp merged 2 commits into
stagingfrom
claude/nostr-mail-cc-contracts-65p6sr

Conversation

@asherp

@asherp asherp commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Summary

This PR introduces explicit consent tracking for multi-recipient agreement workflows in the Nostr-Mail protocol. It adds a new CONSENT armor block type that allows signatories to declare binding consent to a specific agreement document, separate from ordinary signed replies or comments.

Key Changes

  • Version bump: Updated specification from v0.3.0-draft to v0.4.0-draft
  • New CONSENT block type: Added BEGIN NOSTR CONSENT / END NOSTR CONSENT armor delimiters to declare explicit consent to an agreement
    • Contains two fields: agreement (document hash) and signer (pubkey)
    • Bound by the level's SIGNATURE, making consent tamper-evident and non-repudiable
  • Document hash H: Defined as SHA-256(body_1 || recipients_1) computed over the originating message only, fixed for the agreement's lifetime
  • Signature coverage expansion: Updated Section 4.2 to include CONSENT blocks in the signing target: level(L) = decode(body_L) || canonical(recipients_L) || canonical(consent_L)
  • Agreement completion semantics: Clarified that completion requires a verified CONSENT block from each required signatory, not merely a signature
    • Signing without consent (comment) does not count toward completion
    • Originator must include their own CONSENT block if they are a required signatory
  • HTML rendering guidance: Added Section 6.2.6 with detailed styling and layout for rendering agreements, including:
    • Status banner showing "M of N signatories signed"
    • Visual distinction between consent signatures (green) and plain comments (muted)
    • Document hash display with full hash on hover
  • SIGit alignment: Added Section 11.7 documenting the conceptual mapping to SIGit's signing model and noting a planned future Nostr-only transport variant
  • Privacy note: Updated Section 10.9 to clarify that the CONSENT model is transport-independent and could be reused in a gift-wrapped variant

Notable Details

  • CONSENT blocks are not self-signed; they derive their binding from the level's SIGNATURE covering the entire level including the CONSENT block
  • The document hash H deliberately excludes CONSENT blocks to remain fixed and prevent self-reference
  • Backward compatibility: clients predating CONSENT support will simply see ordinary signed replies; agreement-completion logic is unavailable but message decryption and verification work unchanged
  • Ordering is strict: body → RECIPIENTS → CONSENT → nested level → SIGNATURE stack

https://claude.ai/code/session_016YN7L4j4K4nqnfbdu6Lsgm

claude added 2 commits June 13, 2026 12:54
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.
@asherp
asherp merged commit e81bfc7 into staging Jun 13, 2026
1 check 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.

2 participants