@cello-protocol/protocol-types 0.0.53 → 0.0.55

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.
Files changed (41) hide show
  1. package/dist/document-amendment.d.ts +133 -0
  2. package/dist/document-amendment.d.ts.map +1 -0
  3. package/dist/document-amendment.js +229 -0
  4. package/dist/document-amendment.js.map +1 -0
  5. package/dist/document-derive.d.ts +96 -0
  6. package/dist/document-derive.d.ts.map +1 -0
  7. package/dist/document-derive.js +605 -0
  8. package/dist/document-derive.js.map +1 -0
  9. package/dist/document-envelope.d.ts +18 -8
  10. package/dist/document-envelope.d.ts.map +1 -1
  11. package/dist/document-envelope.js +35 -19
  12. package/dist/document-envelope.js.map +1 -1
  13. package/dist/document-governance.d.ts +40 -0
  14. package/dist/document-governance.d.ts.map +1 -0
  15. package/dist/document-governance.js +145 -0
  16. package/dist/document-governance.js.map +1 -0
  17. package/dist/document-multisig.d.ts +81 -0
  18. package/dist/document-multisig.d.ts.map +1 -0
  19. package/dist/document-multisig.js +185 -0
  20. package/dist/document-multisig.js.map +1 -0
  21. package/dist/document-proposal.d.ts +29 -14
  22. package/dist/document-proposal.d.ts.map +1 -1
  23. package/dist/document-proposal.js +101 -7
  24. package/dist/document-proposal.js.map +1 -1
  25. package/dist/document-reconcile.d.ts +100 -0
  26. package/dist/document-reconcile.d.ts.map +1 -0
  27. package/dist/document-reconcile.js +197 -0
  28. package/dist/document-reconcile.js.map +1 -0
  29. package/dist/index.d.ts +14 -6
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +9 -4
  32. package/dist/index.js.map +1 -1
  33. package/package.json +2 -2
  34. package/dist/document-ack.d.ts +0 -111
  35. package/dist/document-ack.d.ts.map +0 -1
  36. package/dist/document-ack.js +0 -228
  37. package/dist/document-ack.js.map +0 -1
  38. package/dist/document-control.d.ts +0 -74
  39. package/dist/document-control.d.ts.map +0 -1
  40. package/dist/document-control.js +0 -174
  41. package/dist/document-control.js.map +0 -1
@@ -27,26 +27,29 @@
27
27
  * the binding is LEARNABLE, and this envelope is where it is learned. Outside
28
28
  * the signature, "learnable" would mean "assertable by anyone on the wire".
29
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.
30
+ * `doc_prev_hash` is not optional and is not defaulted (§14): the chain link is what lets the
31
+ * document log be extracted and verified across sealed sessions, and a decoder that read absence
32
+ * as null would turn every gap into a valid-looking genesis. `governance_parents` is likewise
33
+ * mandatory — it is content's only causal link to the governance that makes it admissible.
33
34
  */
34
35
  /** Domain tag in slot 0 of the to-be-signed array. */
35
- export declare const DOCUMENT_UPDATE_DOMAIN = "CELLO-DOCUMENT-UPDATE-v1";
36
+ /**
37
+ * v2 (SYNC-G1, journal Entry 58): the envelope gains `governance_parents` — the author's
38
+ * governance frontier at authoring — inside the signed preimage. It is the content's causal
39
+ * link to the governance that made it admissible; the per-envelope epoch stamp it replaces is
40
+ * deleted by the same phase. No compatibility owed: nothing was published between bumps.
41
+ */
42
+ export declare const DOCUMENT_UPDATE_DOMAIN = "CELLO-DOCUMENT-UPDATE-v3";
36
43
  /**
37
44
  * The pinned Yjs update encoding (§16.7-8). Pinned in the protocol types precisely so that two
38
45
  * supporting clients can never disagree silently — the failure mode of disagreement is an empty
39
46
  * document, not an error.
40
47
  */
41
48
  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
