run402 4.68.3 → 4.69.1
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/cli.mjs +2 -2
- package/core-dist/allowance-auth.js +1 -1
- package/core-dist/allowance.js +1 -1
- package/core-dist/config.js +4 -4
- package/core-dist/keystore.js +7 -7
- package/core-dist/profiles.js +1 -1
- package/core-dist/redact.js +6 -7
- package/git-remote-run402.mjs +2 -2
- package/gitvault-surface.json +2 -1
- package/lib/agent.mjs +1 -1
- package/lib/allowance.mjs +3 -4
- package/lib/argparse.mjs +7 -9
- package/lib/billing.mjs +33 -35
- package/lib/buzz-notifications.mjs +3 -2
- package/lib/buzz.mjs +14 -8
- package/lib/buzz.test.mjs +1 -1
- package/lib/command-manifest.mjs +38 -20
- package/lib/config.mjs +1 -1
- package/lib/deploy-v2.mjs +3 -3
- package/lib/doctor-source-scan.mjs +1 -1
- package/lib/doctor.mjs +42 -25
- package/lib/email.mjs +2 -3
- package/lib/harness-context.mjs +1 -2
- package/lib/init.mjs +1 -1
- package/lib/next-actions.mjs +1 -1
- package/lib/org-context.mjs +83 -2
- package/lib/org.mjs +231 -114
- package/lib/projects.mjs +2 -2
- package/lib/remote-helper-session.mjs +26 -32
- package/lib/repos.mjs +117 -15
- package/lib/rooms-context.mjs +5 -5
- package/lib/sdk-errors.mjs +1 -2
- package/lib/status.mjs +1 -1
- package/lib/update-check.test.mjs +1 -1
- package/lib/wallet-context.mjs +10 -10
- package/lib/wallet-context.test.mjs +6 -7
- package/lib/wallets.mjs +2 -2
- package/lib/webhooks.mjs +2 -2
- package/package.json +1 -1
- package/sdk/core-dist/allowance-auth.js +1 -1
- package/sdk/core-dist/allowance.js +1 -1
- package/sdk/core-dist/config.js +4 -4
- package/sdk/core-dist/keystore.js +7 -7
- package/sdk/core-dist/profiles.js +1 -1
- package/sdk/core-dist/redact.js +6 -7
- package/sdk/dist/delegate-credentials.d.ts +1 -1
- package/sdk/dist/delegate-credentials.js +1 -1
- package/sdk/dist/errors.d.ts +10 -4
- package/sdk/dist/errors.d.ts.map +1 -1
- package/sdk/dist/errors.js +2 -3
- package/sdk/dist/errors.js.map +1 -1
- package/sdk/dist/kernel.js +1 -1
- package/sdk/dist/kernel.js.map +1 -1
- package/sdk/dist/namespaces/allowance.d.ts +1 -1
- package/sdk/dist/namespaces/allowance.js +1 -1
- package/sdk/dist/namespaces/allowance.js.map +1 -1
- package/sdk/dist/namespaces/assets.js +1 -1
- package/sdk/dist/namespaces/assets.js.map +1 -1
- package/sdk/dist/namespaces/assets.types.d.ts +1 -1
- package/sdk/dist/namespaces/ci.d.ts.map +1 -1
- package/sdk/dist/namespaces/ci.js +4 -6
- package/sdk/dist/namespaces/ci.js.map +1 -1
- package/sdk/dist/namespaces/deploy.js +7 -8
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.crypto.d.ts +86 -3
- package/sdk/dist/namespaces/gitvault.crypto.d.ts.map +1 -1
- package/sdk/dist/namespaces/gitvault.crypto.js +102 -3
- package/sdk/dist/namespaces/gitvault.crypto.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.d.ts +197 -17
- package/sdk/dist/namespaces/gitvault.d.ts.map +1 -1
- package/sdk/dist/namespaces/gitvault.js +698 -58
- package/sdk/dist/namespaces/gitvault.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.types.d.ts +91 -3
- package/sdk/dist/namespaces/gitvault.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/gitvault.types.js.map +1 -1
- package/sdk/dist/namespaces/operator.d.ts +1 -1
- package/sdk/dist/namespaces/operator.js +1 -1
- package/sdk/dist/namespaces/org.d.ts +14 -1
- package/sdk/dist/namespaces/org.d.ts.map +1 -1
- package/sdk/dist/namespaces/org.js +15 -0
- package/sdk/dist/namespaces/org.js.map +1 -1
- package/sdk/dist/namespaces/org.types.d.ts +30 -0
- package/sdk/dist/namespaces/org.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/projects.types.d.ts +1 -1
- package/sdk/dist/namespaces/subdomains.js +1 -1
- package/sdk/dist/namespaces/subdomains.js.map +1 -1
- package/sdk/dist/namespaces/transfers.d.ts +3 -4
- package/sdk/dist/namespaces/transfers.d.ts.map +1 -1
- package/sdk/dist/namespaces/transfers.js +1 -2
- package/sdk/dist/namespaces/transfers.js.map +1 -1
- package/sdk/dist/node/actions-node.d.ts.map +1 -1
- package/sdk/dist/node/actions-node.js +3 -4
- package/sdk/dist/node/actions-node.js.map +1 -1
- package/sdk/dist/node/deploy-manifest.js +2 -2
- package/sdk/dist/node/deploy-manifest.js.map +1 -1
- package/sdk/dist/node/gitvault-address.js +2 -2
- package/sdk/dist/node/gitvault-address.js.map +1 -1
- package/sdk/dist/node/gitvault-creation-journal.d.ts +1 -1
- package/sdk/dist/node/gitvault-creation-journal.js +2 -2
- package/sdk/dist/node/gitvault-creation-journal.js.map +1 -1
- package/sdk/dist/node/gitvault-deploy.d.ts +2 -2
- package/sdk/dist/node/gitvault-deploy.js +2 -2
- package/sdk/dist/node/gitvault-handoff.d.ts +140 -1
- package/sdk/dist/node/gitvault-handoff.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-handoff.js +226 -22
- package/sdk/dist/node/gitvault-handoff.js.map +1 -1
- package/sdk/dist/node/gitvault-keystore.d.ts +78 -3
- package/sdk/dist/node/gitvault-keystore.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-keystore.js +46 -5
- package/sdk/dist/node/gitvault-keystore.js.map +1 -1
- package/sdk/dist/node/gitvault-mirror.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-mirror.js +3 -5
- package/sdk/dist/node/gitvault-mirror.js.map +1 -1
- package/sdk/dist/node/gitvault-profile-scan.js +1 -1
- package/sdk/dist/node/gitvault-publication.d.ts +379 -21
- package/sdk/dist/node/gitvault-publication.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-publication.js +664 -41
- package/sdk/dist/node/gitvault-publication.js.map +1 -1
- package/sdk/dist/node/gitvault-recover.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-recover.js +7 -10
- package/sdk/dist/node/gitvault-recover.js.map +1 -1
- package/sdk/dist/node/gitvault-restore.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-restore.js +5 -2
- package/sdk/dist/node/gitvault-restore.js.map +1 -1
- package/sdk/dist/node/gitvault-snapshot.d.ts +16 -2
- package/sdk/dist/node/gitvault-snapshot.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-snapshot.js +23 -2
- package/sdk/dist/node/gitvault-snapshot.js.map +1 -1
- package/sdk/dist/node/gitvault-writer-state.d.ts +201 -0
- package/sdk/dist/node/gitvault-writer-state.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-writer-state.js +357 -0
- package/sdk/dist/node/gitvault-writer-state.js.map +1 -0
- package/sdk/dist/node/index.d.ts +5 -1
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +21 -2
- package/sdk/dist/node/index.js.map +1 -1
- package/sdk/dist/node/paid-fetch.d.ts.map +1 -1
- package/sdk/dist/node/paid-fetch.js +3 -4
- package/sdk/dist/node/paid-fetch.js.map +1 -1
- package/sdk/dist/node/sites-node.js +1 -1
- package/sdk/dist/node/sites-node.js.map +1 -1
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The exact, closed set of refusal codes this module can ever return —
|
|
3
|
+
* mirrors the gateway's `WriterStateRefusalCode` exactly (same union, same
|
|
4
|
+
* names) so a caller's error mapping needs no translation table.
|
|
5
|
+
*/
|
|
6
|
+
export type WriterStateRefusalCode = "VALIDATION_FAILED" | "GITVAULT_WRITER_NOT_ADMITTED" | "HANDOFF_KEY_REVOKED" | "RECIPIENT_SET_MISMATCH" | "EPOCH_ROTATION_WOULD_LEAVE_VAULT_UNCOVERED";
|
|
7
|
+
export type WriterStateVerdict = {
|
|
8
|
+
ok: true;
|
|
9
|
+
} | {
|
|
10
|
+
ok: false;
|
|
11
|
+
code: WriterStateRefusalCode;
|
|
12
|
+
detail: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const ORG_ROLE_RANK: Readonly<Record<string, number>>;
|
|
15
|
+
export declare const WRITER_ELIGIBLE_ROLE_RANK: number;
|
|
16
|
+
/** Does `role` meet the writer-eligibility threshold (developer or above)? An unknown/absent role never does. */
|
|
17
|
+
export declare function meetsWriterEligibleRole(role: string | null | undefined): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* gitvault-multi-writer rev 47 (task 5.5) — predicts the role a handoff mint
|
|
20
|
+
* will actually confer, mirroring the gateway's OWN attenuation exactly
|
|
21
|
+
* (`services/gitvault/claims.ts mintHandoff`: `requestedRole &&
|
|
22
|
+
* roleRank(requestedRole) < roleRank(minterRole) ? requestedRole :
|
|
23
|
+
* minterRole`). The mint's `writer_admission_grant.minted_role` must equal
|
|
24
|
+
* this prediction byte-for-byte or the gateway refuses VALIDATION_FAILED —
|
|
25
|
+
* after the checkpoint push has already been paid for — so getting the
|
|
26
|
+
* comparison direction right matters. An unrecognized `requestedRole`
|
|
27
|
+
* (never a legal `OrgRole` server-side either) is treated as "no request":
|
|
28
|
+
* a garbage role string fails the gateway's OWN mint validation before its
|
|
29
|
+
* attenuation logic — and therefore before this grant-mismatch check —
|
|
30
|
+
* ever runs, so predicting `minterRole` for that case is never observed as
|
|
31
|
+
* wrong, only moot.
|
|
32
|
+
*/
|
|
33
|
+
export declare function predictMintedRole(requestedRole: string | undefined, minterRole: string): string;
|
|
34
|
+
export interface WriterKeyEntry {
|
|
35
|
+
writer_key_id: string;
|
|
36
|
+
signing_pubkey: string;
|
|
37
|
+
}
|
|
38
|
+
/** The full chain-derived writer state at some generation — protocol §4.15. */
|
|
39
|
+
export interface WriterChainState {
|
|
40
|
+
version: string;
|
|
41
|
+
writers: readonly WriterKeyEntry[];
|
|
42
|
+
sha256: string;
|
|
43
|
+
/** Permanently burned writer_key_ids — protocol §4.15, never re-addable, on this vault, ever. */
|
|
44
|
+
burnedWriterKeyIds: ReadonlySet<string>;
|
|
45
|
+
/** Permanently consumed handoff_ids — protocol §4.17, a writer_admission_grant is single-use. */
|
|
46
|
+
consumedHandoffIds: ReadonlySet<string>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* `vk_` fingerprint of a base64url-encoded Ed25519 public key, or `null` for
|
|
50
|
+
* anything that doesn't decode as a canonical 32-byte base64url scalar —
|
|
51
|
+
* mirrors the gateway's `writerKeyIdOf` (never throws on a malformed key).
|
|
52
|
+
*/
|
|
53
|
+
export declare function writerKeyIdOf(signingPubkeyB64u: string): string | null;
|
|
54
|
+
/** protocol §4.15: writer_set_sha256 = SHA-256(JCS({format, repo_id, version, writers})). */
|
|
55
|
+
export declare function writerSetSha256(repoId: string, version: string, writers: readonly WriterKeyEntry[]): string;
|
|
56
|
+
/**
|
|
57
|
+
* protocol §4.15: the version-0 singleton, derived from `creator_signing_pubkey`
|
|
58
|
+
* (see the module doc for why this diverges from reading a `writer_key_id`
|
|
59
|
+
* field directly).
|
|
60
|
+
*/
|
|
61
|
+
export declare function initialWriterState(repoId: string, genesis: {
|
|
62
|
+
creator_signing_pubkey: string;
|
|
63
|
+
}): WriterChainState;
|
|
64
|
+
/**
|
|
65
|
+
* protocol §4.16: apply an ALREADY-ADMITTED `add_writer_key` transition.
|
|
66
|
+
* Caller MUST have validated it first (`validateAddWriterKeyPayload`) — this
|
|
67
|
+
* function performs no checks, it only advances state.
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
70
|
+
* gitvault-multi-writer (task 5.6) — builds a well-formed `handoff`-door
|
|
71
|
+
* `add_writer_key` payload (schema `r402s.add-writer-key/v1`) from a
|
|
72
|
+
* predecessor writer-set pin and the claimant's own key — the pure
|
|
73
|
+
* assembly step `GitvaultVault.submitWriterActivationHead` delegates to,
|
|
74
|
+
* kept separate so it can be unit-tested directly against
|
|
75
|
+
* {@link validateAddWriterKeyPayload} without a full vault/keystore/git
|
|
76
|
+
* harness. `predecessorPin` needs only `{version, sha256, writers}` — the
|
|
77
|
+
* caller's persisted `writer_set_pin` shape already matches, no
|
|
78
|
+
* `WriterChainState` (with its Sets) is required to build an OUTGOING
|
|
79
|
+
* payload; only to VALIDATE an incoming one.
|
|
80
|
+
*/
|
|
81
|
+
export declare function buildAddWriterKeyActivationPayload(repoId: string, predecessorPin: {
|
|
82
|
+
version: string;
|
|
83
|
+
sha256: string;
|
|
84
|
+
writers: readonly WriterKeyEntry[];
|
|
85
|
+
}, addedWriter: WriterKeyEntry & {
|
|
86
|
+
principal_id: string;
|
|
87
|
+
}, handoffId: string, grant: Record<string, unknown>, acceptance: Record<string, unknown>): AddWriterKeyPayload;
|
|
88
|
+
/**
|
|
89
|
+
* gitvault-multi-writer (task 5.7) — builds a well-formed `writer`-door
|
|
90
|
+
* `add_writer_key` payload from a predecessor writer-set pin and the
|
|
91
|
+
* candidate's own published signing key. Unlike {@link
|
|
92
|
+
* buildAddWriterKeyActivationPayload} (the handoff door), this authorization
|
|
93
|
+
* carries no grant/acceptance — `validateAddWriterKeyPayload`'s `"writer"`
|
|
94
|
+
* branch licenses it purely by the CARRYING HEAD's own signer already being
|
|
95
|
+
* an active writer (checked at admission time, both client-side replay and
|
|
96
|
+
* gateway-side `checkTransitionAdmissible`), so the acting writer's identity
|
|
97
|
+
* never appears IN the payload itself, only in the head that carries it.
|
|
98
|
+
*/
|
|
99
|
+
export declare function buildWriterDoorAddWriterKeyPayload(repoId: string, predecessorPin: {
|
|
100
|
+
version: string;
|
|
101
|
+
sha256: string;
|
|
102
|
+
writers: readonly WriterKeyEntry[];
|
|
103
|
+
}, addedWriter: WriterKeyEntry & {
|
|
104
|
+
principal_id: string;
|
|
105
|
+
}): AddWriterKeyPayload;
|
|
106
|
+
export declare function applyAddWriterKey(repoId: string, state: WriterChainState, addedWriter: WriterKeyEntry, consumedHandoffId: string | null): WriterChainState;
|
|
107
|
+
/**
|
|
108
|
+
* protocol §4.18: apply an ALREADY-ADMITTED `rotate_epoch{writer_set_update}`.
|
|
109
|
+
* Caller MUST have validated it first (`validateWriterSetUpdate`). `writers`
|
|
110
|
+
* MAY be empty — the explicit sole-writer `writer_key_revoked` read-only
|
|
111
|
+
* terminal (D228) is a legal resulting state, not an error at this layer.
|
|
112
|
+
*/
|
|
113
|
+
export declare function applyWriterSetUpdate(repoId: string, state: WriterChainState, removedWriterKeyIds: readonly string[]): WriterChainState;
|
|
114
|
+
/**
|
|
115
|
+
* The FIRST, ordinary-case lookup (protocol §5A step 1): is this head's own
|
|
116
|
+
* `writer_key_id` already active in the predecessor writer state? A null
|
|
117
|
+
* result does not by itself mean refusal — the caller still checks for a
|
|
118
|
+
* qualifying `add_writer_key{"handoff"}` transition naming exactly this key
|
|
119
|
+
* before concluding `GITVAULT_WRITER_NOT_ADMITTED`.
|
|
120
|
+
*/
|
|
121
|
+
export declare function resolveActiveWriter(state: WriterChainState, headWriterKeyId: string): WriterKeyEntry | null;
|
|
122
|
+
export interface AddWriterKeyPayload {
|
|
123
|
+
schema: "r402s.add-writer-key/v1";
|
|
124
|
+
repo_id: string;
|
|
125
|
+
base_writer_set: {
|
|
126
|
+
version: string;
|
|
127
|
+
sha256: string;
|
|
128
|
+
};
|
|
129
|
+
next_writer_set: {
|
|
130
|
+
version: string;
|
|
131
|
+
writers: WriterKeyEntry[];
|
|
132
|
+
sha256: string;
|
|
133
|
+
};
|
|
134
|
+
added_writer: {
|
|
135
|
+
writer_key_id: string;
|
|
136
|
+
signing_pubkey: string;
|
|
137
|
+
principal_id: string;
|
|
138
|
+
};
|
|
139
|
+
authorization: {
|
|
140
|
+
kind: "writer";
|
|
141
|
+
} | {
|
|
142
|
+
kind: "handoff";
|
|
143
|
+
grant: Record<string, unknown>;
|
|
144
|
+
acceptance: Record<string, unknown>;
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* The FULL cryptographic + structural validation of an `add_writer_key`
|
|
149
|
+
* payload (protocol §4.16/§4.17), given the writer state at the PREDECESSOR
|
|
150
|
+
* generation and the carrying head's own `writer_key_id`. Does NOT check
|
|
151
|
+
* `authorization.kind:"writer"`'s org-membership eligibility (active
|
|
152
|
+
* membership >= developer, directory possession-verification) — that is
|
|
153
|
+
* gateway-only, live-state-dependent, and re-checked under the admission
|
|
154
|
+
* fence server-side; a client validating its OWN candidate transition before
|
|
155
|
+
* submission relies on the gateway's fence-time re-check as the backstop.
|
|
156
|
+
*/
|
|
157
|
+
export declare function validateAddWriterKeyPayload(repoId: string, predecessorState: WriterChainState, payload: AddWriterKeyPayload, headWriterKeyId: string): WriterStateVerdict;
|
|
158
|
+
export interface WriterSetUpdatePayload {
|
|
159
|
+
base_version: string;
|
|
160
|
+
base_sha256: string;
|
|
161
|
+
next_version: string;
|
|
162
|
+
next_sha256: string;
|
|
163
|
+
removed: readonly {
|
|
164
|
+
writer_key_id: string;
|
|
165
|
+
principal_id: string;
|
|
166
|
+
reason: string;
|
|
167
|
+
}[];
|
|
168
|
+
writers: readonly WriterKeyEntry[];
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* The FULL cryptographic + structural validation of a `rotate_epoch`
|
|
172
|
+
* transition's `writer_set_update` field (protocol §4.18, D227), given the
|
|
173
|
+
* writer state at the PREDECESSOR generation, the carrying head's own
|
|
174
|
+
* `writer_key_id`, and the caller's own belief about which writer keys are
|
|
175
|
+
* due for removal (`gatewayBlockedWriterKeyIds` — for a client building a
|
|
176
|
+
* CANDIDATE rotation this is `state read (blocked set)`; the gateway's own
|
|
177
|
+
* fence-time re-check is the source of truth at admission). `allowEmptyResult`
|
|
178
|
+
* is true ONLY for the explicit, owner+step-up, sole remaining writer
|
|
179
|
+
* `writer_key_revoked` removal (D228); every other call site passes `false`.
|
|
180
|
+
*/
|
|
181
|
+
export declare function validateWriterSetUpdate(repoId: string, predecessorState: WriterChainState, update: WriterSetUpdatePayload, headWriterKeyId: string, gatewayBlockedWriterKeyIds: ReadonlySet<string>, allowEmptyResult: boolean): WriterStateVerdict;
|
|
182
|
+
/**
|
|
183
|
+
* DR / offline replay (protocol §5A "Writer-set DR"): rebuild the writer
|
|
184
|
+
* state purely from genesis + admitted writer-changing transitions, in
|
|
185
|
+
* order. Every transition MUST already be admitted (this performs no
|
|
186
|
+
* validation — apply-only, mirroring `applyAddWriterKey`/`applyWriterSetUpdate`).
|
|
187
|
+
*/
|
|
188
|
+
export type AdmittedWriterTransition = {
|
|
189
|
+
kind: "add_writer_key";
|
|
190
|
+
addedWriter: WriterKeyEntry;
|
|
191
|
+
consumedHandoffId: string | null;
|
|
192
|
+
} | {
|
|
193
|
+
kind: "writer_set_update";
|
|
194
|
+
removedWriterKeyIds: readonly string[];
|
|
195
|
+
};
|
|
196
|
+
export declare function replayWriterState(repoId: string, genesis: {
|
|
197
|
+
creator_signing_pubkey: string;
|
|
198
|
+
}, transitions: readonly AdmittedWriterTransition[]): WriterChainState;
|
|
199
|
+
/** protocol §4.15: `MAX_VAULT_WRITERS`. A writer-changing transition producing more active writers than this is refused. */
|
|
200
|
+
export declare const MAX_VAULT_WRITERS = 64;
|
|
201
|
+
//# sourceMappingURL=gitvault-writer-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitvault-writer-state.d.ts","sourceRoot":"","sources":["../../src/node/gitvault-writer-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* r402s/v0 rev 47 — the writer set as CHAIN STATE (protocol §4.15), and the
|
|
3
|
+
* pure cryptographic half of `add_writer_key` / `rotate_epoch{writer_set_update}`
|
|
4
|
+
* admission (§4.16–§4.18, D221–D227). Client-side mirror of the gateway's
|
|
5
|
+
* `services/gitvault/writer-state.ts` (task gitvault-multi-writer 2.3) — same
|
|
6
|
+
* functions, same Verdict shape, same crypto rules — so both sides reach the
|
|
7
|
+
* SAME conclusion from the SAME chain bytes with no shared network call.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately pure and isomorphic (no I/O, no Node-only APIs): a recovering
|
|
10
|
+
* client, the browser viewer, and `r402s-verify` all need to replay writer
|
|
11
|
+
* state from nothing but genesis + admitted chain objects. `checkChainLink`'s
|
|
12
|
+
* own asserts stay ignorant of transition PAYLOADS (protocol discipline); this
|
|
13
|
+
* module is where a transition's writer-set content gets opened and verified,
|
|
14
|
+
* once the caller has already established the transition is admitted or is
|
|
15
|
+
* validating a candidate before submission.
|
|
16
|
+
*
|
|
17
|
+
* One deliberate divergence from the gateway's file: `initialWriterState`
|
|
18
|
+
* DERIVES the version-0 writer_key_id from `creator_signing_pubkey` rather
|
|
19
|
+
* than reading a `genesis.writer_key_id` field — the gateway's own genesis
|
|
20
|
+
* admission already asserts `writerKeyIdOf(creator_signing_pubkey) ===
|
|
21
|
+
* genesis.writer_key_id` (chain.ts), so for any validly-admitted genesis both
|
|
22
|
+
* approaches agree; deriving is simpler for a client that has no reason to
|
|
23
|
+
* trust an extra redundant field over the pubkey it already verified.
|
|
24
|
+
*/
|
|
25
|
+
import { LocalError } from "../errors.js";
|
|
26
|
+
import { GITVAULT_B64U_32_RE, GITVAULT_B64U_64_RE, ed25519VerifyStrict, fromBase64url, gitvaultWithoutSignature, isCanonicalBase64url, jcs, sha256Hex, signaturePreimage, vkFingerprint, } from "../namespaces/gitvault.crypto.js";
|
|
27
|
+
// ─── Org role lattice (mirrors org-owned-control-plane's owner > admin > developer > billing > viewer) ──
|
|
28
|
+
export const ORG_ROLE_RANK = Object.freeze({
|
|
29
|
+
viewer: 0,
|
|
30
|
+
billing: 1,
|
|
31
|
+
developer: 2,
|
|
32
|
+
admin: 3,
|
|
33
|
+
owner: 4,
|
|
34
|
+
});
|
|
35
|
+
export const WRITER_ELIGIBLE_ROLE_RANK = ORG_ROLE_RANK.developer;
|
|
36
|
+
/** Does `role` meet the writer-eligibility threshold (developer or above)? An unknown/absent role never does. */
|
|
37
|
+
export function meetsWriterEligibleRole(role) {
|
|
38
|
+
return !!role && (ORG_ROLE_RANK[role] ?? -1) >= WRITER_ELIGIBLE_ROLE_RANK;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* gitvault-multi-writer rev 47 (task 5.5) — predicts the role a handoff mint
|
|
42
|
+
* will actually confer, mirroring the gateway's OWN attenuation exactly
|
|
43
|
+
* (`services/gitvault/claims.ts mintHandoff`: `requestedRole &&
|
|
44
|
+
* roleRank(requestedRole) < roleRank(minterRole) ? requestedRole :
|
|
45
|
+
* minterRole`). The mint's `writer_admission_grant.minted_role` must equal
|
|
46
|
+
* this prediction byte-for-byte or the gateway refuses VALIDATION_FAILED —
|
|
47
|
+
* after the checkpoint push has already been paid for — so getting the
|
|
48
|
+
* comparison direction right matters. An unrecognized `requestedRole`
|
|
49
|
+
* (never a legal `OrgRole` server-side either) is treated as "no request":
|
|
50
|
+
* a garbage role string fails the gateway's OWN mint validation before its
|
|
51
|
+
* attenuation logic — and therefore before this grant-mismatch check —
|
|
52
|
+
* ever runs, so predicting `minterRole` for that case is never observed as
|
|
53
|
+
* wrong, only moot.
|
|
54
|
+
*/
|
|
55
|
+
export function predictMintedRole(requestedRole, minterRole) {
|
|
56
|
+
return requestedRole !== undefined && requestedRole in ORG_ROLE_RANK && ORG_ROLE_RANK[requestedRole] < ORG_ROLE_RANK[minterRole] ? requestedRole : minterRole;
|
|
57
|
+
}
|
|
58
|
+
const WRITER_SET_FORMAT = "r402s/writer-set/v1";
|
|
59
|
+
function asStr(v) {
|
|
60
|
+
return typeof v === "string" ? v : null;
|
|
61
|
+
}
|
|
62
|
+
function sortWriters(writers) {
|
|
63
|
+
return [...writers].sort((a, b) => (a.writer_key_id < b.writer_key_id ? -1 : a.writer_key_id > b.writer_key_id ? 1 : 0));
|
|
64
|
+
}
|
|
65
|
+
function writersArraysEqual(a, b) {
|
|
66
|
+
return a.length === b.length && a.every((w, i) => w.writer_key_id === b[i].writer_key_id && w.signing_pubkey === b[i].signing_pubkey);
|
|
67
|
+
}
|
|
68
|
+
function nextVersionHex16(hex16) {
|
|
69
|
+
return (BigInt("0x" + hex16) + 1n).toString(16).padStart(16, "0");
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* `vk_` fingerprint of a base64url-encoded Ed25519 public key, or `null` for
|
|
73
|
+
* anything that doesn't decode as a canonical 32-byte base64url scalar —
|
|
74
|
+
* mirrors the gateway's `writerKeyIdOf` (never throws on a malformed key).
|
|
75
|
+
*/
|
|
76
|
+
export function writerKeyIdOf(signingPubkeyB64u) {
|
|
77
|
+
if (!GITVAULT_B64U_32_RE.test(signingPubkeyB64u) || !isCanonicalBase64url(signingPubkeyB64u))
|
|
78
|
+
return null;
|
|
79
|
+
return vkFingerprint(fromBase64url(signingPubkeyB64u));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Strict Ed25519 verification of a detached (b64u-encoded) signature over
|
|
83
|
+
* `message`, given a b64u-encoded public key. Never throws — a malformed
|
|
84
|
+
* scalar is simply `false`, matching `ed25519VerifyStrict`'s own contract.
|
|
85
|
+
*/
|
|
86
|
+
function verifyDetachedB64u(publicKeyB64u, signatureB64u, message) {
|
|
87
|
+
if (!GITVAULT_B64U_32_RE.test(publicKeyB64u) || !isCanonicalBase64url(publicKeyB64u))
|
|
88
|
+
return false;
|
|
89
|
+
if (!GITVAULT_B64U_64_RE.test(signatureB64u) || !isCanonicalBase64url(signatureB64u))
|
|
90
|
+
return false;
|
|
91
|
+
return ed25519VerifyStrict(fromBase64url(signatureB64u), message, fromBase64url(publicKeyB64u));
|
|
92
|
+
}
|
|
93
|
+
/** protocol §4.15: writer_set_sha256 = SHA-256(JCS({format, repo_id, version, writers})). */
|
|
94
|
+
export function writerSetSha256(repoId, version, writers) {
|
|
95
|
+
const writersJson = writers.map((w) => ({ writer_key_id: w.writer_key_id, signing_pubkey: w.signing_pubkey }));
|
|
96
|
+
return sha256Hex(jcs({ format: WRITER_SET_FORMAT, repo_id: repoId, version, writers: writersJson }));
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* protocol §4.15: the version-0 singleton, derived from `creator_signing_pubkey`
|
|
100
|
+
* (see the module doc for why this diverges from reading a `writer_key_id`
|
|
101
|
+
* field directly).
|
|
102
|
+
*/
|
|
103
|
+
export function initialWriterState(repoId, genesis) {
|
|
104
|
+
const writerKeyId = writerKeyIdOf(genesis.creator_signing_pubkey);
|
|
105
|
+
if (writerKeyId === null) {
|
|
106
|
+
throw new LocalError("genesis.creator_signing_pubkey is not a canonical base64url Ed25519 public key", "computing the vault's initial writer state", { code: "GITVAULT_BAD_GENESIS" });
|
|
107
|
+
}
|
|
108
|
+
const writers = [{ writer_key_id: writerKeyId, signing_pubkey: genesis.creator_signing_pubkey }];
|
|
109
|
+
return {
|
|
110
|
+
version: "0000000000000000",
|
|
111
|
+
writers,
|
|
112
|
+
sha256: writerSetSha256(repoId, "0000000000000000", writers),
|
|
113
|
+
burnedWriterKeyIds: new Set(),
|
|
114
|
+
consumedHandoffIds: new Set(),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* protocol §4.16: apply an ALREADY-ADMITTED `add_writer_key` transition.
|
|
119
|
+
* Caller MUST have validated it first (`validateAddWriterKeyPayload`) — this
|
|
120
|
+
* function performs no checks, it only advances state.
|
|
121
|
+
*/
|
|
122
|
+
/**
|
|
123
|
+
* gitvault-multi-writer (task 5.6) — builds a well-formed `handoff`-door
|
|
124
|
+
* `add_writer_key` payload (schema `r402s.add-writer-key/v1`) from a
|
|
125
|
+
* predecessor writer-set pin and the claimant's own key — the pure
|
|
126
|
+
* assembly step `GitvaultVault.submitWriterActivationHead` delegates to,
|
|
127
|
+
* kept separate so it can be unit-tested directly against
|
|
128
|
+
* {@link validateAddWriterKeyPayload} without a full vault/keystore/git
|
|
129
|
+
* harness. `predecessorPin` needs only `{version, sha256, writers}` — the
|
|
130
|
+
* caller's persisted `writer_set_pin` shape already matches, no
|
|
131
|
+
* `WriterChainState` (with its Sets) is required to build an OUTGOING
|
|
132
|
+
* payload; only to VALIDATE an incoming one.
|
|
133
|
+
*/
|
|
134
|
+
export function buildAddWriterKeyActivationPayload(repoId, predecessorPin, addedWriter, handoffId, grant, acceptance) {
|
|
135
|
+
const predecessorState = { version: predecessorPin.version, writers: predecessorPin.writers, sha256: predecessorPin.sha256, burnedWriterKeyIds: new Set(), consumedHandoffIds: new Set() };
|
|
136
|
+
const nextState = applyAddWriterKey(repoId, predecessorState, { writer_key_id: addedWriter.writer_key_id, signing_pubkey: addedWriter.signing_pubkey }, handoffId);
|
|
137
|
+
return {
|
|
138
|
+
schema: "r402s.add-writer-key/v1",
|
|
139
|
+
repo_id: repoId,
|
|
140
|
+
base_writer_set: { version: predecessorPin.version, sha256: predecessorPin.sha256 },
|
|
141
|
+
next_writer_set: { version: nextState.version, writers: [...nextState.writers], sha256: nextState.sha256 },
|
|
142
|
+
added_writer: { writer_key_id: addedWriter.writer_key_id, signing_pubkey: addedWriter.signing_pubkey, principal_id: addedWriter.principal_id },
|
|
143
|
+
authorization: { kind: "handoff", grant, acceptance },
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* gitvault-multi-writer (task 5.7) — builds a well-formed `writer`-door
|
|
148
|
+
* `add_writer_key` payload from a predecessor writer-set pin and the
|
|
149
|
+
* candidate's own published signing key. Unlike {@link
|
|
150
|
+
* buildAddWriterKeyActivationPayload} (the handoff door), this authorization
|
|
151
|
+
* carries no grant/acceptance — `validateAddWriterKeyPayload`'s `"writer"`
|
|
152
|
+
* branch licenses it purely by the CARRYING HEAD's own signer already being
|
|
153
|
+
* an active writer (checked at admission time, both client-side replay and
|
|
154
|
+
* gateway-side `checkTransitionAdmissible`), so the acting writer's identity
|
|
155
|
+
* never appears IN the payload itself, only in the head that carries it.
|
|
156
|
+
*/
|
|
157
|
+
export function buildWriterDoorAddWriterKeyPayload(repoId, predecessorPin, addedWriter) {
|
|
158
|
+
const predecessorState = { version: predecessorPin.version, writers: predecessorPin.writers, sha256: predecessorPin.sha256, burnedWriterKeyIds: new Set(), consumedHandoffIds: new Set() };
|
|
159
|
+
const nextState = applyAddWriterKey(repoId, predecessorState, { writer_key_id: addedWriter.writer_key_id, signing_pubkey: addedWriter.signing_pubkey }, null);
|
|
160
|
+
return {
|
|
161
|
+
schema: "r402s.add-writer-key/v1",
|
|
162
|
+
repo_id: repoId,
|
|
163
|
+
base_writer_set: { version: predecessorPin.version, sha256: predecessorPin.sha256 },
|
|
164
|
+
next_writer_set: { version: nextState.version, writers: [...nextState.writers], sha256: nextState.sha256 },
|
|
165
|
+
added_writer: { writer_key_id: addedWriter.writer_key_id, signing_pubkey: addedWriter.signing_pubkey, principal_id: addedWriter.principal_id },
|
|
166
|
+
authorization: { kind: "writer" },
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
export function applyAddWriterKey(repoId, state, addedWriter, consumedHandoffId) {
|
|
170
|
+
const writers = sortWriters([...state.writers, addedWriter]);
|
|
171
|
+
const version = nextVersionHex16(state.version);
|
|
172
|
+
return {
|
|
173
|
+
version,
|
|
174
|
+
writers,
|
|
175
|
+
sha256: writerSetSha256(repoId, version, writers),
|
|
176
|
+
burnedWriterKeyIds: state.burnedWriterKeyIds,
|
|
177
|
+
consumedHandoffIds: consumedHandoffId === null ? state.consumedHandoffIds : new Set([...state.consumedHandoffIds, consumedHandoffId]),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* protocol §4.18: apply an ALREADY-ADMITTED `rotate_epoch{writer_set_update}`.
|
|
182
|
+
* Caller MUST have validated it first (`validateWriterSetUpdate`). `writers`
|
|
183
|
+
* MAY be empty — the explicit sole-writer `writer_key_revoked` read-only
|
|
184
|
+
* terminal (D228) is a legal resulting state, not an error at this layer.
|
|
185
|
+
*/
|
|
186
|
+
export function applyWriterSetUpdate(repoId, state, removedWriterKeyIds) {
|
|
187
|
+
const removed = new Set(removedWriterKeyIds);
|
|
188
|
+
const writers = sortWriters(state.writers.filter((w) => !removed.has(w.writer_key_id)));
|
|
189
|
+
const version = nextVersionHex16(state.version);
|
|
190
|
+
return {
|
|
191
|
+
version,
|
|
192
|
+
writers,
|
|
193
|
+
sha256: writerSetSha256(repoId, version, writers),
|
|
194
|
+
burnedWriterKeyIds: new Set([...state.burnedWriterKeyIds, ...removed]),
|
|
195
|
+
consumedHandoffIds: state.consumedHandoffIds,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* The FIRST, ordinary-case lookup (protocol §5A step 1): is this head's own
|
|
200
|
+
* `writer_key_id` already active in the predecessor writer state? A null
|
|
201
|
+
* result does not by itself mean refusal — the caller still checks for a
|
|
202
|
+
* qualifying `add_writer_key{"handoff"}` transition naming exactly this key
|
|
203
|
+
* before concluding `GITVAULT_WRITER_NOT_ADMITTED`.
|
|
204
|
+
*/
|
|
205
|
+
export function resolveActiveWriter(state, headWriterKeyId) {
|
|
206
|
+
return state.writers.find((w) => w.writer_key_id === headWriterKeyId) ?? null;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* The FULL cryptographic + structural validation of an `add_writer_key`
|
|
210
|
+
* payload (protocol §4.16/§4.17), given the writer state at the PREDECESSOR
|
|
211
|
+
* generation and the carrying head's own `writer_key_id`. Does NOT check
|
|
212
|
+
* `authorization.kind:"writer"`'s org-membership eligibility (active
|
|
213
|
+
* membership >= developer, directory possession-verification) — that is
|
|
214
|
+
* gateway-only, live-state-dependent, and re-checked under the admission
|
|
215
|
+
* fence server-side; a client validating its OWN candidate transition before
|
|
216
|
+
* submission relies on the gateway's fence-time re-check as the backstop.
|
|
217
|
+
*/
|
|
218
|
+
export function validateAddWriterKeyPayload(repoId, predecessorState, payload, headWriterKeyId) {
|
|
219
|
+
if (payload.base_writer_set.version !== predecessorState.version || payload.base_writer_set.sha256 !== predecessorState.sha256) {
|
|
220
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "base_writer_set does not match the writer state at the predecessor generation" };
|
|
221
|
+
}
|
|
222
|
+
const addedKeyId = writerKeyIdOf(payload.added_writer.signing_pubkey);
|
|
223
|
+
if (addedKeyId === null || addedKeyId !== payload.added_writer.writer_key_id) {
|
|
224
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "added_writer.writer_key_id does not derive from added_writer.signing_pubkey" };
|
|
225
|
+
}
|
|
226
|
+
if (predecessorState.burnedWriterKeyIds.has(addedKeyId)) {
|
|
227
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: `writer_key_id ${addedKeyId} was permanently removed and can never be re-added` };
|
|
228
|
+
}
|
|
229
|
+
if (predecessorState.writers.some((w) => w.writer_key_id === addedKeyId)) {
|
|
230
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: `writer_key_id ${addedKeyId} is already an active writer` };
|
|
231
|
+
}
|
|
232
|
+
if (predecessorState.writers.length >= MAX_VAULT_WRITERS) {
|
|
233
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: `this vault already has ${MAX_VAULT_WRITERS} active writers, the protocol maximum (MAX_VAULT_WRITERS)` };
|
|
234
|
+
}
|
|
235
|
+
const expectedNextWriters = sortWriters([
|
|
236
|
+
...predecessorState.writers,
|
|
237
|
+
{ writer_key_id: addedKeyId, signing_pubkey: payload.added_writer.signing_pubkey },
|
|
238
|
+
]);
|
|
239
|
+
const expectedNextVersion = nextVersionHex16(predecessorState.version);
|
|
240
|
+
const expectedNextSha = writerSetSha256(repoId, expectedNextVersion, expectedNextWriters);
|
|
241
|
+
if (payload.next_writer_set.version !== expectedNextVersion ||
|
|
242
|
+
payload.next_writer_set.sha256 !== expectedNextSha ||
|
|
243
|
+
!writersArraysEqual(payload.next_writer_set.writers, expectedNextWriters)) {
|
|
244
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "next_writer_set is not exactly base_writer_set plus added_writer" };
|
|
245
|
+
}
|
|
246
|
+
if (payload.authorization.kind === "writer") {
|
|
247
|
+
if (headWriterKeyId === addedKeyId) {
|
|
248
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: 'authorization.kind:"writer" cannot be self-signed by the added key' };
|
|
249
|
+
}
|
|
250
|
+
if (!predecessorState.writers.some((w) => w.writer_key_id === headWriterKeyId)) {
|
|
251
|
+
return { ok: false, code: "GITVAULT_WRITER_NOT_ADMITTED", detail: "the carrying head's signer is not an active writer at the predecessor generation" };
|
|
252
|
+
}
|
|
253
|
+
return { ok: true };
|
|
254
|
+
}
|
|
255
|
+
// authorization.kind === "handoff"
|
|
256
|
+
if (headWriterKeyId !== addedKeyId) {
|
|
257
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "a handoff activation head must be signed by the added key itself" };
|
|
258
|
+
}
|
|
259
|
+
const { grant, acceptance } = payload.authorization;
|
|
260
|
+
const grantorKeyId = asStr(grant.grantor_writer_key_id);
|
|
261
|
+
const grantorEntry = grantorKeyId === null ? null : (predecessorState.writers.find((w) => w.writer_key_id === grantorKeyId) ?? null);
|
|
262
|
+
if (grantorEntry === null) {
|
|
263
|
+
return { ok: false, code: "HANDOFF_KEY_REVOKED", detail: "grantor_not_active" };
|
|
264
|
+
}
|
|
265
|
+
if (asStr(grant.object_kind) !== "writer_admission_grant") {
|
|
266
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "writer_admission_grant.object_kind is not writer_admission_grant" };
|
|
267
|
+
}
|
|
268
|
+
const grantSignature = asStr(grant.signature);
|
|
269
|
+
const grantPreimage = signaturePreimage("writer_admission_grant", gitvaultWithoutSignature(grant));
|
|
270
|
+
if (grantSignature === null || !verifyDetachedB64u(grantorEntry.signing_pubkey, grantSignature, grantPreimage)) {
|
|
271
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "writer_admission_grant signature does not verify under the grantor's writer key" };
|
|
272
|
+
}
|
|
273
|
+
const statementRaw = acceptance.statement;
|
|
274
|
+
if (typeof statementRaw !== "object" || statementRaw === null || Array.isArray(statementRaw)) {
|
|
275
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "writer_acceptance.statement is missing or malformed" };
|
|
276
|
+
}
|
|
277
|
+
const statement = statementRaw;
|
|
278
|
+
const statementPreimage = signaturePreimage("handoff-writer-accept/v1", statement);
|
|
279
|
+
const handoffAdmissionPubkey = asStr(grant.handoff_admission_pubkey);
|
|
280
|
+
const acceptanceSignature = asStr(acceptance.acceptance_signature);
|
|
281
|
+
if (handoffAdmissionPubkey === null ||
|
|
282
|
+
acceptanceSignature === null ||
|
|
283
|
+
!verifyDetachedB64u(handoffAdmissionPubkey, acceptanceSignature, statementPreimage)) {
|
|
284
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "writer_acceptance.acceptance_signature does not verify under the grant's admission key" };
|
|
285
|
+
}
|
|
286
|
+
const possessionSignature = asStr(acceptance.possession_signature);
|
|
287
|
+
if (possessionSignature === null ||
|
|
288
|
+
!verifyDetachedB64u(payload.added_writer.signing_pubkey, possessionSignature, statementPreimage)) {
|
|
289
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "writer_acceptance.possession_signature does not verify under the added writer's own key" };
|
|
290
|
+
}
|
|
291
|
+
const handoffId = asStr(grant.handoff_id);
|
|
292
|
+
if (handoffId === null || handoffId !== asStr(statement.handoff_id)) {
|
|
293
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "grant.handoff_id != acceptance.statement.handoff_id" };
|
|
294
|
+
}
|
|
295
|
+
if (asStr(grant.auth_hash) !== asStr(statement.auth_hash)) {
|
|
296
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "grant.auth_hash != acceptance.statement.auth_hash" };
|
|
297
|
+
}
|
|
298
|
+
if (asStr(statement.writer_key_id) !== addedKeyId || asStr(statement.signing_pubkey) !== payload.added_writer.signing_pubkey) {
|
|
299
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "acceptance.statement writer identity does not match added_writer" };
|
|
300
|
+
}
|
|
301
|
+
if (predecessorState.consumedHandoffIds.has(handoffId)) {
|
|
302
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: `handoff_id ${handoffId} has already been consumed in this vault's writer history` };
|
|
303
|
+
}
|
|
304
|
+
return { ok: true };
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* The FULL cryptographic + structural validation of a `rotate_epoch`
|
|
308
|
+
* transition's `writer_set_update` field (protocol §4.18, D227), given the
|
|
309
|
+
* writer state at the PREDECESSOR generation, the carrying head's own
|
|
310
|
+
* `writer_key_id`, and the caller's own belief about which writer keys are
|
|
311
|
+
* due for removal (`gatewayBlockedWriterKeyIds` — for a client building a
|
|
312
|
+
* CANDIDATE rotation this is `state read (blocked set)`; the gateway's own
|
|
313
|
+
* fence-time re-check is the source of truth at admission). `allowEmptyResult`
|
|
314
|
+
* is true ONLY for the explicit, owner+step-up, sole remaining writer
|
|
315
|
+
* `writer_key_revoked` removal (D228); every other call site passes `false`.
|
|
316
|
+
*/
|
|
317
|
+
export function validateWriterSetUpdate(repoId, predecessorState, update, headWriterKeyId, gatewayBlockedWriterKeyIds, allowEmptyResult) {
|
|
318
|
+
if (update.base_version !== predecessorState.version || update.base_sha256 !== predecessorState.sha256) {
|
|
319
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "writer_set_update base does not match the writer state at the predecessor generation" };
|
|
320
|
+
}
|
|
321
|
+
const removedIds = new Set(update.removed.map((r) => r.writer_key_id));
|
|
322
|
+
const blockedSorted = [...gatewayBlockedWriterKeyIds].sort();
|
|
323
|
+
const removedSorted = [...removedIds].sort();
|
|
324
|
+
const exactMatch = blockedSorted.length === removedSorted.length && blockedSorted.every((id, i) => id === removedSorted[i]);
|
|
325
|
+
if (!exactMatch) {
|
|
326
|
+
return { ok: false, code: "RECIPIENT_SET_MISMATCH", detail: "writer_set_update.removed does not equal exactly the blocked writer key set" };
|
|
327
|
+
}
|
|
328
|
+
const expectedWriters = sortWriters(predecessorState.writers.filter((w) => !removedIds.has(w.writer_key_id)));
|
|
329
|
+
if (!writersArraysEqual(update.writers, expectedWriters)) {
|
|
330
|
+
return { ok: false, code: "RECIPIENT_SET_MISMATCH", detail: "writer_set_update.writers is not base_writer_set minus exactly the removed set" };
|
|
331
|
+
}
|
|
332
|
+
if (expectedWriters.length === 0 && !allowEmptyResult) {
|
|
333
|
+
return { ok: false, code: "EPOCH_ROTATION_WOULD_LEAVE_VAULT_UNCOVERED", detail: "this rotation would leave the vault with zero writers" };
|
|
334
|
+
}
|
|
335
|
+
if (expectedWriters.length > 0 && !expectedWriters.some((w) => w.writer_key_id === headWriterKeyId)) {
|
|
336
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "the rotation head's own signer must remain in the next writer set" };
|
|
337
|
+
}
|
|
338
|
+
const expectedNextVersion = nextVersionHex16(predecessorState.version);
|
|
339
|
+
const expectedNextSha = writerSetSha256(repoId, expectedNextVersion, expectedWriters);
|
|
340
|
+
if (update.next_version !== expectedNextVersion || update.next_sha256 !== expectedNextSha) {
|
|
341
|
+
return { ok: false, code: "VALIDATION_FAILED", detail: "writer_set_update next commitment does not match the recomputed removal" };
|
|
342
|
+
}
|
|
343
|
+
return { ok: true };
|
|
344
|
+
}
|
|
345
|
+
export function replayWriterState(repoId, genesis, transitions) {
|
|
346
|
+
let state = initialWriterState(repoId, genesis);
|
|
347
|
+
for (const t of transitions) {
|
|
348
|
+
state =
|
|
349
|
+
t.kind === "add_writer_key"
|
|
350
|
+
? applyAddWriterKey(repoId, state, t.addedWriter, t.consumedHandoffId)
|
|
351
|
+
: applyWriterSetUpdate(repoId, state, t.removedWriterKeyIds);
|
|
352
|
+
}
|
|
353
|
+
return state;
|
|
354
|
+
}
|
|
355
|
+
/** protocol §4.15: `MAX_VAULT_WRITERS`. A writer-changing transition producing more active writers than this is refused. */
|
|
356
|
+
export const MAX_VAULT_WRITERS = 64;
|
|
357
|
+
//# sourceMappingURL=gitvault-writer-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitvault-writer-state.js","sourceRoot":"","sources":["../../src/node/gitvault-writer-state.ts"],"names":[],"mappings":"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"}
|
package/sdk/dist/node/index.d.ts
CHANGED
|
@@ -118,7 +118,7 @@ export { GitvaultKeystore, getGitvaultKeystoreRoot, readFileNoFollow, writeFileA
|
|
|
118
118
|
export type { GitvaultAuditEntry, GitvaultAuditEvent, GitvaultHeadPin, GitvaultIdentityFile, GitvaultKeystoreOptions, GitvaultKeystoreState, GitvaultLockOptions, GitvaultPermissionFinding, GitvaultRepoFile, } from "./gitvault-keystore.js";
|
|
119
119
|
export { GITVAULT_CREATION_STAGES, GitvaultCreation, createGitvault, findResumableGitvaultJournal, findResumablePushToCreateJournal, gitvaultDoctorRecoveryText, gitvaultJournalPath, listIncompleteGitvaultJournals, readGitvaultJournal, } from "./gitvault-creation-journal.js";
|
|
120
120
|
export type { GitvaultAdmitGenesisRequest, GitvaultAdmitGenesisResult, GitvaultAllocateRequest, GitvaultCreationJournal, GitvaultCreationOptions, GitvaultCreationResult, GitvaultCreationStage, GitvaultCreationTransport, GitvaultDoctorRecoveryText, GitvaultJournaledObject, GitvaultObjectReceipt, GitvaultPushToCreateAddress, GitvaultPutObjectRequest, } from "./gitvault-creation-journal.js";
|
|
121
|
-
export { GITVAULT_DEPLOY_REF, GITVAULT_HANDOFF_SENSITIVE_DENYLIST, GITVAULT_MAX_GIT_OBJECT_BYTES, GITVAULT_MIN_GIT_VERSION, HARDENED_GIT_ARGV_PREFIX, captureHandoffSnapshot, captureSnapshot, capturedSetDigest, capturedSetUnchanged, deriveCapturedSet, detectActiveFilters, diffCapturedSets, discoverGlobalExcludes, findOversizeObjects, gitvaultCommitLine, globMatchesGitPath, hardenedGit, hardenedGitEnv, hasObject, inspectRepository, isAncestor, isHandoffSensitivePath, materializeSnapshot, parseGitConfigAsData, probeGitVersion, resolveGitInvocationRepo, snapshotCommitment, } from "./gitvault-snapshot.js";
|
|
121
|
+
export { GITVAULT_DEPLOY_REF, GITVAULT_HANDOFF_SENSITIVE_DENYLIST, GITVAULT_MAX_GIT_OBJECT_BYTES, GITVAULT_MIN_GIT_VERSION, HARDENED_GIT_ARGV_PREFIX, captureHandoffSnapshot, captureSnapshot, capturedSetDigest, capturedSetUnchanged, deriveCapturedSet, detectActiveFilters, diffCapturedSets, discoverGlobalExcludes, findOversizeObjects, gitvaultCommitLine, globMatchesGitPath, hardenedGit, hardenedGitEnv, run402PassthroughEnv, hasObject, inspectRepository, isAncestor, isHandoffSensitivePath, materializeSnapshot, parseGitConfigAsData, probeGitVersion, resolveGitInvocationRepo, snapshotCommitment, } from "./gitvault-snapshot.js";
|
|
122
122
|
export type { GitConfigDiscoveryEnv, GitInvocationRepo, GitvaultCapturedFile, GitvaultCapturedSetDrift, GitvaultHandoffCaptureOptions, GitvaultHandoffCaptureStats, GitvaultHandoffSnapshot, GitvaultRepositoryInspection, GitvaultRepositoryRefusalCode, GitvaultSnapshot, GitvaultSnapshotOptions, GitvaultSnapshotRefusalPath, GlobalExcludesDiscovery, GlobalExcludesRefusal, HardenedGitOptions, HardenedGitResult, ParsedGitConfigEntry, } from "./gitvault-snapshot.js";
|
|
123
123
|
export { GITVAULT_INLINE_UPLOAD_MAX_OBJECT_BYTES, GITVAULT_INLINE_UPLOAD_MAX_REQUEST_BYTES, GITVAULT_MAX_CANONICAL_REFS, GITVAULT_MAX_CHECKPOINT_PACKS, GITVAULT_MAX_CHECKPOINT_TOTAL_STORED_BYTES, GITVAULT_MAX_HEADS_PER_LISTING_PAGE, GITVAULT_MAX_REF_STATE_OBJECT_BYTES, GITVAULT_MAX_REF_UPDATES_PER_TRANSACTION, GITVAULT_MAX_REPAIR_ADDED_ROOTS, GITVAULT_MAX_RETENTION_ROOT_ENTRIES, GITVAULT_MAX_WAL_RECEIPTS_PER_HEAD, GITVAULT_MULTI_OBJECT_PACK_TARGET_BYTES, GITVAULT_PUSH_CONFLICT_RETRIES, GITVAULT_R402_REF_NAMESPACE, GITVAULT_RETAIN_REF_PREFIX, GITVAULT_RETENTION_MIN_DAYS, GITVAULT_VERIFICATION_BUDGET_HEADS, GitvaultVault, assertNoTransition, assertRefMapCardinality, bigIntToGeneration, captureBinding, checkChainLink, checkClaimSetEquality, checkGenerationRegression, checkOpenBinding, compareRoots, createGitvaultHttpTransport, deployRefTransaction, effectiveAdmittedAt, evaluateRefTransaction, evolveRetentionRoots, generationToBigInt, gitvaultInlineUploadEligible, gitvaultPaths, gitvaultRetainedRefName, isRootEligibleForRemoval, nextGeneration, nextListingRequest, gitvaultLedgerId, gitvaultManifestEntry, gitvaultWireRefForPath, openBindingDigest, reconcileRetainedTipRefs, validateHeadsListingRequest, verifyHeadsListingPage, readGitvaultRestoreMarker, GITVAULT_AUTO_GC_GENERATIONS_DEFAULT, readGitvaultAutoGcThreshold, writeGitvaultAutoGcThreshold, } from "./gitvault-publication.js";
|
|
124
124
|
export type { GitvaultAdmitHeadRequest, GitvaultAdmitHeadResult, GitvaultBuiltCheckpoint, GitvaultChainLinkInput, GitvaultCutoffOptions, GitvaultDroppedTip, GitvaultEvaluateRefTransactionOptions, GitvaultEvolveRootsOptions, GitvaultHttpTransportOptions, GitvaultListingProgress, GitvaultMaintenanceLease, GitvaultMaintenanceLeaseRequest, GitvaultObjectReadRequest, GitvaultResourceBinding, GitvaultVaultRecord, GitvaultVaultState, GitvaultWireRef, GitvaultMaterializedState, GitvaultOpenBindingRecord, GitvaultPublishResult, GitvaultPushOptions, GitvaultPushPlan, GitvaultRefMap, GitvaultRefTransactionEvaluation, GitvaultRefUpdateFailure, GitvaultRestoreMarker, GitvaultRetainedRefsReconcileResult, GitvaultRetentionCutoffIssued, GitvaultTransport, GitvaultUploadObject, GitvaultUploadReceipt, GitvaultVaultOptions, GitvaultVerifiedState, GitvaultCompactionGrant, } from "./gitvault-publication.js";
|
|
@@ -126,6 +126,10 @@ export { GITVAULT_DEPLOY_OUTCOMES, SNAPSHOT_MOVED_DURING_DEPLOY, checkActivation
|
|
|
126
126
|
export type { GitvaultCaptureReceiptMatch, GitvaultDeployError, GitvaultDeployLane, GitvaultDeployLaneCommitInput, GitvaultDeployLanePlan, GitvaultDeployLanePlanInput, GitvaultDeployNextAction, GitvaultDeployOptions, GitvaultDeployOutcome, GitvaultDeployResult, GitvaultOverrideDrainReport, GitvaultOverrideJournal, GitvaultSnapshotMovedDetails, } from "./gitvault-deploy.js";
|
|
127
127
|
export { HANDOFF_ENVELOPE_KIND, HANDOFF_KEY_PREFIXES, assembleHandoffKey, assertHandoffNoteHasNoSecret, deriveHandoffSecrets, isKygitHandoffNote, openHandoffEnvelope, parseHandoffKey, scanHandoffNoteForSecrets, sealHandoffEnvelope, uuidToBytes, } from "./gitvault-handoff.js";
|
|
128
128
|
export type { HandoffEnvelopePayload, HandoffKeyParts, HandoffKeyPrefixEntry, HandoffNoteSecretFinding, HandoffSecrets, KygitHandoffNote, KygitHandoffNoteCapture, } from "./gitvault-handoff.js";
|
|
129
|
+
export { HANDOFF_WRITER_ACCEPT_DOMAIN, buildWriterAcceptance, buildWriterAdmissionGrant, deriveWriterAdmissionSeed, verifyWriterAcceptance, verifyWriterAdmissionGrant, } from "./gitvault-handoff.js";
|
|
130
|
+
export type { BuildWriterAcceptanceInput, BuildWriterAdmissionGrantInput, GitvaultWriterMintedRole, HandoffWriterAcceptStatement, WriterAcceptance, WriterAdmissionGrant, } from "./gitvault-handoff.js";
|
|
131
|
+
export { MAX_VAULT_WRITERS, ORG_ROLE_RANK, WRITER_ELIGIBLE_ROLE_RANK, applyAddWriterKey, applyWriterSetUpdate, buildAddWriterKeyActivationPayload, buildWriterDoorAddWriterKeyPayload, initialWriterState, meetsWriterEligibleRole, predictMintedRole, replayWriterState, resolveActiveWriter, validateAddWriterKeyPayload, validateWriterSetUpdate, writerKeyIdOf, writerSetSha256, } from "./gitvault-writer-state.js";
|
|
132
|
+
export type { AddWriterKeyPayload, AdmittedWriterTransition, WriterChainState, WriterKeyEntry, WriterSetUpdatePayload, WriterStateRefusalCode, WriterStateVerdict, } from "./gitvault-writer-state.js";
|
|
129
133
|
export { applyHandoffCheckpoint, cloneGitvaultRemote, readGitCommitMessage, resolveResumeTargetDir } from "./gitvault-restore.js";
|
|
130
134
|
export type { GitvaultHandoffRestoreOptions, GitvaultHandoffRestoreResult } from "./gitvault-restore.js";
|
|
131
135
|
export { openOrCreateGitvault } from "./gitvault-open-or-create.js";
|