@cello-protocol/protocol-types 0.0.43 → 0.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -28,8 +28,4 @@ export { IT_LENGTH_PREFIX_DEFAULT_MAX, CONTENT_PARK_PROTOCOL_ID, CONTENT_PARK_AU
28
28
  export type { SessionLiveness, SessionLivenessQuery, SessionLivenessResponse, } from "./session-liveness.js";
29
29
  export { encodeSessionLivenessQuery, decodeSessionLivenessQuery, encodeSessionLivenessResponse, decodeSessionLivenessResponse, } from "./session-liveness.js";
30
30
  export { MONIKER_RE, validateMoniker } from "./moniker.js";
31
- export { DOCUMENT_UPDATE_DOMAIN, DOCUMENT_UPDATE_ENCODING_V1, DOCUMENT_EPOCH_V1, buildDocumentUpdateTbs, encodeDocumentUpdateEnvelope, decodeDocumentUpdateEnvelope, documentEnvelopeHash, verifyDocumentChainLink, } from "./document-envelope.js";
32
- export type { DocumentUpdateEnvelope } from "./document-envelope.js";
33
- export { DOCUMENT_PROPOSAL_DOMAIN, DOCUMENT_FEATURE_VERSION, ASSURANCE_TIER_V1, TOPOLOGY_V1, buildDocumentProposalTbs, documentIdFromProposal, encodeDocumentProposal, decodeDocumentProposal, seamViolation, documentFeatureIncompatibility, } from "./document-proposal.js";
34
- export type { DocumentProposalEnvelope, DocumentProperties, DocumentConsentState, } from "./document-proposal.js";
35
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -19,6 +19,4 @@ export { IT_LENGTH_PREFIX_DEFAULT_MAX, CONTENT_PARK_PROTOCOL_ID, CONTENT_PARK_AU
19
19
  export { encodeSessionLivenessQuery, decodeSessionLivenessQuery, encodeSessionLivenessResponse, decodeSessionLivenessResponse, } from "./session-liveness.js";
20
20
  // MONIKER-0 — the single home of the agent-name / moniker charset rule (wire contract).
21
21
  export { MONIKER_RE, validateMoniker } from "./moniker.js";
22
- export { DOCUMENT_UPDATE_DOMAIN, DOCUMENT_UPDATE_ENCODING_V1, DOCUMENT_EPOCH_V1, buildDocumentUpdateTbs, encodeDocumentUpdateEnvelope, decodeDocumentUpdateEnvelope, documentEnvelopeHash, verifyDocumentChainLink, } from "./document-envelope.js";
23
- export { DOCUMENT_PROPOSAL_DOMAIN, DOCUMENT_FEATURE_VERSION, ASSURANCE_TIER_V1, TOPOLOGY_V1, buildDocumentProposalTbs, documentIdFromProposal, encodeDocumentProposal, decodeDocumentProposal, seamViolation, documentFeatureIncompatibility, } from "./document-proposal.js";
24
22
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEnD,8FAA8F;AAC9F,wFAAwF;AACxF,2BAA2B;AAC3B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAO3B,+FAA+F;AAC/F,qGAAqG;AACrG,wFAAwF;AACxF,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GACb,MAAM,iBAAiB,CAAC;AAezB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGvE,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AA0BjK,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAmBjC,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AA8DnF,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,eAAe,CAAC;AAuBvB,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAE/B,wFAAwF;AACxF,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EACL,sBAAsB,EACtB,2BAA2B,EAC3B,iBAAiB,EACjB,sBAAsB,EACtB,4BAA4B,EAC5B,4BAA4B,EAC5B,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,EACX,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,aAAa,EACb,8BAA8B,GAC/B,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEnD,8FAA8F;AAC9F,wFAAwF;AACxF,2BAA2B;AAC3B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAO3B,+FAA+F;AAC/F,qGAAqG;AACrG,wFAAwF;AACxF,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GACb,MAAM,iBAAiB,CAAC;AAezB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGvE,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AA0BjK,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAmBjC,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AA8DnF,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,eAAe,CAAC;AAuBvB,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAE/B,wFAAwF;AACxF,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cello-protocol/protocol-types",
3
- "version": "0.0.43",
3
+ "version": "0.0.44",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -1,132 +0,0 @@
1
- /**
2
- * DOD-DOC-ENVELOPE-1 — the document UPDATE envelope (§14).
3
- *
4
- * A distinct wire type from the handshake PROPOSAL envelope (whose hash mints the `document_id`).
5
- * The two share the word, not the shape.
6
- *
7
- * ── WHY THREE OF THESE FIELDS ARE SECURITY FIELDS, NOT METADATA ───────────────────────────────
8
- *
9
- * DOD-DOC-GATE-1 enforces three bindings that no property of a Yjs update's BYTES can establish.
10
- * The gate is only as trustworthy as the signature covering them, which is why all three sit
11
- * inside the TBS rather than beside it:
12
- *
13
- * `document_id` A Yjs update carries no document identity. A well-formed update authored
14
- * against a DIFFERENT document merges into this one silently and converges —
15
- * there is no error, and the result is a splice of two documents.
16
- *
17
- * `update_encoding` v2-encoded bytes are ACCEPTED by the v1 decoder and silently drop all
18
- * content. It cannot be sniffed either: a v2 update begins [0,0,…] and a
19
- * legitimate pure-delete v1 delta begins [0,1,…], so a first-byte heuristic
20
- * would refuse real deletions. The sender must SAY, under signature.
21
- *
22
- * `sender_client_id` Authorship in Yjs IS the clientID, and the gate refuses any client whose
23
- * clock advances without being bound to the sender. §14 forbids persisting or
24
- * deriving a clientID (a shared one splices two authors together with an
25
- * empty pending set — measured in DOD-DOC-FUZZ-1), so an honest peer mints a
26
- * fresh one on every restart. The gate's rule is therefore correct ONLY if
27
- * the binding is LEARNABLE, and this envelope is where it is learned. Outside
28
- * the signature, "learnable" would mean "assertable by anyone on the wire".
29
- *
30
- * `epoch_id` and `doc_prev_hash` are not optional and are not defaulted (§14). An update that does
31
- * not state its epoch cannot be verified unambiguously after a compaction, and the chain link is
32
- * what lets the document log be extracted and verified across sealed sessions.
33
- */
34
- /** Domain tag in slot 0 of the to-be-signed array. */
35
- export declare const DOCUMENT_UPDATE_DOMAIN = "CELLO-DOCUMENT-UPDATE-v1";
36
- /**
37
- * The pinned Yjs update encoding (§16.7-8). Pinned in the protocol types precisely so that two
38
- * supporting clients can never disagree silently — the failure mode of disagreement is an empty
39
- * document, not an error.
40
- */
41
- export declare const DOCUMENT_UPDATE_ENCODING_V1 = "yjs-v1";
42
- /** V1 has exactly one epoch. Compaction (which mints new epochs) is V2. */
43
- export declare const DOCUMENT_EPOCH_V1 = 0;
44
- export interface DocumentUpdateEnvelope {
45
- type: "document_update";
46
- /** Hash of the handshake proposal envelope that minted this document. */
47
- document_id: string;
48
- /** Constant `DOCUMENT_EPOCH_V1` in V1 — carried explicitly, never omitted. */
49
- epoch_id: number;
50
- /**
51
- * The per-sender chain link: the `documentEnvelopeHash` of this sender's previous envelope for
52
- * this document, or `null` for this sender's FIRST envelope. `null` and absent are different
53
- * facts and are treated differently — see `decodeDocumentUpdateEnvelope`.
54
- */
55
- doc_prev_hash: string | null;
56
- sender_agent_id: string;
57
- /** The Yjs clientID this update was authored under. See the header. */
58
- sender_client_id: number;
59
- /** Always `DOCUMENT_UPDATE_ENCODING_V1` in V1. See the header. */
60
- update_encoding: string;
61
- /** The sender's Yjs state vector at publish (§7) — what it had seen when it authored. */
62
- state_vector: Uint8Array;
63
- /** The Yjs update payload. */
64
- update: Uint8Array;
65
- /** Ed25519 (RFC 8032) over `buildDocumentUpdateTbs`. */
66
- signature: Uint8Array;
67
- }
68
- /**
69
- * The canonical to-be-signed preimage: a fixed-order CBOR ARRAY with the domain in slot 0.
70
- *
71
- * An array, not a map, because `encodeCbor` is deliberately NOT deterministic for maps — keys
72
- * follow insertion order and the header is not minimal-length (see `cbor.ts`). Two honest senders
73
- * that built the same envelope in a different field order would produce different signatures over
74
- * it. Arrays are order-fixed and self-delimiting, which also removes the concatenation ambiguity
75
- * that length-framing exists to prevent.
76
- *
77
- * The `signature` is excluded, as it must be — a statement cannot cover its own signature.
78
- *
79
- * `preHash: false` returns the preimage itself rather than its digest; it exists for the hash
80
- * construction below and for tests that need to inspect the structure.
81
- */
82
- export declare function buildDocumentUpdateTbs(env: DocumentUpdateEnvelope, opts?: {
83
- preHash?: boolean;
84
- }): Uint8Array;
85
- /**
86
- * The envelope's identity: SHA-256 over the same preimage that is signed.
87
- *
88
- * Deliberately the SAME preimage, so a chain link commits to exactly the bytes whose signature was
89
- * verified — a link can never point at an envelope other than the one that was authenticated.
90
- *
91
- * It therefore excludes the signature, which is the property the chain needs: a re-signed but
92
- * otherwise identical envelope keeps its hash, so anything already pointing at it (the next
93
- * envelope in the chain, a `0x05` rejection leaf) is not orphaned.
94
- */
95
- export declare function documentEnvelopeHash(env: DocumentUpdateEnvelope): string;
96
- export declare function encodeDocumentUpdateEnvelope(env: DocumentUpdateEnvelope): Uint8Array;
97
- /**
98
- * Decode and VALIDATE. Every refusal names the field, because the caller's next move is to tell an
99
- * operator which peer sent what — an unnamed refusal is a label on the exit point, not a diagnosis.
100
- */
101
- export declare function decodeDocumentUpdateEnvelope(bytes: Uint8Array): DocumentUpdateEnvelope;
102
- /**
103
- * The receive-time chain check: does this envelope link to what we already hold from this sender?
104
- *
105
- * `known` is every envelope hash we hold from this sender for this document, and `head` is their
106
- * most recent. Both, not just the head: replay is SET-based per §16.7-5, and delivery derives
107
- * pending from the log and retries across restarts — so an older envelope arriving again, because
108
- * its ack was lost while a later one landed, is designed behaviour. Comparing against the head
109
- * alone recognised only the newest redelivery and reported every other one as a broken chain.
110
- *
111
- * The set is also what separates the two failures. A predecessor we have never seen is a GAP; a
112
- * predecessor we hold that is not the head is a BRANCH. One reason string for both would hide a
113
- * fork inside a delivery-shaped error.
114
- *
115
- * The refusal reasons are deliberately the SAME STRINGS the daemon's whole-log verifier uses
116
- * (`DocumentStore.verifyChainLinkage`): `document_chain_forked` and `document_chain_broken`. Two
117
- * vocabularies for one fact means a policy-log query or an operator keyed on one silently misses
118
- * the other. The division of labour is real — this checks a single link on arrival, that one walks
119
- * the whole log for reachability — but they are the same two failures.
120
- *
121
- * **LINKAGE ONLY — this is not authenticity.** `documentEnvelopeHash` excludes the signature, so
122
- * `duplicate: true` means the TBS is byte-identical to one we hold, NOT that whoever sent it holds
123
- * the key. A caller must verify the signature before consulting the chain; `duplicate` is the
124
- * value most likely to be read as "already known, ack it and move on".
125
- */
126
- export declare function verifyDocumentChainLink(env: DocumentUpdateEnvelope, sender: {
127
- head: string | null;
128
- known: ReadonlySet<string>;
129
- }): {
130
- duplicate: boolean;
131
- };
132
- //# sourceMappingURL=document-envelope.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"document-envelope.d.ts","sourceRoot":"","sources":["../src/document-envelope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH,sDAAsD;AACtD,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AAEjE;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,WAAW,CAAC;AAEpD,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAKnC,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,iBAAiB,CAAC;IACxB,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,gBAAgB,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,eAAe,EAAE,MAAM,CAAC;IACxB,yFAAyF;IACzF,YAAY,EAAE,UAAU,CAAC;IACzB,8BAA8B;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,wDAAwD;IACxD,SAAS,EAAE,UAAU,CAAC;CACvB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,sBAAsB,EAC3B,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/B,UAAU,CAcZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,sBAAsB,GAAG,MAAM,CAIxE;AAED,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,sBAAsB,GAAG,UAAU,CAapF;AAmCD;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,UAAU,GAAG,sBAAsB,CAsEtF;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,sBAAsB,EAC3B,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAE,GAC1D;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,CAiCxB"}
@@ -1,243 +0,0 @@
1
- /**
2
- * DOD-DOC-ENVELOPE-1 — the document UPDATE envelope (§14).
3
- *
4
- * A distinct wire type from the handshake PROPOSAL envelope (whose hash mints the `document_id`).
5
- * The two share the word, not the shape.
6
- *
7
- * ── WHY THREE OF THESE FIELDS ARE SECURITY FIELDS, NOT METADATA ───────────────────────────────
8
- *
9
- * DOD-DOC-GATE-1 enforces three bindings that no property of a Yjs update's BYTES can establish.
10
- * The gate is only as trustworthy as the signature covering them, which is why all three sit
11
- * inside the TBS rather than beside it:
12
- *
13
- * `document_id` A Yjs update carries no document identity. A well-formed update authored
14
- * against a DIFFERENT document merges into this one silently and converges —
15
- * there is no error, and the result is a splice of two documents.
16
- *
17
- * `update_encoding` v2-encoded bytes are ACCEPTED by the v1 decoder and silently drop all
18
- * content. It cannot be sniffed either: a v2 update begins [0,0,…] and a
19
- * legitimate pure-delete v1 delta begins [0,1,…], so a first-byte heuristic
20
- * would refuse real deletions. The sender must SAY, under signature.
21
- *
22
- * `sender_client_id` Authorship in Yjs IS the clientID, and the gate refuses any client whose
23
- * clock advances without being bound to the sender. §14 forbids persisting or
24
- * deriving a clientID (a shared one splices two authors together with an
25
- * empty pending set — measured in DOD-DOC-FUZZ-1), so an honest peer mints a
26
- * fresh one on every restart. The gate's rule is therefore correct ONLY if
27
- * the binding is LEARNABLE, and this envelope is where it is learned. Outside
28
- * the signature, "learnable" would mean "assertable by anyone on the wire".
29
- *
30
- * `epoch_id` and `doc_prev_hash` are not optional and are not defaulted (§14). An update that does
31
- * not state its epoch cannot be verified unambiguously after a compaction, and the chain link is
32
- * what lets the document log be extracted and verified across sealed sessions.
33
- */
34
- import { createHash } from "node:crypto";
35
- import { encodeCbor, decodeCbor } from "./cbor.js";
36
- /** Domain tag in slot 0 of the to-be-signed array. */
37
- export const DOCUMENT_UPDATE_DOMAIN = "CELLO-DOCUMENT-UPDATE-v1";
38
- /**
39
- * The pinned Yjs update encoding (§16.7-8). Pinned in the protocol types precisely so that two
40
- * supporting clients can never disagree silently — the failure mode of disagreement is an empty
41
- * document, not an error.
42
- */
43
- export const DOCUMENT_UPDATE_ENCODING_V1 = "yjs-v1";
44
- /** V1 has exactly one epoch. Compaction (which mints new epochs) is V2. */
45
- export const DOCUMENT_EPOCH_V1 = 0;
46
- /** A 32-byte hex digest — the shape of `document_id` and of every chain link. */
47
- const HEX32 = /^[0-9a-f]{64}$/;
48
- /**
49
- * The canonical to-be-signed preimage: a fixed-order CBOR ARRAY with the domain in slot 0.
50
- *
51
- * An array, not a map, because `encodeCbor` is deliberately NOT deterministic for maps — keys
52
- * follow insertion order and the header is not minimal-length (see `cbor.ts`). Two honest senders
53
- * that built the same envelope in a different field order would produce different signatures over
54
- * it. Arrays are order-fixed and self-delimiting, which also removes the concatenation ambiguity
55
- * that length-framing exists to prevent.
56
- *
57
- * The `signature` is excluded, as it must be — a statement cannot cover its own signature.
58
- *
59
- * `preHash: false` returns the preimage itself rather than its digest; it exists for the hash
60
- * construction below and for tests that need to inspect the structure.
61
- */
62
- export function buildDocumentUpdateTbs(env, opts = {}) {
63
- const preimage = encodeCbor([
64
- DOCUMENT_UPDATE_DOMAIN,
65
- env.document_id,
66
- env.epoch_id,
67
- env.doc_prev_hash, // null encodes distinctly from any string — genesis is unambiguous
68
- env.sender_agent_id,
69
- env.sender_client_id,
70
- env.update_encoding,
71
- env.state_vector,
72
- env.update,
73
- ]);
74
- if (opts.preHash === false)
75
- return preimage;
76
- return new Uint8Array(createHash("sha256").update(preimage).digest());
77
- }
78
- /**
79
- * The envelope's identity: SHA-256 over the same preimage that is signed.
80
- *
81
- * Deliberately the SAME preimage, so a chain link commits to exactly the bytes whose signature was
82
- * verified — a link can never point at an envelope other than the one that was authenticated.
83
- *
84
- * It therefore excludes the signature, which is the property the chain needs: a re-signed but
85
- * otherwise identical envelope keeps its hash, so anything already pointing at it (the next
86
- * envelope in the chain, a `0x05` rejection leaf) is not orphaned.
87
- */
88
- export function documentEnvelopeHash(env) {
89
- return createHash("sha256")
90
- .update(buildDocumentUpdateTbs(env, { preHash: false }))
91
- .digest("hex");
92
- }
93
- export function encodeDocumentUpdateEnvelope(env) {
94
- return encodeCbor({
95
- type: env.type,
96
- document_id: env.document_id,
97
- epoch_id: env.epoch_id,
98
- doc_prev_hash: env.doc_prev_hash,
99
- sender_agent_id: env.sender_agent_id,
100
- sender_client_id: env.sender_client_id,
101
- update_encoding: env.update_encoding,
102
- state_vector: env.state_vector,
103
- update: env.update,
104
- signature: env.signature,
105
- });
106
- }
107
- function requirePresent(map, field) {
108
- // `in`, not a truthiness or nullish check. ABSENT and `null` are different facts: absent
109
- // doc_prev_hash read as null would turn every gap in a chain into a fresh valid-looking genesis,
110
- // and absent epoch_id read as 0 would make a post-compaction ambiguity silent. A decoder that
111
- // supplies a default for a field the spec calls mandatory is manufacturing the sender's claim.
112
- if (!(field in map)) {
113
- throw new Error(`document_envelope_missing_field: ${field} is mandatory and was not present`);
114
- }
115
- return map[field];
116
- }
117
- function requireBytes(map, field) {
118
- const value = requirePresent(map, field);
119
- if (!(value instanceof Uint8Array)) {
120
- throw new Error(`document_envelope_field_type: ${field} must be a CBOR byte string`);
121
- }
122
- // COPIED, not returned as-is. Measured: cbor-x returns byte strings as VIEWS into the buffer it
123
- // was handed (`decoded.buffer === input.buffer`), so an aliased update mutates when the caller
124
- // reuses or zeroes its read buffer — and a pooled network read buffer is exactly that. Every
125
- // check in this decoder, and every check the gate makes afterwards, would then have been made
126
- // against bytes that are no longer the bytes applied. The copy is also what makes the return
127
- // type honest: a Buffer view and a Uint8Array are not interchangeable to a structural comparison.
128
- return new Uint8Array(value);
129
- }
130
- function requireString(map, field) {
131
- const value = requirePresent(map, field);
132
- if (typeof value !== "string") {
133
- throw new Error(`document_envelope_field_type: ${field} must be a text string`);
134
- }
135
- return value;
136
- }
137
- /**
138
- * Decode and VALIDATE. Every refusal names the field, because the caller's next move is to tell an
139
- * operator which peer sent what — an unnamed refusal is a label on the exit point, not a diagnosis.
140
- */
141
- export function decodeDocumentUpdateEnvelope(bytes) {
142
- const decoded = decodeCbor(bytes);
143
- if (typeof decoded !== "object" || decoded === null || Array.isArray(decoded)) {
144
- throw new Error("document_envelope_malformed: not a CBOR map");
145
- }
146
- const map = decoded;
147
- const type = requireString(map, "type");
148
- if (type !== "document_update") {
149
- throw new Error(`document_envelope_type: expected document_update, got ${type}`);
150
- }
151
- const documentId = requireString(map, "document_id");
152
- if (!HEX32.test(documentId)) {
153
- throw new Error(`document_envelope_document_id: must be a 32-byte lowercase hex digest, got "${documentId}"`);
154
- }
155
- const epochId = requirePresent(map, "epoch_id");
156
- if (typeof epochId !== "number" || !Number.isInteger(epochId)) {
157
- throw new Error(`document_envelope_epoch: must be an integer, got ${String(epochId)}`);
158
- }
159
- if (epochId !== DOCUMENT_EPOCH_V1) {
160
- // V2 introduces compaction and non-zero epochs. Accepting one now would mean applying an
161
- // update whose base state this build cannot reconstruct.
162
- throw new Error(`document_envelope_epoch: this build speaks epoch ${DOCUMENT_EPOCH_V1} only, got ${epochId}`);
163
- }
164
- const prev = requirePresent(map, "doc_prev_hash");
165
- if (prev !== null && (typeof prev !== "string" || !HEX32.test(prev))) {
166
- throw new Error(`document_envelope_prev_hash: must be a 32-byte hex digest or explicit null, got "${String(prev)}"`);
167
- }
168
- const senderAgentId = requireString(map, "sender_agent_id");
169
- if (senderAgentId.length === 0) {
170
- throw new Error("document_envelope_sender: sender_agent_id must not be empty");
171
- }
172
- const clientId = requirePresent(map, "sender_client_id");
173
- if (typeof clientId !== "number" || !Number.isInteger(clientId) || clientId < 0) {
174
- throw new Error(`document_envelope_client_id: must be a non-negative integer, got ${String(clientId)}`);
175
- }
176
- const encoding = requireString(map, "update_encoding");
177
- if (encoding !== DOCUMENT_UPDATE_ENCODING_V1) {
178
- // The one refusal that cannot be replaced by a heuristic. See the header.
179
- throw new Error(`document_envelope_encoding: this build speaks ${DOCUMENT_UPDATE_ENCODING_V1} only, got "${encoding}"`);
180
- }
181
- return {
182
- type: "document_update",
183
- document_id: documentId,
184
- epoch_id: epochId,
185
- doc_prev_hash: prev,
186
- sender_agent_id: senderAgentId,
187
- sender_client_id: clientId,
188
- update_encoding: encoding,
189
- state_vector: requireBytes(map, "state_vector"),
190
- update: requireBytes(map, "update"),
191
- signature: requireBytes(map, "signature"),
192
- };
193
- }
194
- /**
195
- * The receive-time chain check: does this envelope link to what we already hold from this sender?
196
- *
197
- * `known` is every envelope hash we hold from this sender for this document, and `head` is their
198
- * most recent. Both, not just the head: replay is SET-based per §16.7-5, and delivery derives
199
- * pending from the log and retries across restarts — so an older envelope arriving again, because
200
- * its ack was lost while a later one landed, is designed behaviour. Comparing against the head
201
- * alone recognised only the newest redelivery and reported every other one as a broken chain.
202
- *
203
- * The set is also what separates the two failures. A predecessor we have never seen is a GAP; a
204
- * predecessor we hold that is not the head is a BRANCH. One reason string for both would hide a
205
- * fork inside a delivery-shaped error.
206
- *
207
- * The refusal reasons are deliberately the SAME STRINGS the daemon's whole-log verifier uses
208
- * (`DocumentStore.verifyChainLinkage`): `document_chain_forked` and `document_chain_broken`. Two
209
- * vocabularies for one fact means a policy-log query or an operator keyed on one silently misses
210
- * the other. The division of labour is real — this checks a single link on arrival, that one walks
211
- * the whole log for reachability — but they are the same two failures.
212
- *
213
- * **LINKAGE ONLY — this is not authenticity.** `documentEnvelopeHash` excludes the signature, so
214
- * `duplicate: true` means the TBS is byte-identical to one we hold, NOT that whoever sent it holds
215
- * the key. A caller must verify the signature before consulting the chain; `duplicate` is the
216
- * value most likely to be read as "already known, ack it and move on".
217
- */
218
- export function verifyDocumentChainLink(env, sender) {
219
- if (sender.known.has(documentEnvelopeHash(env)))
220
- return { duplicate: true };
221
- if (env.doc_prev_hash === null) {
222
- if (sender.head !== null) {
223
- // Two roots for one sender. DOD-DOC-REJECT-1 measured what this costs: the chain no longer
224
- // verifies, so the document rebuilds until the next daemon restart and is permanently
225
- // unopenable after it. The log is append-only; there is no repair.
226
- throw new Error(`document_chain_forked: ${env.sender_agent_id} sent a genesis envelope for document ` +
227
- `${env.document_id}, but we already hold their chain at ${sender.head}`);
228
- }
229
- return { duplicate: false };
230
- }
231
- if (!sender.known.has(env.doc_prev_hash)) {
232
- throw new Error(`document_chain_broken: ${env.sender_agent_id} chained to ${env.doc_prev_hash} for document ` +
233
- `${env.document_id}, which we have never seen — their last envelope we hold is ` +
234
- `${sender.head ?? "none (no envelope from this sender yet)"}`);
235
- }
236
- if (env.doc_prev_hash !== sender.head) {
237
- throw new Error(`document_chain_forked: ${env.sender_agent_id} chained to ${env.doc_prev_hash} for document ` +
238
- `${env.document_id}, which we hold but which is not their head ${sender.head} — a chain ` +
239
- `branches nowhere`);
240
- }
241
- return { duplicate: false };
242
- }
243
- //# sourceMappingURL=document-envelope.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"document-envelope.js","sourceRoot":"","sources":["../src/document-envelope.ts"],"names":[],"mappings":"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"}
@@ -1,127 +0,0 @@
1
- /**
2
- * DOD-DOC-HANDSHAKE-1 — the document PROPOSAL envelope (§16.3).
3
- *
4
- * A distinct wire type from `document-envelope.ts`'s UPDATE envelope. The two share the word
5
- * "envelope" and nothing else: this one is proposed once, consented to once, and its hash becomes
6
- * the `document_id` that every subsequent update names.
7
- *
8
- * **`document_id` is the hash of this envelope** — globally unique with no minting authority and
9
- * no coordination round. That is the property that makes the whole scheme federated, and it is why
10
- * the proposal must be canonically encodable: two parties that hash it differently are on two
11
- * different documents while believing they are on one.
12
- *
13
- * ── THE SEAM (§3.4, §11.1) ────────────────────────────────────────────────────────────────────
14
- *
15
- * Three properties are DECLARED in V1 but support exactly one value each, and the pattern is
16
- * deliberate — §3.3 chose it for `schema_enforcement` and §16.1 generalized it. Declaring a field
17
- * that only accepts one value looks redundant until you need the second value: the field is
18
- * already on the wire and already signed, so V2 is a validation change rather than a wire break
19
- * that strands every document created before it.
20
- *
21
- * Refused at BOTH ends — at proposal and again at accept. Not belt-and-braces: the proposer and
22
- * the accepter run different builds. A V2 peer proposing `topology: "mesh"` to a V1 peer must be
23
- * refused by the V1 accepter, and a V1 proposer must not be able to emit a value it cannot honour.
24
- * One-sided validation means whichever side is newer silently decides for both.
25
- *
26
- * ── THE FEATURE VERSION (§16.7-8) ─────────────────────────────────────────────────────────────
27
- *
28
- * Alpha owes no backward compatibility, so this is not a negotiation — it is the difference
29
- * between a human answer and a timeout. A peer whose client predates documents does not understand
30
- * the proposal at all, and without a version the symptom is silence: the proposal is never
31
- * answered and the operator sees a hang. `documentFeatureIncompatibility` turns that into "your
32
- * peer's client doesn't support shared documents yet — ask them to upgrade".
33
- */
34
- /** Domain tag in slot 0 of the to-be-signed array. Distinct from the UPDATE envelope's domain. */
35
- export declare const DOCUMENT_PROPOSAL_DOMAIN = "CELLO-DOCUMENT-PROPOSAL-v1";
36
- /**
37
- * The document feature version this build speaks. Bumped when the document wire changes in a way
38
- * a peer must understand; see `documentFeatureIncompatibility` for what a mismatch produces.
39
- */
40
- export declare const DOCUMENT_FEATURE_VERSION = 1;
41
- /** §6 — Tier 1. Tier 2 (attested) is V2; the field exists so V2 is a validation change. */
42
- export declare const ASSURANCE_TIER_V1 = "authenticated";
43
- /** §11 — the pairwise two-document form. Mesh is deferred (§11.1). */
44
- export declare const TOPOLOGY_V1 = "hub-and-spoke";
45
- export type DocumentConsentState = "pending" | "accepted" | "refused";
46
- /**
47
- * The properties agreed at handshake (§3.4). **Immutable after accept** — a property change is an
48
- * epoch event and therefore V2 (§16.3), so no mutate call exists in V1. That is not an omission to
49
- * fill in later: mutating a property after acceptance would silently change the rules the other
50
- * party consented to, which is the one thing the handshake exists to prevent.
51
- */
52
- export interface DocumentProperties {
53
- /** Only `authenticated` in V1. */
54
- assurance_tier: string;
55
- /** Only `false` in V1 — the schema-as-first-update path (§3.3) is V2. */
56
- schema_enforcement: boolean;
57
- /** Only `hub-and-spoke` in V1. */
58
- topology: string;
59
- /** Receiver-local append-only enforcement (§16.7-1). Freely settable — not a seam field. */
60
- append_only: boolean;
61
- }
62
- export interface DocumentProposalEnvelope {
63
- type: "document_proposal";
64
- /** Which build proposed this. A peer that cannot read it answers with a human-readable refusal. */
65
- feature_version: number;
66
- proposer_agent_id: string;
67
- peer_agent_id: string;
68
- /** Free-form label chosen by the proposer, e.g. "markdown". Not a seam field. */
69
- document_type: string;
70
- properties: DocumentProperties;
71
- /**
72
- * The epoch-zero template (§16.3 step 1), or null. A Yjs update in the pinned encoding, so both
73
- * sides mint byte-identical starting state rather than each building their own from a template
74
- * string — two "identical" documents built independently do not converge.
75
- */
76
- starting_content: Uint8Array | null;
77
- /** Distinguishes two otherwise identical proposals, so each gets its own document_id. */
78
- nonce: Uint8Array;
79
- proposed_at_ms: number;
80
- /** Ed25519 (RFC 8032) over `buildDocumentProposalTbs`. */
81
- signature: Uint8Array;
82
- }
83
- /**
84
- * The canonical to-be-signed preimage: a fixed-order CBOR ARRAY with the domain in slot 0.
85
- *
86
- * The properties are flattened into their own slots rather than nested as a map. `encodeCbor` is
87
- * not deterministic for maps — keys follow insertion order — so a nested `properties` object would
88
- * make the signature depend on the order the proposer happened to build it in, and two honest
89
- * builds of the same proposal would produce different `document_id`s. For this envelope that is
90
- * worse than a bad signature: the id IS the hash, so the two parties would be on two documents.
91
- */
92
- export declare function buildDocumentProposalTbs(env: DocumentProposalEnvelope, opts?: {
93
- preHash?: boolean;
94
- }): Uint8Array;
95
- /**
96
- * `document_id` = the hash of the proposal envelope (§16.3).
97
- *
98
- * Over the same preimage that is signed, and therefore NOT over the signature — so the id a party
99
- * computes is the id of the thing whose signature it verified, and re-signing cannot change the
100
- * identity of an already-accepted document.
101
- */
102
- export declare function documentIdFromProposal(env: DocumentProposalEnvelope): string;
103
- /**
104
- * Refuse any seam value this build cannot honour, at proposal AND at accept.
105
- *
106
- * Returns the reason, or null when the properties are acceptable. A REASON rather than a boolean
107
- * because the operator on the refusing side has to be able to tell "your peer asked for mesh
108
- * topology, which this version does not support" from a generic refusal — a handshake that fails
109
- * without saying which property failed is indistinguishable from the peer being unreachable.
110
- */
111
- export declare function seamViolation(props: DocumentProperties): string | null;
112
- /**
113
- * A human answer for a version mismatch, or null when the peer is compatible.
114
- *
115
- * Deliberately phrased for the operator rather than for a log: the alternative to this string is a
116
- * proposal that is never answered, which surfaces as a hang and gets diagnosed as a network fault.
117
- */
118
- export declare function documentFeatureIncompatibility(peerFeatureVersion: number | null): string | null;
119
- export declare function encodeDocumentProposal(env: DocumentProposalEnvelope): Uint8Array;
120
- /**
121
- * Decode and validate. Does NOT check the seam — `seamViolation` is called separately at both the
122
- * proposal and the accept step, because a decoder that refused seam values would make a
123
- * V2 proposal undecodable and therefore unanswerable, which is exactly the silent hang the feature
124
- * version exists to replace.
125
- */
126
- export declare function decodeDocumentProposal(input: Uint8Array): DocumentProposalEnvelope;
127
- //# sourceMappingURL=document-proposal.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"document-proposal.d.ts","sourceRoot":"","sources":["../src/document-proposal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH,kGAAkG;AAClG,eAAO,MAAM,wBAAwB,+BAA+B,CAAC;AAErE;;;GAGG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,2FAA2F;AAC3F,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AACjD,sEAAsE;AACtE,eAAO,MAAM,WAAW,kBAAkB,CAAC;AAE3C,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,kCAAkC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,mGAAmG;IACnG,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,kBAAkB,CAAC;IAC/B;;;;OAIG;IACH,gBAAgB,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC,yFAAyF;IACzF,KAAK,EAAE,UAAU,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,SAAS,EAAE,UAAU,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,wBAAwB,EAC7B,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/B,UAAU,CAiBZ;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,wBAAwB,GAAG,MAAM,CAI5E;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAoBtE;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAoB/F;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,wBAAwB,GAAG,UAAU,CAkBhF;AA6BD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,UAAU,GAAG,wBAAwB,CA8DlF"}
@@ -1,233 +0,0 @@
1
- /**
2
- * DOD-DOC-HANDSHAKE-1 — the document PROPOSAL envelope (§16.3).
3
- *
4
- * A distinct wire type from `document-envelope.ts`'s UPDATE envelope. The two share the word
5
- * "envelope" and nothing else: this one is proposed once, consented to once, and its hash becomes
6
- * the `document_id` that every subsequent update names.
7
- *
8
- * **`document_id` is the hash of this envelope** — globally unique with no minting authority and
9
- * no coordination round. That is the property that makes the whole scheme federated, and it is why
10
- * the proposal must be canonically encodable: two parties that hash it differently are on two
11
- * different documents while believing they are on one.
12
- *
13
- * ── THE SEAM (§3.4, §11.1) ────────────────────────────────────────────────────────────────────
14
- *
15
- * Three properties are DECLARED in V1 but support exactly one value each, and the pattern is
16
- * deliberate — §3.3 chose it for `schema_enforcement` and §16.1 generalized it. Declaring a field
17
- * that only accepts one value looks redundant until you need the second value: the field is
18
- * already on the wire and already signed, so V2 is a validation change rather than a wire break
19
- * that strands every document created before it.
20
- *
21
- * Refused at BOTH ends — at proposal and again at accept. Not belt-and-braces: the proposer and
22
- * the accepter run different builds. A V2 peer proposing `topology: "mesh"` to a V1 peer must be
23
- * refused by the V1 accepter, and a V1 proposer must not be able to emit a value it cannot honour.
24
- * One-sided validation means whichever side is newer silently decides for both.
25
- *
26
- * ── THE FEATURE VERSION (§16.7-8) ─────────────────────────────────────────────────────────────
27
- *
28
- * Alpha owes no backward compatibility, so this is not a negotiation — it is the difference
29
- * between a human answer and a timeout. A peer whose client predates documents does not understand
30
- * the proposal at all, and without a version the symptom is silence: the proposal is never
31
- * answered and the operator sees a hang. `documentFeatureIncompatibility` turns that into "your
32
- * peer's client doesn't support shared documents yet — ask them to upgrade".
33
- */
34
- import { createHash } from "node:crypto";
35
- import { encodeCbor, decodeCbor } from "./cbor.js";
36
- /** Domain tag in slot 0 of the to-be-signed array. Distinct from the UPDATE envelope's domain. */
37
- export const DOCUMENT_PROPOSAL_DOMAIN = "CELLO-DOCUMENT-PROPOSAL-v1";
38
- /**
39
- * The document feature version this build speaks. Bumped when the document wire changes in a way
40
- * a peer must understand; see `documentFeatureIncompatibility` for what a mismatch produces.
41
- */
42
- export const DOCUMENT_FEATURE_VERSION = 1;
43
- /** §6 — Tier 1. Tier 2 (attested) is V2; the field exists so V2 is a validation change. */
44
- export const ASSURANCE_TIER_V1 = "authenticated";
45
- /** §11 — the pairwise two-document form. Mesh is deferred (§11.1). */
46
- export const TOPOLOGY_V1 = "hub-and-spoke";
47
- /**
48
- * The canonical to-be-signed preimage: a fixed-order CBOR ARRAY with the domain in slot 0.
49
- *
50
- * The properties are flattened into their own slots rather than nested as a map. `encodeCbor` is
51
- * not deterministic for maps — keys follow insertion order — so a nested `properties` object would
52
- * make the signature depend on the order the proposer happened to build it in, and two honest
53
- * builds of the same proposal would produce different `document_id`s. For this envelope that is
54
- * worse than a bad signature: the id IS the hash, so the two parties would be on two documents.
55
- */
56
- export function buildDocumentProposalTbs(env, opts = {}) {
57
- const preimage = encodeCbor([
58
- DOCUMENT_PROPOSAL_DOMAIN,
59
- env.feature_version,
60
- env.proposer_agent_id,
61
- env.peer_agent_id,
62
- env.document_type,
63
- env.properties.assurance_tier,
64
- env.properties.schema_enforcement,
65
- env.properties.topology,
66
- env.properties.append_only,
67
- env.starting_content,
68
- env.nonce,
69
- env.proposed_at_ms,
70
- ]);
71
- if (opts.preHash === false)
72
- return preimage;
73
- return new Uint8Array(createHash("sha256").update(preimage).digest());
74
- }
75
- /**
76
- * `document_id` = the hash of the proposal envelope (§16.3).
77
- *
78
- * Over the same preimage that is signed, and therefore NOT over the signature — so the id a party
79
- * computes is the id of the thing whose signature it verified, and re-signing cannot change the
80
- * identity of an already-accepted document.
81
- */
82
- export function documentIdFromProposal(env) {
83
- return createHash("sha256")
84
- .update(buildDocumentProposalTbs(env, { preHash: false }))
85
- .digest("hex");
86
- }
87
- /**
88
- * Refuse any seam value this build cannot honour, at proposal AND at accept.
89
- *
90
- * Returns the reason, or null when the properties are acceptable. A REASON rather than a boolean
91
- * because the operator on the refusing side has to be able to tell "your peer asked for mesh
92
- * topology, which this version does not support" from a generic refusal — a handshake that fails
93
- * without saying which property failed is indistinguishable from the peer being unreachable.
94
- */
95
- export function seamViolation(props) {
96
- if (props.assurance_tier !== ASSURANCE_TIER_V1) {
97
- return (`document_seam_assurance_tier: this version supports "${ASSURANCE_TIER_V1}" only, and the ` +
98
- `proposal asks for "${props.assurance_tier}" — attested documents (§6 Tier 2) are not yet built`);
99
- }
100
- if (props.schema_enforcement !== false) {
101
- return ("document_seam_schema_enforcement: this version supports schema_enforcement: false only — " +
102
- "schema-as-first-update validation (§3.3) is not yet built");
103
- }
104
- if (props.topology !== TOPOLOGY_V1) {
105
- return (`document_seam_topology: this version supports "${TOPOLOGY_V1}" only, and the proposal asks ` +
106
- `for "${props.topology}" — mesh documents (§11.1) are not yet built`);
107
- }
108
- return null;
109
- }
110
- /**
111
- * A human answer for a version mismatch, or null when the peer is compatible.
112
- *
113
- * Deliberately phrased for the operator rather than for a log: the alternative to this string is a
114
- * proposal that is never answered, which surfaces as a hang and gets diagnosed as a network fault.
115
- */
116
- export function documentFeatureIncompatibility(peerFeatureVersion) {
117
- if (peerFeatureVersion === null) {
118
- return ("your peer's client doesn't support shared documents yet — ask them to upgrade to a version " +
119
- "that speaks the document protocol");
120
- }
121
- if (peerFeatureVersion > DOCUMENT_FEATURE_VERSION) {
122
- return (`your peer's client speaks document feature version ${peerFeatureVersion} and this one ` +
123
- `speaks ${DOCUMENT_FEATURE_VERSION} — upgrade this client to collaborate with them`);
124
- }
125
- if (peerFeatureVersion < DOCUMENT_FEATURE_VERSION) {
126
- return (`your peer's client speaks document feature version ${peerFeatureVersion} and this one ` +
127
- `speaks ${DOCUMENT_FEATURE_VERSION} — ask them to upgrade`);
128
- }
129
- return null;
130
- }
131
- export function encodeDocumentProposal(env) {
132
- return encodeCbor({
133
- type: env.type,
134
- feature_version: env.feature_version,
135
- proposer_agent_id: env.proposer_agent_id,
136
- peer_agent_id: env.peer_agent_id,
137
- document_type: env.document_type,
138
- properties: {
139
- assurance_tier: env.properties.assurance_tier,
140
- schema_enforcement: env.properties.schema_enforcement,
141
- topology: env.properties.topology,
142
- append_only: env.properties.append_only,
143
- },
144
- starting_content: env.starting_content,
145
- nonce: env.nonce,
146
- proposed_at_ms: env.proposed_at_ms,
147
- signature: env.signature,
148
- });
149
- }
150
- function present(map, field) {
151
- // `in`, not a nullish check — see document-envelope.ts. A defaulted seam field is a property the
152
- // peer never actually declared, admitted under this build's own preference.
153
- if (!(field in map)) {
154
- throw new Error(`document_proposal_missing_field: ${field} is mandatory and was not present`);
155
- }
156
- return map[field];
157
- }
158
- function str(map, field) {
159
- const v = present(map, field);
160
- if (typeof v !== "string" || v.length === 0) {
161
- throw new Error(`document_proposal_field_type: ${field} must be a non-empty text string`);
162
- }
163
- return v;
164
- }
165
- function bytes(map, field) {
166
- const v = present(map, field);
167
- if (!(v instanceof Uint8Array)) {
168
- throw new Error(`document_proposal_field_type: ${field} must be a CBOR byte string`);
169
- }
170
- // COPIED — cbor-x returns byte strings as views into the decoded buffer, so a caller reusing a
171
- // pooled read buffer would mutate the starting content after it was validated and hashed.
172
- return new Uint8Array(v);
173
- }
174
- /**
175
- * Decode and validate. Does NOT check the seam — `seamViolation` is called separately at both the
176
- * proposal and the accept step, because a decoder that refused seam values would make a
177
- * V2 proposal undecodable and therefore unanswerable, which is exactly the silent hang the feature
178
- * version exists to replace.
179
- */
180
- export function decodeDocumentProposal(input) {
181
- const decoded = decodeCbor(input);
182
- if (typeof decoded !== "object" || decoded === null || Array.isArray(decoded)) {
183
- throw new Error("document_proposal_malformed: not a CBOR map");
184
- }
185
- const map = decoded;
186
- const type = str(map, "type");
187
- if (type !== "document_proposal") {
188
- throw new Error(`document_proposal_type: expected document_proposal, got ${type}`);
189
- }
190
- const featureVersion = present(map, "feature_version");
191
- if (typeof featureVersion !== "number" || !Number.isInteger(featureVersion) || featureVersion < 1) {
192
- throw new Error(`document_proposal_feature_version: must be a positive integer, got ${String(featureVersion)}`);
193
- }
194
- const rawProps = present(map, "properties");
195
- if (typeof rawProps !== "object" || rawProps === null || Array.isArray(rawProps)) {
196
- throw new Error("document_proposal_properties: must be a CBOR map");
197
- }
198
- const p = rawProps;
199
- const schemaEnforcement = present(p, "schema_enforcement");
200
- if (typeof schemaEnforcement !== "boolean") {
201
- throw new Error("document_proposal_field_type: properties.schema_enforcement must be a boolean");
202
- }
203
- const appendOnly = present(p, "append_only");
204
- if (typeof appendOnly !== "boolean") {
205
- throw new Error("document_proposal_field_type: properties.append_only must be a boolean");
206
- }
207
- const startingContent = present(map, "starting_content");
208
- if (startingContent !== null && !(startingContent instanceof Uint8Array)) {
209
- throw new Error("document_proposal_field_type: starting_content must be a CBOR byte string or explicit null");
210
- }
211
- const proposedAt = present(map, "proposed_at_ms");
212
- if (typeof proposedAt !== "number" || !Number.isInteger(proposedAt)) {
213
- throw new Error(`document_proposal_field_type: proposed_at_ms must be an integer`);
214
- }
215
- return {
216
- type: "document_proposal",
217
- feature_version: featureVersion,
218
- proposer_agent_id: str(map, "proposer_agent_id"),
219
- peer_agent_id: str(map, "peer_agent_id"),
220
- document_type: str(map, "document_type"),
221
- properties: {
222
- assurance_tier: str(p, "assurance_tier"),
223
- schema_enforcement: schemaEnforcement,
224
- topology: str(p, "topology"),
225
- append_only: appendOnly,
226
- },
227
- starting_content: startingContent === null ? null : new Uint8Array(startingContent),
228
- nonce: bytes(map, "nonce"),
229
- proposed_at_ms: proposedAt,
230
- signature: bytes(map, "signature"),
231
- };
232
- }
233
- //# sourceMappingURL=document-proposal.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"document-proposal.js","sourceRoot":"","sources":["../src/document-proposal.ts"],"names":[],"mappings":"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"}