@cello-protocol/protocol-types 0.0.53 → 0.0.54
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/document-amendment.d.ts +128 -0
- package/dist/document-amendment.d.ts.map +1 -0
- package/dist/document-amendment.js +347 -0
- package/dist/document-amendment.js.map +1 -0
- package/dist/document-envelope.js +7 -7
- package/dist/document-envelope.js.map +1 -1
- package/dist/document-governance.d.ts +40 -0
- package/dist/document-governance.d.ts.map +1 -0
- package/dist/document-governance.js +110 -0
- package/dist/document-governance.js.map +1 -0
- package/dist/document-join-answer.d.ts +34 -0
- package/dist/document-join-answer.d.ts.map +1 -0
- package/dist/document-join-answer.js +100 -0
- package/dist/document-join-answer.js.map +1 -0
- package/dist/document-join.d.ts +83 -0
- package/dist/document-join.d.ts.map +1 -0
- package/dist/document-join.js +225 -0
- package/dist/document-join.js.map +1 -0
- package/dist/document-multisig.d.ts +81 -0
- package/dist/document-multisig.d.ts.map +1 -0
- package/dist/document-multisig.js +185 -0
- package/dist/document-multisig.js.map +1 -0
- package/dist/document-proposal.d.ts +23 -14
- package/dist/document-proposal.d.ts.map +1 -1
- package/dist/document-proposal.js +80 -7
- package/dist/document-proposal.js.map +1 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOD-MP-AMEND-1 — the amendment record: an epoch event in its FINAL frame shape, and the replay
|
|
3
|
+
* that derives a document's arrangement from genesis + the chain.
|
|
4
|
+
*
|
|
5
|
+
* The genesis proposal stays the anchor — never edited, still hashing to `document_id`. What may
|
|
6
|
+
* change after it — who holds the document, who administers it, its amendable properties — is
|
|
7
|
+
* derived ONLY from this chain of signed amendments, replayed independently by every holder. An
|
|
8
|
+
* amendment whose signature collection does not meet its kind's requirement is INVALID everywhere,
|
|
9
|
+
* computed rather than detected; that is the invariant that replaced immutability (multiplayer log
|
|
10
|
+
* §6, rulings §13).
|
|
11
|
+
*
|
|
12
|
+
* ── THE FRAME IS FINAL (TIER2-READY constraint 1) ─────────────────────────────────────────────
|
|
13
|
+
*
|
|
14
|
+
* Signed, chained to its predecessor, epoch-incrementing, and carrying `state_hash` — the
|
|
15
|
+
* canonical-hash-at-boundary slot — as DEFINED-ABSENT (`null`) while the tier is `authenticated`.
|
|
16
|
+
* Tier 2 fills the slot; it does not migrate the frame. Dropping the slot "because Tier 1 doesn't
|
|
17
|
+
* use it" is the exact seam violation M14 forbade for `epoch_id`.
|
|
18
|
+
*
|
|
19
|
+
* ── WHO MUST SIGN IS INJECTED ─────────────────────────────────────────────────────────────────
|
|
20
|
+
*
|
|
21
|
+
* The replay owns MECHANICS: chaining, completeness, application order, and the arrangement
|
|
22
|
+
* invariants (admins ⊆ participants, admins never empty, the holder cap). WHICH signatures each
|
|
23
|
+
* kind requires is GOVERN-1's policy, consulted against the state BEFORE the amendment — so a
|
|
24
|
+
* newly-promoted admin is required on the NEXT amendment, not retroactively on their own
|
|
25
|
+
* promotion.
|
|
26
|
+
*/
|
|
27
|
+
import { type MultisigCollection } from "./document-multisig.js";
|
|
28
|
+
/** Domain tag in slot 0 of the to-be-signed array. Sibling of the other CELLO-DOCUMENT-* tags. */
|
|
29
|
+
export declare const DOCUMENT_AMENDMENT_DOMAIN = "CELLO-DOCUMENT-AMENDMENT-v1";
|
|
30
|
+
/** The `subject_kind` an amendment's multisig collection must carry. */
|
|
31
|
+
export declare const AMENDMENT_SUBJECT_KIND = "document_amendment";
|
|
32
|
+
/** D5 (ruled 2026-08-11): documents inherit the group-room cap. Enforced at amendment validation. */
|
|
33
|
+
export declare const MAX_DOCUMENT_HOLDERS = 20;
|
|
34
|
+
export declare const AMENDMENT_KINDS: readonly ["add_holder", "remove_holder", "promote_admin", "remove_admin", "change_property"];
|
|
35
|
+
export type AmendmentKind = (typeof AMENDMENT_KINDS)[number];
|
|
36
|
+
/**
|
|
37
|
+
* Properties an amendment may change. Deliberately NARROW to start: the seam properties are owned
|
|
38
|
+
* elsewhere (`assurance_tier` changes are the Tier 2 tier-upgrade epoch event; `schema_enforcement`
|
|
39
|
+
* is Tier 2's schema work; `topology` and `content_profile` are identity-shaped — changing them
|
|
40
|
+
* under a live document is a new agreement, not an amendment). Widening this set is a one-line,
|
|
41
|
+
* journaled decision; shrinking it after documents exist is a migration.
|
|
42
|
+
*/
|
|
43
|
+
export declare const AMENDABLE_PROPERTIES: Set<string>;
|
|
44
|
+
export interface DocumentAmendmentBody {
|
|
45
|
+
document_id: string;
|
|
46
|
+
/** The epoch this amendment MINTS: previous epoch + 1. Genesis is epoch 0 and is not an amendment. */
|
|
47
|
+
epoch_id: number;
|
|
48
|
+
/** Hex hash of the predecessor amendment's TBS; null for the first (anchored to genesis via document_id). */
|
|
49
|
+
prev_amendment_hash: string | null;
|
|
50
|
+
kind: AmendmentKind;
|
|
51
|
+
/** The holder the amendment is about (pubkey hex). Null exactly for `change_property`. */
|
|
52
|
+
subject_agent_id: string | null;
|
|
53
|
+
/** Non-null exactly for `change_property`. */
|
|
54
|
+
property_change: {
|
|
55
|
+
key: string;
|
|
56
|
+
value: string | number | boolean;
|
|
57
|
+
} | null;
|
|
58
|
+
/**
|
|
59
|
+
* Tier 2's canonical-hash-at-boundary slot. DEFINED-ABSENT (`null`) while the document's tier
|
|
60
|
+
* is `authenticated`; refused non-null at replay until the attested tier exists.
|
|
61
|
+
*/
|
|
62
|
+
state_hash: Uint8Array | null;
|
|
63
|
+
authored_at_ms: number;
|
|
64
|
+
}
|
|
65
|
+
export interface DocumentAmendmentEnvelope {
|
|
66
|
+
body: DocumentAmendmentBody;
|
|
67
|
+
/** SIG-1 collection over `documentAmendmentHash(body)` with `subject_kind: "document_amendment"`. */
|
|
68
|
+
collection: MultisigCollection;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The canonical to-be-signed preimage: a fixed-order CBOR ARRAY with the domain in slot 0.
|
|
72
|
+
* `property_change` is FLATTENED into two slots — `encodeCbor` maps follow insertion order, and a
|
|
73
|
+
* nested map would make the hash depend on how the builder happened to assemble it.
|
|
74
|
+
*/
|
|
75
|
+
export declare function buildDocumentAmendmentTbs(body: DocumentAmendmentBody, opts?: {
|
|
76
|
+
preHash?: boolean;
|
|
77
|
+
}): Uint8Array;
|
|
78
|
+
/** The amendment's identity: SHA-256 over the TBS preimage — signature-independent, like `document_id`. */
|
|
79
|
+
export declare function documentAmendmentHash(body: DocumentAmendmentBody): Uint8Array;
|
|
80
|
+
export declare function encodeDocumentAmendment(env: DocumentAmendmentEnvelope): Uint8Array;
|
|
81
|
+
export declare function decodeDocumentAmendment(input: Uint8Array): DocumentAmendmentEnvelope;
|
|
82
|
+
/** The genesis facts replay starts from — all of them signed into the proposal (or its admin slot). */
|
|
83
|
+
export interface ArrangementGenesis {
|
|
84
|
+
documentId: string;
|
|
85
|
+
proposerAgentId: string;
|
|
86
|
+
peerAgentId: string;
|
|
87
|
+
/** Pubkey-hex identities holding admin power at creation. Must be ⊆ {proposer, peer}, non-empty. */
|
|
88
|
+
adminSet: readonly string[];
|
|
89
|
+
properties: Record<string, string | number | boolean | undefined>;
|
|
90
|
+
}
|
|
91
|
+
export interface Arrangement {
|
|
92
|
+
epoch: number;
|
|
93
|
+
participants: ReadonlySet<string>;
|
|
94
|
+
admins: ReadonlySet<string>;
|
|
95
|
+
/** The DERIVED view — genesis properties + applied change_property amendments. */
|
|
96
|
+
properties: Record<string, string | number | boolean | undefined>;
|
|
97
|
+
lastAmendmentHash: string | null;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* GOVERN-1's seam: is the collection's CLAIMED required-signer set acceptable for this amendment,
|
|
101
|
+
* given the arrangement as it stands BEFORE the amendment applies. A verdict rather than a
|
|
102
|
+
* minted set, because "any single admin" has no single answer — {a} and {b} are both acceptable
|
|
103
|
+
* claims — and the multisig layer then demands every claimed signature verify.
|
|
104
|
+
*/
|
|
105
|
+
export type SignerPolicy = (kind: AmendmentKind, subjectAgentId: string | null, state: {
|
|
106
|
+
participants: ReadonlySet<string>;
|
|
107
|
+
admins: ReadonlySet<string>;
|
|
108
|
+
}, claimedRequiredSet: readonly string[]) => {
|
|
109
|
+
ok: true;
|
|
110
|
+
} | {
|
|
111
|
+
ok: false;
|
|
112
|
+
reason: string;
|
|
113
|
+
};
|
|
114
|
+
export type DeriveResult = {
|
|
115
|
+
ok: true;
|
|
116
|
+
arrangement: Arrangement;
|
|
117
|
+
} | {
|
|
118
|
+
ok: false;
|
|
119
|
+
reason: string;
|
|
120
|
+
epoch: number;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Replay: genesis + the ordered amendment chain → the current arrangement, or a loud refusal
|
|
124
|
+
* naming the epoch and the cause. NEVER a partial arrangement — a holder that cannot derive the
|
|
125
|
+
* whole chain has no arrangement, which is what makes "invalid everywhere" computable.
|
|
126
|
+
*/
|
|
127
|
+
export declare function deriveArrangement(genesis: ArrangementGenesis, amendments: readonly DocumentAmendmentEnvelope[], policy: SignerPolicy, verify: (agentId: string, tbs: Uint8Array, signature: Uint8Array) => boolean): DeriveResult;
|
|
128
|
+
//# sourceMappingURL=document-amendment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-amendment.d.ts","sourceRoot":"","sources":["../src/document-amendment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOD-MP-AMEND-1 — the amendment record: an epoch event in its FINAL frame shape, and the replay
|
|
3
|
+
* that derives a document's arrangement from genesis + the chain.
|
|
4
|
+
*
|
|
5
|
+
* The genesis proposal stays the anchor — never edited, still hashing to `document_id`. What may
|
|
6
|
+
* change after it — who holds the document, who administers it, its amendable properties — is
|
|
7
|
+
* derived ONLY from this chain of signed amendments, replayed independently by every holder. An
|
|
8
|
+
* amendment whose signature collection does not meet its kind's requirement is INVALID everywhere,
|
|
9
|
+
* computed rather than detected; that is the invariant that replaced immutability (multiplayer log
|
|
10
|
+
* §6, rulings §13).
|
|
11
|
+
*
|
|
12
|
+
* ── THE FRAME IS FINAL (TIER2-READY constraint 1) ─────────────────────────────────────────────
|
|
13
|
+
*
|
|
14
|
+
* Signed, chained to its predecessor, epoch-incrementing, and carrying `state_hash` — the
|
|
15
|
+
* canonical-hash-at-boundary slot — as DEFINED-ABSENT (`null`) while the tier is `authenticated`.
|
|
16
|
+
* Tier 2 fills the slot; it does not migrate the frame. Dropping the slot "because Tier 1 doesn't
|
|
17
|
+
* use it" is the exact seam violation M14 forbade for `epoch_id`.
|
|
18
|
+
*
|
|
19
|
+
* ── WHO MUST SIGN IS INJECTED ─────────────────────────────────────────────────────────────────
|
|
20
|
+
*
|
|
21
|
+
* The replay owns MECHANICS: chaining, completeness, application order, and the arrangement
|
|
22
|
+
* invariants (admins ⊆ participants, admins never empty, the holder cap). WHICH signatures each
|
|
23
|
+
* kind requires is GOVERN-1's policy, consulted against the state BEFORE the amendment — so a
|
|
24
|
+
* newly-promoted admin is required on the NEXT amendment, not retroactively on their own
|
|
25
|
+
* promotion.
|
|
26
|
+
*/
|
|
27
|
+
import { createHash } from "node:crypto";
|
|
28
|
+
import { encodeCbor, decodeCbor } from "./cbor.js";
|
|
29
|
+
import { collectionStatus, encodeMultisigCollection, decodeMultisigCollection, } from "./document-multisig.js";
|
|
30
|
+
/** Domain tag in slot 0 of the to-be-signed array. Sibling of the other CELLO-DOCUMENT-* tags. */
|
|
31
|
+
export const DOCUMENT_AMENDMENT_DOMAIN = "CELLO-DOCUMENT-AMENDMENT-v1";
|
|
32
|
+
/** The `subject_kind` an amendment's multisig collection must carry. */
|
|
33
|
+
export const AMENDMENT_SUBJECT_KIND = "document_amendment";
|
|
34
|
+
/** D5 (ruled 2026-08-11): documents inherit the group-room cap. Enforced at amendment validation. */
|
|
35
|
+
export const MAX_DOCUMENT_HOLDERS = 20;
|
|
36
|
+
export const AMENDMENT_KINDS = [
|
|
37
|
+
"add_holder",
|
|
38
|
+
"remove_holder",
|
|
39
|
+
"promote_admin",
|
|
40
|
+
"remove_admin",
|
|
41
|
+
"change_property",
|
|
42
|
+
];
|
|
43
|
+
/**
|
|
44
|
+
* Properties an amendment may change. Deliberately NARROW to start: the seam properties are owned
|
|
45
|
+
* elsewhere (`assurance_tier` changes are the Tier 2 tier-upgrade epoch event; `schema_enforcement`
|
|
46
|
+
* is Tier 2's schema work; `topology` and `content_profile` are identity-shaped — changing them
|
|
47
|
+
* under a live document is a new agreement, not an amendment). Widening this set is a one-line,
|
|
48
|
+
* journaled decision; shrinking it after documents exist is a migration.
|
|
49
|
+
*/
|
|
50
|
+
export const AMENDABLE_PROPERTIES = new Set(["append_only"]);
|
|
51
|
+
/**
|
|
52
|
+
* The canonical to-be-signed preimage: a fixed-order CBOR ARRAY with the domain in slot 0.
|
|
53
|
+
* `property_change` is FLATTENED into two slots — `encodeCbor` maps follow insertion order, and a
|
|
54
|
+
* nested map would make the hash depend on how the builder happened to assemble it.
|
|
55
|
+
*/
|
|
56
|
+
export function buildDocumentAmendmentTbs(body, opts = {}) {
|
|
57
|
+
const preimage = encodeCbor([
|
|
58
|
+
DOCUMENT_AMENDMENT_DOMAIN,
|
|
59
|
+
body.document_id,
|
|
60
|
+
body.epoch_id,
|
|
61
|
+
body.prev_amendment_hash,
|
|
62
|
+
body.kind,
|
|
63
|
+
body.subject_agent_id,
|
|
64
|
+
body.property_change?.key ?? null,
|
|
65
|
+
body.property_change?.value ?? null,
|
|
66
|
+
body.state_hash,
|
|
67
|
+
// BIGINT past 0xffffffff — the same float64-vs-uint64 coercion every sibling builder carries.
|
|
68
|
+
typeof body.authored_at_ms === "number" && body.authored_at_ms > 0xffffffff
|
|
69
|
+
? BigInt(body.authored_at_ms)
|
|
70
|
+
: body.authored_at_ms,
|
|
71
|
+
]);
|
|
72
|
+
if (opts.preHash === false)
|
|
73
|
+
return preimage;
|
|
74
|
+
return new Uint8Array(createHash("sha256").update(preimage).digest());
|
|
75
|
+
}
|
|
76
|
+
/** The amendment's identity: SHA-256 over the TBS preimage — signature-independent, like `document_id`. */
|
|
77
|
+
export function documentAmendmentHash(body) {
|
|
78
|
+
return new Uint8Array(createHash("sha256").update(buildDocumentAmendmentTbs(body, { preHash: false })).digest());
|
|
79
|
+
}
|
|
80
|
+
export function encodeDocumentAmendment(env) {
|
|
81
|
+
return encodeCbor({
|
|
82
|
+
// The FRAME discriminator — how the session router tells an amendment from conversation.
|
|
83
|
+
// Not part of the TBS (the hash and every signature are over the body's preimage), so its
|
|
84
|
+
// absence in early builds cost classification, never integrity.
|
|
85
|
+
type: "document_amendment",
|
|
86
|
+
body: {
|
|
87
|
+
document_id: env.body.document_id,
|
|
88
|
+
epoch_id: env.body.epoch_id,
|
|
89
|
+
prev_amendment_hash: env.body.prev_amendment_hash,
|
|
90
|
+
kind: env.body.kind,
|
|
91
|
+
subject_agent_id: env.body.subject_agent_id,
|
|
92
|
+
property_change: env.body.property_change,
|
|
93
|
+
state_hash: env.body.state_hash,
|
|
94
|
+
authored_at_ms: env.body.authored_at_ms,
|
|
95
|
+
},
|
|
96
|
+
collection: encodeMultisigCollection(env.collection),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function present(map, field) {
|
|
100
|
+
if (!(field in map)) {
|
|
101
|
+
throw new Error(`document_amendment_missing_field: ${field} is mandatory and was not present`);
|
|
102
|
+
}
|
|
103
|
+
return map[field];
|
|
104
|
+
}
|
|
105
|
+
function str(map, field) {
|
|
106
|
+
const v = present(map, field);
|
|
107
|
+
if (typeof v !== "string" || v.length === 0) {
|
|
108
|
+
throw new Error(`document_amendment_field_type: ${field} must be a non-empty text string`);
|
|
109
|
+
}
|
|
110
|
+
return v;
|
|
111
|
+
}
|
|
112
|
+
export function decodeDocumentAmendment(input) {
|
|
113
|
+
const decoded = decodeCbor(input);
|
|
114
|
+
if (typeof decoded !== "object" || decoded === null || Array.isArray(decoded)) {
|
|
115
|
+
throw new Error("document_amendment_malformed: not a CBOR map");
|
|
116
|
+
}
|
|
117
|
+
const map = decoded;
|
|
118
|
+
const frameType = present(map, "type");
|
|
119
|
+
if (frameType !== "document_amendment") {
|
|
120
|
+
throw new Error(`document_amendment_type: expected document_amendment, got ${String(frameType)}`);
|
|
121
|
+
}
|
|
122
|
+
const rawBody = present(map, "body");
|
|
123
|
+
if (typeof rawBody !== "object" || rawBody === null || Array.isArray(rawBody)) {
|
|
124
|
+
throw new Error("document_amendment_field_type: body must be a CBOR map");
|
|
125
|
+
}
|
|
126
|
+
const b = rawBody;
|
|
127
|
+
const epochId = present(b, "epoch_id");
|
|
128
|
+
if (typeof epochId !== "number" || !Number.isInteger(epochId) || epochId < 1) {
|
|
129
|
+
throw new Error(`document_amendment_epoch: must be a positive integer (genesis is epoch 0 and is not an ` +
|
|
130
|
+
`amendment), got ${String(epochId)}`);
|
|
131
|
+
}
|
|
132
|
+
const kind = str(b, "kind");
|
|
133
|
+
if (!AMENDMENT_KINDS.includes(kind)) {
|
|
134
|
+
throw new Error(`document_amendment_kind: "${kind}" is not an amendment kind this build knows ` +
|
|
135
|
+
`(${AMENDMENT_KINDS.join(", ")})`);
|
|
136
|
+
}
|
|
137
|
+
const prevHash = present(b, "prev_amendment_hash");
|
|
138
|
+
if (prevHash !== null && (typeof prevHash !== "string" || !/^[0-9a-f]{64}$/.test(prevHash))) {
|
|
139
|
+
throw new Error("document_amendment_field_type: prev_amendment_hash must be 64-hex or explicit null");
|
|
140
|
+
}
|
|
141
|
+
const subject = present(b, "subject_agent_id");
|
|
142
|
+
if (subject !== null && (typeof subject !== "string" || subject.length === 0)) {
|
|
143
|
+
throw new Error("document_amendment_field_type: subject_agent_id must be a non-empty string or explicit null");
|
|
144
|
+
}
|
|
145
|
+
const rawChange = present(b, "property_change");
|
|
146
|
+
let propertyChange = null;
|
|
147
|
+
if (rawChange !== null) {
|
|
148
|
+
if (typeof rawChange !== "object" || Array.isArray(rawChange)) {
|
|
149
|
+
throw new Error("document_amendment_field_type: property_change must be a CBOR map or null");
|
|
150
|
+
}
|
|
151
|
+
const c = rawChange;
|
|
152
|
+
const key = str(c, "key");
|
|
153
|
+
const value = present(c, "value");
|
|
154
|
+
if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") {
|
|
155
|
+
throw new Error("document_amendment_field_type: property_change.value must be a string, number, or boolean");
|
|
156
|
+
}
|
|
157
|
+
propertyChange = { key, value };
|
|
158
|
+
}
|
|
159
|
+
const stateHash = present(b, "state_hash");
|
|
160
|
+
if (stateHash !== null && !(stateHash instanceof Uint8Array)) {
|
|
161
|
+
throw new Error("document_amendment_field_type: state_hash must be a CBOR byte string or explicit null");
|
|
162
|
+
}
|
|
163
|
+
const authoredAt = present(b, "authored_at_ms");
|
|
164
|
+
if (typeof authoredAt !== "number" || !Number.isInteger(authoredAt)) {
|
|
165
|
+
throw new Error("document_amendment_field_type: authored_at_ms must be an integer");
|
|
166
|
+
}
|
|
167
|
+
const rawCollection = present(map, "collection");
|
|
168
|
+
if (!(rawCollection instanceof Uint8Array)) {
|
|
169
|
+
throw new Error("document_amendment_field_type: collection must be a CBOR byte string");
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
body: {
|
|
173
|
+
document_id: str(b, "document_id"),
|
|
174
|
+
epoch_id: epochId,
|
|
175
|
+
prev_amendment_hash: prevHash,
|
|
176
|
+
kind: kind,
|
|
177
|
+
subject_agent_id: subject,
|
|
178
|
+
property_change: propertyChange,
|
|
179
|
+
state_hash: stateHash === null ? null : new Uint8Array(stateHash),
|
|
180
|
+
authored_at_ms: authoredAt,
|
|
181
|
+
},
|
|
182
|
+
collection: decodeMultisigCollection(new Uint8Array(rawCollection)),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function refuse(reason, epoch) {
|
|
186
|
+
return { ok: false, reason, epoch };
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Replay: genesis + the ordered amendment chain → the current arrangement, or a loud refusal
|
|
190
|
+
* naming the epoch and the cause. NEVER a partial arrangement — a holder that cannot derive the
|
|
191
|
+
* whole chain has no arrangement, which is what makes "invalid everywhere" computable.
|
|
192
|
+
*/
|
|
193
|
+
export function deriveArrangement(genesis, amendments, policy, verify) {
|
|
194
|
+
const participants = new Set([genesis.proposerAgentId, genesis.peerAgentId]);
|
|
195
|
+
const admins = new Set(genesis.adminSet);
|
|
196
|
+
if (admins.size === 0) {
|
|
197
|
+
return refuse("arrangement_admin_set_empty: a document with no admins can never be amended — the " +
|
|
198
|
+
"creation flow must name at least one", 0);
|
|
199
|
+
}
|
|
200
|
+
for (const admin of admins) {
|
|
201
|
+
if (!participants.has(admin)) {
|
|
202
|
+
return refuse(`arrangement_admin_not_participant: ${admin} holds admin power but is not a holder — ` +
|
|
203
|
+
`admins are always holders`, 0);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const properties = { ...genesis.properties };
|
|
207
|
+
let epoch = 0;
|
|
208
|
+
let lastHash = null;
|
|
209
|
+
for (const env of amendments) {
|
|
210
|
+
const body = env.body;
|
|
211
|
+
const at = body.epoch_id;
|
|
212
|
+
if (body.document_id !== genesis.documentId) {
|
|
213
|
+
return refuse(`amendment_wrong_document: names ${body.document_id}, replaying ${genesis.documentId}`, at);
|
|
214
|
+
}
|
|
215
|
+
if (body.epoch_id !== epoch + 1) {
|
|
216
|
+
return refuse(`amendment_chain_gap: expected epoch ${epoch + 1} next, got ${body.epoch_id} — a missing ` +
|
|
217
|
+
`amendment is a gap to resolve, never to skip`, at);
|
|
218
|
+
}
|
|
219
|
+
if (body.prev_amendment_hash !== lastHash) {
|
|
220
|
+
return refuse(`amendment_chain_broken: epoch ${at} chains to ${body.prev_amendment_hash ?? "genesis"} ` +
|
|
221
|
+
`but the replayed predecessor is ${lastHash ?? "genesis"} — a fork, not a gap`, at);
|
|
222
|
+
}
|
|
223
|
+
// WHITELIST, not an equality on the benign value: only a tier that DEFINES the slot may fill
|
|
224
|
+
// it. An equality check on "authenticated" silently accepted a Tier 2 field whenever the
|
|
225
|
+
// genesis lacked the tier property — a mis-built genesis running degraded instead of refusing.
|
|
226
|
+
if (body.state_hash !== null && properties["assurance_tier"] !== "attested") {
|
|
227
|
+
return refuse(`amendment_state_hash_tier: epoch ${at} carries a canonical state hash but the document's ` +
|
|
228
|
+
`tier is ${JSON.stringify(properties["assurance_tier"] ?? null)} — only "attested" ` +
|
|
229
|
+
`(Tier 2) defines that slot`, at);
|
|
230
|
+
}
|
|
231
|
+
// Subject semantics against the CURRENT state — a no-op amendment is refused, not absorbed:
|
|
232
|
+
// silently absorbing "add someone who already holds" would let two amendments with one
|
|
233
|
+
// meaning carry different signatures.
|
|
234
|
+
const subject = body.subject_agent_id;
|
|
235
|
+
switch (body.kind) {
|
|
236
|
+
case "add_holder": {
|
|
237
|
+
if (subject === null)
|
|
238
|
+
return refuse(`amendment_subject_required: add_holder names nobody`, at);
|
|
239
|
+
if (participants.has(subject)) {
|
|
240
|
+
return refuse(`amendment_subject_already_holder: ${subject} already holds this document`, at);
|
|
241
|
+
}
|
|
242
|
+
if (participants.size + 1 > MAX_DOCUMENT_HOLDERS) {
|
|
243
|
+
return refuse(`amendment_holder_cap: admitting ${subject} would make ${participants.size + 1} holders ` +
|
|
244
|
+
`and the cap is ${MAX_DOCUMENT_HOLDERS} (D5)`, at);
|
|
245
|
+
}
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
case "remove_holder": {
|
|
249
|
+
if (subject === null)
|
|
250
|
+
return refuse(`amendment_subject_required: remove_holder names nobody`, at);
|
|
251
|
+
if (!participants.has(subject)) {
|
|
252
|
+
return refuse(`amendment_subject_not_holder: ${subject} does not hold this document`, at);
|
|
253
|
+
}
|
|
254
|
+
if (admins.has(subject) && admins.size === 1) {
|
|
255
|
+
return refuse(`amendment_last_admin: removing ${subject} would leave the document with no admins — ` +
|
|
256
|
+
`it could never be amended again`, at);
|
|
257
|
+
}
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
case "promote_admin": {
|
|
261
|
+
if (subject === null)
|
|
262
|
+
return refuse(`amendment_subject_required: promote_admin names nobody`, at);
|
|
263
|
+
if (!participants.has(subject)) {
|
|
264
|
+
return refuse(`amendment_subject_not_holder: ${subject} does not hold this document`, at);
|
|
265
|
+
}
|
|
266
|
+
if (admins.has(subject)) {
|
|
267
|
+
return refuse(`amendment_subject_already_admin: ${subject} is already an admin`, at);
|
|
268
|
+
}
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
case "remove_admin": {
|
|
272
|
+
if (subject === null)
|
|
273
|
+
return refuse(`amendment_subject_required: remove_admin names nobody`, at);
|
|
274
|
+
if (!admins.has(subject)) {
|
|
275
|
+
return refuse(`amendment_subject_not_admin: ${subject} holds no admin power to remove`, at);
|
|
276
|
+
}
|
|
277
|
+
if (admins.size === 1) {
|
|
278
|
+
return refuse(`amendment_last_admin: demoting ${subject} would leave the document with no admins — ` +
|
|
279
|
+
`it could never be amended again`, at);
|
|
280
|
+
}
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
case "change_property": {
|
|
284
|
+
if (subject !== null) {
|
|
285
|
+
return refuse(`amendment_subject_forbidden: change_property is about the document, not a holder`, at);
|
|
286
|
+
}
|
|
287
|
+
if (body.property_change === null) {
|
|
288
|
+
return refuse(`amendment_property_missing: change_property carries no change`, at);
|
|
289
|
+
}
|
|
290
|
+
if (!AMENDABLE_PROPERTIES.has(body.property_change.key)) {
|
|
291
|
+
return refuse(`amendment_property_not_amendable: "${body.property_change.key}" is not amendable — ` +
|
|
292
|
+
`the amendable set is {${[...AMENDABLE_PROPERTIES].join(", ")}}; tier and schema ` +
|
|
293
|
+
`changes are Tier 2 epoch events, topology and profile are a new agreement`, at);
|
|
294
|
+
}
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// The collection: bound to THIS amendment, its claimed required set ACCEPTABLE TO THE POLICY
|
|
299
|
+
// for the state BEFORE it, and complete. Order matters — a mismatch in what the collection claims is
|
|
300
|
+
// reported before whether it gathered enough names for the wrong claim.
|
|
301
|
+
const expectedHash = documentAmendmentHash(body);
|
|
302
|
+
if (env.collection.document_id !== body.document_id) {
|
|
303
|
+
return refuse(`amendment_collection_document_mismatch: collection names ${env.collection.document_id}`, at);
|
|
304
|
+
}
|
|
305
|
+
if (env.collection.subject_kind !== AMENDMENT_SUBJECT_KIND) {
|
|
306
|
+
return refuse(`amendment_collection_kind: collection signs "${env.collection.subject_kind}", not an amendment`, at);
|
|
307
|
+
}
|
|
308
|
+
if (Buffer.compare(env.collection.subject_hash, expectedHash) !== 0) {
|
|
309
|
+
return refuse(`amendment_collection_subject_mismatch: the collection signs a different amendment than ` +
|
|
310
|
+
`the one it rides with`, at);
|
|
311
|
+
}
|
|
312
|
+
const verdict = policy(body.kind, subject, { participants, admins }, env.collection.required_signers);
|
|
313
|
+
if (!verdict.ok) {
|
|
314
|
+
// The policy's reason IS the diagnosis — epoch context prepended, nothing substituted.
|
|
315
|
+
return refuse(`epoch ${at}: ${verdict.reason}`, at);
|
|
316
|
+
}
|
|
317
|
+
const status = collectionStatus(env.collection, verify);
|
|
318
|
+
if (!status.complete) {
|
|
319
|
+
return refuse(`amendment_collection_incomplete: epoch ${at} — missing [${status.missing.join(", ")}], ` +
|
|
320
|
+
`invalid [${status.invalidSigners.join(", ")}], unknown [${status.unknown.join(", ")}], ` +
|
|
321
|
+
`duplicate [${status.duplicates.join(", ")}]`, at);
|
|
322
|
+
}
|
|
323
|
+
// Apply.
|
|
324
|
+
switch (body.kind) {
|
|
325
|
+
case "add_holder":
|
|
326
|
+
participants.add(subject);
|
|
327
|
+
break;
|
|
328
|
+
case "remove_holder":
|
|
329
|
+
participants.delete(subject);
|
|
330
|
+
admins.delete(subject);
|
|
331
|
+
break;
|
|
332
|
+
case "promote_admin":
|
|
333
|
+
admins.add(subject);
|
|
334
|
+
break;
|
|
335
|
+
case "remove_admin":
|
|
336
|
+
admins.delete(subject);
|
|
337
|
+
break;
|
|
338
|
+
case "change_property":
|
|
339
|
+
properties[body.property_change.key] = body.property_change.value;
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
epoch = body.epoch_id;
|
|
343
|
+
lastHash = Buffer.from(expectedHash).toString("hex");
|
|
344
|
+
}
|
|
345
|
+
return { ok: true, arrangement: { epoch, participants, admins, properties, lastAmendmentHash: lastHash } };
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=document-amendment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-amendment.js","sourceRoot":"","sources":["../src/document-amendment.ts"],"names":[],"mappings":"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"}
|
|
@@ -153,13 +153,13 @@ export function decodeDocumentUpdateEnvelope(bytes) {
|
|
|
153
153
|
throw new Error(`document_envelope_document_id: must be a 32-byte lowercase hex digest, got "${documentId}"`);
|
|
154
154
|
}
|
|
155
155
|
const epochId = requirePresent(map, "epoch_id");
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
throw new Error(`document_envelope_epoch:
|
|
156
|
+
// SHAPE ONLY (M14B / DOD-MP-AMEND-1 — relaxed from a hard `!== 0` refusal). Epoch CORRECTNESS
|
|
157
|
+
// is a per-document fact — the current epoch is derived from the amendment chain — and a
|
|
158
|
+
// decoder cannot know it. The inbound path rules on it, and may trust this decoded value
|
|
159
|
+
// because `epoch_id` sits inside the signed TBS: a lie about the epoch fails verification
|
|
160
|
+
// before any epoch comparison runs.
|
|
161
|
+
if (typeof epochId !== "number" || !Number.isInteger(epochId) || epochId < 0) {
|
|
162
|
+
throw new Error(`document_envelope_epoch: must be a non-negative integer, got ${String(epochId)}`);
|
|
163
163
|
}
|
|
164
164
|
const prev = requirePresent(map, "doc_prev_hash");
|
|
165
165
|
if (prev !== null && (typeof prev !== "string" || !HEX32.test(prev))) {
|
|
@@ -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 `deriveArrangement`'s job 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,CA+EnB"}
|