What
Wrap L2PS messages in the DACS ChannelMessage envelope (DACS-3 §8.3.3) with monotonic per-channel sequencing, CCI-key signing, and transcript export. Satisfies CH-3 (authenticity) and CH-6 (per-session channelId uniqueness).
Envelope (verbatim from §8.3.3)
type ChannelMessage = {
channelId: string
sequence: number // monotonic per channel, starts at 1
sender: ClaimReference // author's CCI primary claim (from WI-1)
sentAt: number // unix ms
type: "offer" | "counter" | "accept" | "reject"
| "sealed-envelope-commit" | "sealed-envelope-reveal" | "abort"
body: unknown
refs?: { repliesTo?: number }
signature: ChannelMessageSignature
}
Signing rule (exact)
canonical_form := RFC 8785 JCS of envelope with `signature` omitted
envelope_hash := sha256(canonical_form) // hex
signed_bytes := "dacs-channelmsg:v1:" || envelope_hash
Signed with the sender's Demos Ed25519 key (via signWithPrimaryClaim from WI-0). Transport-level fields may wrap the envelope but MUST NOT change the signed bytes.
Three things to implement
- Sequence numbering — assign + enforce monotonic per-channel sequence starting at 1. Reject out-of-order / duplicate sequences. Combined with CH-6 this is the anti-replay defence (§8.12).
- channelId uniqueness (CH-6) — substrate derives a per-session-unique
channelId. Reject a session that reuses a prior channelId.
- Sign/verify + transcript export:
sign(envelope, demos) -> ChannelMessage
verify(msg) -> bool — verifies signature against the sender's bound CCI key (via WI-1 resolveMember), checks sender ∈ members, checks sequence monotonicity
exportTranscript(channelId, messages, members) -> ChannelTranscript:
type ChannelTranscript = {
transcriptVersion: "1"
channelId: string
members: ClaimReference[]
messages: ChannelMessage[] // in sequence order
generatedAt: number
signatures: TranscriptSignature[]
}
Acceptance
Dependencies
- Blocked by WI-1 (
resolveMember, binding registry).
- Consumes WI-0 helpers for signing + verification.
Source
Brief §2 WI-2 + DACS-3 §8.3.3, §8.12.
What
Wrap L2PS messages in the DACS
ChannelMessageenvelope (DACS-3 §8.3.3) with monotonic per-channel sequencing, CCI-key signing, and transcript export. Satisfies CH-3 (authenticity) and CH-6 (per-session channelId uniqueness).Envelope (verbatim from §8.3.3)
Signing rule (exact)
Signed with the sender's Demos Ed25519 key (via
signWithPrimaryClaimfrom WI-0). Transport-level fields may wrap the envelope but MUST NOT change the signed bytes.Three things to implement
channelId. Reject a session that reuses a priorchannelId.sign(envelope, demos) -> ChannelMessageverify(msg) -> bool— verifies signature against the sender's bound CCI key (via WI-1resolveMember), checkssender ∈ members, checks sequence monotonicityexportTranscript(channelId, messages, members) -> ChannelTranscript:Acceptance
verify()passes.channelIdis rejected (CH-6).sequenceis rejected.sequenceis rejected.sender(no WI-1 binding) is rejected.Dependencies
resolveMember, binding registry).Source
Brief §2 WI-2 + DACS-3 §8.3.3, §8.12.