49
  export interface DocumentUpdateEnvelope {
45
50
  type: "document_update";
46
51
  /** Hash of the handshake proposal envelope that minted this document. */
47
52
  document_id: string;
48
- /** Constant `DOCUMENT_EPOCH_V1` in V1 — carried explicitly, never omitted. */
49
- epoch_id: number;
50
53
  /**
51
54
  * The per-sender chain link: the `documentEnvelopeHash` of this sender's previous envelope for
52
55
  * this document, or `null` for this sender's FIRST envelope. `null` and absent are different
@@ -62,6 +65,13 @@ export interface DocumentUpdateEnvelope {
62
65
  state_vector: Uint8Array;
63
66
  /** The Yjs update payload. */
64
67
  update: Uint8Array;
68
+ /**
69
+ * SYNC-G1 — the author's GOVERNANCE frontier when authoring: governance entry hashes,
70
+ * canonical (strictly ascending, capped). This is what R20/R30 rule on for content: was the
71
+ * author a participant at THESE ancestors, and is no ending among them. Empty = authored at
72
+ * genesis, before any governance entry existed.
73
+ */
74
+ governance_parents: string[];
65
75
  /** Ed25519 (RFC 8032) over `buildDocumentUpdateTbs`. */
66
76
  signature: Uint8Array;
67
77
  }
@@ -1 +1 @@
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
+ {"version":3,"file":"document-envelope.d.ts","sourceRoot":"","sources":["../src/document-envelope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAKH,sDAAsD;AACtD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AAEjE;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,WAAW,CAAC;AAOpD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,iBAAiB,CAAC;IACxB,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;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;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,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,CAkFtF;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"}
@@ -27,14 +27,21 @@
27
27
  * the binding is LEARNABLE, and this envelope is where it is learned. Outside
28
28
  * the signature, "learnable" would mean "assertable by anyone on the wire".
29
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.
30
+ * `doc_prev_hash` is not optional and is not defaulted (§14): the chain link is what lets the
31
+ * document log be extracted and verified across sealed sessions, and a decoder that read absence
32
+ * as null would turn every gap into a valid-looking genesis. `governance_parents` is likewise
33
+ * mandatory — it is content's only causal link to the governance that makes it admissible.
33
34
  */
34
35
  import { createHash } from "node:crypto";
35
36
  import { encodeCbor, decodeCbor } from "./cbor.js";
36
37
  /** Domain tag in slot 0 of the to-be-signed array. */
37
- export const DOCUMENT_UPDATE_DOMAIN = "CELLO-DOCUMENT-UPDATE-v1";
38
+ /**
39
+ * v2 (SYNC-G1, journal Entry 58): the envelope gains `governance_parents` — the author's
40
+ * governance frontier at authoring — inside the signed preimage. It is the content's causal
41
+ * link to the governance that made it admissible; the per-envelope epoch stamp it replaces is
42
+ * deleted by the same phase. No compatibility owed: nothing was published between bumps.
43
+ */
44
+ export const DOCUMENT_UPDATE_DOMAIN = "CELLO-DOCUMENT-UPDATE-v3";
38
45
  /**
39
46
  * The pinned Yjs update encoding (§16.7-8). Pinned in the protocol types precisely so that two
40
47
  * supporting clients can never disagree silently — the failure mode of disagreement is an empty
@@ -42,7 +49,6 @@ export const DOCUMENT_UPDATE_DOMAIN = "CELLO-DOCUMENT-UPDATE-v1";
42
49
  */
43
50
  export const DOCUMENT_UPDATE_ENCODING_V1 = "yjs-v1";
44
51
  /** V1 has exactly one epoch. Compaction (which mints new epochs) is V2. */
45
- export const DOCUMENT_EPOCH_V1 = 0;
46
52
  /** A 32-byte hex digest — the shape of `document_id` and of every chain link. */
47
53
  const HEX32 = /^[0-9a-f]{64}$/;
48
54
  /**
@@ -63,13 +69,13 @@ export function buildDocumentUpdateTbs(env, opts = {}) {
63
69
  const preimage = encodeCbor([
64
70
  DOCUMENT_UPDATE_DOMAIN,
65
71
  env.document_id,
66
- env.epoch_id,
67
72
  env.doc_prev_hash, // null encodes distinctly from any string — genesis is unambiguous
68
73
  env.sender_agent_id,
69
74
  env.sender_client_id,
70
75
  env.update_encoding,
71
76
  env.state_vector,
72
77
  env.update,
78
+ [...env.governance_parents],
73
79
  ]);
74
80
  if (opts.preHash === false)
75
81
  return preimage;
@@ -94,20 +100,20 @@ export function encodeDocumentUpdateEnvelope(env) {
94
100
  return encodeCbor({
95
101
  type: env.type,
96
102
  document_id: env.document_id,
97
- epoch_id: env.epoch_id,
98
103
  doc_prev_hash: env.doc_prev_hash,
99
104
  sender_agent_id: env.sender_agent_id,
100
105
  sender_client_id: env.sender_client_id,
101
106
  update_encoding: env.update_encoding,
102
107
  state_vector: env.state_vector,
103
108
  update: env.update,
109
+ governance_parents: [...env.governance_parents],
104
110
  signature: env.signature,
105
111
  });
106
112
  }
107
113
  function requirePresent(map, field) {
108
114
  // `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
115
+ // doc_prev_hash read as null would turn every gap in a chain into a fresh valid-looking genesis.
116
+ // A decoder that
111
117
  // supplies a default for a field the spec calls mandatory is manufacturing the sender's claim.
112
118
  if (!(field in map)) {
113
119
  throw new Error(`document_envelope_missing_field: ${field} is mandatory and was not present`);
@@ -152,15 +158,6 @@ export function decodeDocumentUpdateEnvelope(bytes) {
152
158
  if (!HEX32.test(documentId)) {
153
159
  throw new Error(`document_envelope_document_id: must be a 32-byte lowercase hex digest, got "${documentId}"`);
154
160
  }
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
161
  const prev = requirePresent(map, "doc_prev_hash");
165
162
  if (prev !== null && (typeof prev !== "string" || !HEX32.test(prev))) {
166
163
  throw new Error(`document_envelope_prev_hash: must be a 32-byte hex digest or explicit null, got "${String(prev)}"`);
@@ -178,16 +175,35 @@ export function decodeDocumentUpdateEnvelope(bytes) {
178
175
  // The one refusal that cannot be replaced by a heuristic. See the header.
179
176
  throw new Error(`document_envelope_encoding: this build speaks ${DOCUMENT_UPDATE_ENCODING_V1} only, got "${encoding}"`);
180
177
  }
178
+ const rawParents = requirePresent(map, "governance_parents");
179
+ if (!Array.isArray(rawParents)) {
180
+ throw new Error("document_envelope_governance_parents: must be an array of entry hashes");
181
+ }
182
+ if (rawParents.length > 64) {
183
+ throw new Error(`document_envelope_governance_parents_cap: ${rawParents.length} exceeds the ceiling of 64`);
184
+ }
185
+ const governanceParents = rawParents.map((h) => {
186
+ if (typeof h !== "string" || !HEX32.test(h)) {
187
+ throw new Error("document_envelope_governance_parents: must hold 64-hex entry hashes");
188
+ }
189
+ return h;
190
+ });
191
+ for (let i = 1; i < governanceParents.length; i++) {
192
+ if (governanceParents[i] <= governanceParents[i - 1]) {
193
+ throw new Error("document_envelope_governance_parents_canonical: strictly ascending, no duplicates — " +
194
+ "one envelope, one identity");
195
+ }
196
+ }
181
197
  return {
182
198
  type: "document_update",
183
199
  document_id: documentId,
184
- epoch_id: epochId,
185
200
  doc_prev_hash: prev,
186
201
  sender_agent_id: senderAgentId,
187
202
  sender_client_id: clientId,
188
203
  update_encoding: encoding,
189
204
  state_vector: requireBytes(map, "state_vector"),
190
205
  update: requireBytes(map, "update"),
206
+ governance_parents: governanceParents,
191
207
  signature: requireBytes(map, "signature"),
192
208
  };
193
209
  }
@@ -1 +1 @@
1
- {"version":3,"file":"document-envelope.js","sourceRoot":"","sources":["../src/document-envelope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"document-envelope.js","sourceRoot":"","sources":["../src/document-envelope.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * DOD-MP-GOVERN-1 — the signature-requirement policy. Rulings D2/D3 (2026-08-11), as code.
3
+ *
4
+ * The policy VALIDATES the collection's claimed required set; it does not mint one. "Any single
5
+ * admin may act" has no single answer to mint — {a} and {b} are both acceptable claims — so the
6
+ * seam is a verdict on what the collection claims, and the multisig layer then demands every
7
+ * claimed signature actually verify.
8
+ *
9
+ * The rules:
10
+ * - **Single-admin kinds** — `add_holder`, `promote_admin`, `remove_holder` (of a non-admin),
11
+ * `change_property`: the claim is EXACTLY ONE current admin. A wider claim is refused, not
12
+ * welcomed as extra-safe: every claimed signer must sign for the collection to complete, so an
13
+ * inflated claim lets one absent co-signer veto an action the rule gives to any single admin —
14
+ * a governance change smuggled through the claim.
15
+ * - **Voluntary leave** — `remove_holder` claimed by exactly the subject themselves is always
16
+ * acceptable, admin or not. Leaving is theirs (D3).
17
+ * - **`remove_admin`** — the claim is exactly ALL OTHER admins; the subject neither required nor
18
+ * counted. With exactly two admins NEITHER CAN REMOVE THE OTHER — by design, and the refusal
19
+ * names the recourse (D3: stop working in it, duplicate it, start fresh without them).
20
+ * - **The holder door is not a bypass** — `remove_holder` of a CURRENT ADMIN (other than
21
+ * voluntary leave) is refused: holder removal drops admin status too, so allowing it under the
22
+ * single-admin rule would expel an admin on one signature, evading `remove_admin` and the
23
+ * deadlock in one move. Demote first, under remove_admin's rule.
24
+ *
25
+ * Kind/subject semantics (does the subject hold? is it already an admin? last-admin protection)
26
+ * are the causal fold's job (`deriveDocumentState`) and run BEFORE this policy is consulted — it may assume a
27
+ * semantically coherent amendment.
28
+ */
29
+ import type { AmendmentKind } from "./document-amendment.js";
30
+ export type GovernanceVerdict = {
31
+ ok: true;
32
+ } | {
33
+ ok: false;
34
+ reason: string;
35
+ };
36
+ export declare function documentGovernancePolicy(kind: AmendmentKind, subjectAgentId: string | null, state: {
37
+ participants: ReadonlySet<string>;
38
+ admins: ReadonlySet<string>;
39
+ }, claimedRequiredSet: readonly string[]): GovernanceVerdict;
40
+ //# sourceMappingURL=document-governance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-governance.d.ts","sourceRoot":"","sources":["../src/document-governance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,MAAM,iBAAiB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAiB7E,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,aAAa,EACnB,cAAc,EAAE,MAAM,GAAG,IAAI,EAC7B,KAAK,EAAE;IAAE,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAE,EACzE,kBAAkB,EAAE,SAAS,MAAM,EAAE,GACpC,iBAAiB,CAyHnB"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * DOD-MP-GOVERN-1 — the signature-requirement policy. Rulings D2/D3 (2026-08-11), as code.
3
+ *
4
+ * The policy VALIDATES the collection's claimed required set; it does not mint one. "Any single
5
+ * admin may act" has no single answer to mint — {a} and {b} are both acceptable claims — so the
6
+ * seam is a verdict on what the collection claims, and the multisig layer then demands every
7
+ * claimed signature actually verify.
8
+ *
9
+ * The rules:
10
+ * - **Single-admin kinds** — `add_holder`, `promote_admin`, `remove_holder` (of a non-admin),
11
+ * `change_property`: the claim is EXACTLY ONE current admin. A wider claim is refused, not
12
+ * welcomed as extra-safe: every claimed signer must sign for the collection to complete, so an
13
+ * inflated claim lets one absent co-signer veto an action the rule gives to any single admin —
14
+ * a governance change smuggled through the claim.
15
+ * - **Voluntary leave** — `remove_holder` claimed by exactly the subject themselves is always
16
+ * acceptable, admin or not. Leaving is theirs (D3).
17
+ * - **`remove_admin`** — the claim is exactly ALL OTHER admins; the subject neither required nor
18
+ * counted. With exactly two admins NEITHER CAN REMOVE THE OTHER — by design, and the refusal
19
+ * names the recourse (D3: stop working in it, duplicate it, start fresh without them).
20
+ * - **The holder door is not a bypass** — `remove_holder` of a CURRENT ADMIN (other than
21
+ * voluntary leave) is refused: holder removal drops admin status too, so allowing it under the
22
+ * single-admin rule would expel an admin on one signature, evading `remove_admin` and the
23
+ * deadlock in one move. Demote first, under remove_admin's rule.
24
+ *
25
+ * Kind/subject semantics (does the subject hold? is it already an admin? last-admin protection)
26
+ * are the causal fold's job (`deriveDocumentState`) and run BEFORE this policy is consulted — it may assume a
27
+ * semantically coherent amendment.
28
+ */
29
+ function canonical(ids) {
30
+ return [...new Set(ids)].sort();
31
+ }
32
+ /** A duplicated claim is a builder bug, refused — deduping here would hand the multisig layer a
33
+ * collection it THROWS on (`multisig_duplicate_signer`), escaping the derivation's never-throw
34
+ * contract. The two layers agree: duplicates refuse, loudly, at the first gate they reach. */
35
+ function hasDuplicates(ids) {
36
+ return new Set(ids).size !== ids.length;
37
+ }
38
+ function sameSet(a, b) {
39
+ return a.length === b.length && a.every((id, i) => id === b[i]);
40
+ }
41
+ export function documentGovernancePolicy(kind, subjectAgentId, state, claimedRequiredSet) {
42
+ if (hasDuplicates(claimedRequiredSet)) {
43
+ return {
44
+ ok: false,
45
+ reason: "governance_claim_shape: the claimed required set names a signer more than once",
46
+ };
47
+ }
48
+ const claimed = canonical(claimedRequiredSet);
49
+ if (claimed.length === 0) {
50
+ return {
51
+ ok: false,
52
+ reason: "governance_claim_shape: a collection nobody is required to sign authorizes nothing",
53
+ };
54
+ }
55
+ // SYNC-P2 — the subject's own acts: consent answers an admission, refuse_join declines one.
56
+ // The claim is EXACTLY the subject; no admin can consent on anyone's behalf (R22).
57
+ if (kind === "consent" || kind === "refuse_join" || kind === "close") {
58
+ if (subjectAgentId !== null && claimed.length === 1 && claimed[0] === subjectAgentId) {
59
+ return { ok: true };
60
+ }
61
+ return {
62
+ ok: false,
63
+ reason: `governance_consent_self: ${kind} is the subject's own act — the claim must be exactly ` +
64
+ `[${subjectAgentId ?? "the subject"}] and the collection claims [${claimed.join(", ")}]`,
65
+ };
66
+ }
67
+ // SYNC-P4 (R28): a kill is one admin's own act — self-claimed AND admin-held.
68
+ if (kind === "kill") {
69
+ if (subjectAgentId !== null &&
70
+ claimed.length === 1 &&
71
+ claimed[0] === subjectAgentId &&
72
+ state.admins.has(subjectAgentId)) {
73
+ return { ok: true };
74
+ }
75
+ if (subjectAgentId !== null && !state.admins.has(subjectAgentId)) {
76
+ return {
77
+ ok: false,
78
+ reason: `governance_not_admin: ${subjectAgentId} holds no admin power over this document — ` +
79
+ `ending everyone's document takes a current admin's own signature`,
80
+ };
81
+ }
82
+ return {
83
+ ok: false,
84
+ reason: `governance_consent_self: kill is the admin's own act — the claim must be exactly ` +
85
+ `[${subjectAgentId ?? "the admin"}] and the collection claims [${claimed.join(", ")}]`,
86
+ };
87
+ }
88
+ if (kind === "remove_admin") {
89
+ // The fold already refused a non-admin subject and the last-admin case.
90
+ if (state.admins.size === 2) {
91
+ return {
92
+ ok: false,
93
+ reason: "governance_two_admin_deadlock: with exactly two admins neither can remove the other " +
94
+ "(D3, by design) — the recourse is to stop working in this document, duplicate it, and " +
95
+ "start fresh without them",
96
+ };
97
+ }
98
+ const others = canonical([...state.admins].filter((id) => id !== subjectAgentId));
99
+ if (!sameSet(claimed, others)) {
100
+ return {
101
+ ok: false,
102
+ reason: `governance_remove_admin_set: removing an admin takes the signatures of ALL other ` +
103
+ `admins [${others.join(", ")}] exactly — the subject neither required nor counted — ` +
104
+ `and the collection claims [${claimed.join(", ")}]`,
105
+ };
106
+ }
107
+ return { ok: true };
108
+ }
109
+ // Voluntary leave: the subject signing their own removal, admin or not. Checked before the
110
+ // admin-door rule below so a leaving admin is not told to demote themselves first.
111
+ if (kind === "remove_holder" &&
112
+ subjectAgentId !== null &&
113
+ claimed.length === 1 &&
114
+ claimed[0] === subjectAgentId) {
115
+ return { ok: true };
116
+ }
117
+ if (kind === "remove_holder" && subjectAgentId !== null && state.admins.has(subjectAgentId)) {
118
+ return {
119
+ ok: false,
120
+ reason: "governance_remove_admin_first: a fellow admin cannot be expelled through the holder " +
121
+ "door — holder removal would drop their admin status with it. Demotion takes every " +
122
+ "other admin's signature, and NO VERB FOR THAT EXISTS YET: today the only way an admin " +
123
+ "leaves is to remove themselves (pass their own agent id). Do not wait for a demote " +
124
+ "command; there isn't one.",
125
+ };
126
+ }
127
+ // The single-admin kinds: add_holder, promote_admin, remove_holder (non-admin), change_property.
128
+ if (claimed.length !== 1) {
129
+ return {
130
+ ok: false,
131
+ reason: `governance_claim_shape: ${kind} is a single-admin action and the collection claims ` +
132
+ `${claimed.length} required signers — a wider claim lets an absent co-signer veto what ` +
133
+ `the rule gives to any one admin`,
134
+ };
135
+ }
136
+ if (!state.admins.has(claimed[0])) {
137
+ return {
138
+ ok: false,
139
+ reason: `governance_not_admin: ${claimed[0]} holds no admin power over this document — ` +
140
+ `${kind} takes a current admin's signature`,
141
+ };
142
+ }
143
+ return { ok: true };
144
+ }
145
+ //# sourceMappingURL=document-governance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-governance.js","sourceRoot":"","sources":["../src/document-governance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * DOD-MP-SIG-1 — the multi-signature primitive: N Ed25519 signatures over ONE preimage.
3
+ *
4
+ * A collection is COMPLETE only when every signer in the required set has a verifying signature —
5
+ * no more, no fewer, no substitutes. Anything short of that is a partial collection: storable
6
+ * while signatures are being gathered, never valid. Completeness is computed independently by any
7
+ * holder from the collection alone plus a verifier; there is no coordinator whose word settles it.
8
+ *
9
+ * ── GENERIC BY CONSTRUCTION ───────────────────────────────────────────────────────────────────
10
+ *
11
+ * Nothing in this module knows what an amendment is. The subject is carried as
12
+ * `(subject_kind, subject_hash)` — the hash of the subject's OWN to-be-signed structure — so the
13
+ * amendment record (its first consumer) and Tier 2's N-way quiescence agreement (its named second)
14
+ * use the same preimage builder and the same completeness rule. Anything subject-specific growing
15
+ * in here is the drift the M14B Tier-2-readiness lens blocks.
16
+ *
17
+ * ── THE PREIMAGE COMMITS TO WHO MUST SIGN ─────────────────────────────────────────────────────
18
+ *
19
+ * `required_signers` is inside the signed bytes, sorted so the set — not the order it was typed
20
+ * in — is what is committed. Each signer therefore signs knowing exactly which co-signatures the
21
+ * collection needs: a signature given as "the sole required signer" cannot be replayed into a
22
+ * collection claiming a different signer set, because the preimage differs and the signature
23
+ * stops verifying. Replay across chain positions is the SUBJECT's job to prevent (its TBS chains
24
+ * to its predecessor), not this layer's.
25
+ *
26
+ * Signatures are Ed25519 (RFC 8032) over the SHA-256 of the preimage array, matching the sibling
27
+ * envelope builders. Verification is injected — the same seam the proposal path uses — so this
28
+ * module stays pure types + bytes.
29
+ */
30
+ /** Domain tag in slot 0 of the to-be-signed array. Distinct from every sibling envelope domain. */
31
+ export declare const DOCUMENT_MULTISIG_DOMAIN = "CELLO-DOCUMENT-MULTISIG-v1";
32
+ /** The fields the preimage commits to. `signatures` is deliberately NOT part of the TBS. */
33
+ export interface MultisigSubject {
34
+ document_id: string;
35
+ /** What kind of thing is being co-signed, e.g. "document_amendment". Open set on purpose. */
36
+ subject_kind: string;
37
+ /** SHA-256 of the subject's own to-be-signed structure. */
38
+ subject_hash: Uint8Array;
39
+ /** Pubkey-hex identities that must ALL sign. Committed as a sorted set. */
40
+ required_signers: readonly string[];
41
+ }
42
+ export interface MultisigSignature {
43
+ signer_agent_id: string;
44
+ /** Ed25519 (RFC 8032) over `buildDocumentMultisigTbs` of the subject fields. */
45
+ signature: Uint8Array;
46
+ }
47
+ export interface MultisigCollection extends MultisigSubject {
48
+ required_signers: string[];
49
+ signatures: MultisigSignature[];
50
+ }
51
+ /**
52
+ * The canonical to-be-signed preimage: a fixed-order CBOR ARRAY with the domain in slot 0.
53
+ * SHA-256 pre-hashed by default, matching the sibling builders.
54
+ */
55
+ export declare function buildDocumentMultisigTbs(subject: MultisigSubject, opts?: {
56
+ preHash?: boolean;
57
+ }): Uint8Array;
58
+ export interface MultisigStatus {
59
+ /** True only when every required signer has exactly one verifying signature and nobody else signed. */
60
+ complete: boolean;
61
+ /** Required signers with no signature present. */
62
+ missing: string[];
63
+ /** Signers present whose signature does not verify against the preimage. */
64
+ invalidSigners: string[];
65
+ /** Signatures from identities OUTSIDE the required set — never counted, always named. */
66
+ unknown: string[];
67
+ /** Signers with more than one signature row — settle once. */
68
+ duplicates: string[];
69
+ }
70
+ /**
71
+ * Completeness, computed from the collection alone plus an injected verifier.
72
+ *
73
+ * Every defect class is NAMED rather than folded into a boolean, because the operator-facing
74
+ * question differs: "waiting on C" (missing), "B's signature is bad" (invalid), "someone outside
75
+ * the arrangement signed" (unknown — refused because extra names must not make a collection look
76
+ * more agreed than the rule it commits to), and "B signed twice" (duplicate).
77
+ */
78
+ export declare function collectionStatus(collection: MultisigCollection, verify: (agentId: string, tbs: Uint8Array, signature: Uint8Array) => boolean): MultisigStatus;
79
+ export declare function encodeMultisigCollection(collection: MultisigCollection): Uint8Array;
80
+ export declare function decodeMultisigCollection(input: Uint8Array): MultisigCollection;
81
+ //# sourceMappingURL=document-multisig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-multisig.d.ts","sourceRoot":"","sources":["../src/document-multisig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAKH,mGAAmG;AACnG,eAAO,MAAM,wBAAwB,+BAA+B,CAAC;AAErE,4FAA4F;AAC5F,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,6FAA6F;IAC7F,YAAY,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,YAAY,EAAE,UAAU,CAAC;IACzB,2EAA2E;IAC3E,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,SAAS,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAgCD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,eAAe,EACxB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/B,UAAU,CAUZ;AAED,MAAM,WAAW,cAAc;IAC7B,uGAAuG;IACvG,QAAQ,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,4EAA4E;IAC5E,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,yFAAyF;IACzF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,kBAAkB,EAC9B,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,KAAK,OAAO,GAC3E,cAAc,CAuChB;AAED,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,kBAAkB,GAAG,UAAU,CAWnF;AA0BD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,GAAG,kBAAkB,CAoC9E"}