run402 4.24.0 → 4.25.0
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 +6 -6
- package/git-remote-run402.mjs +270 -0
- package/lib/command-manifest.mjs +11 -1
- package/lib/credentials.mjs +4 -0
- package/lib/domains.mjs +0 -14
- package/lib/gitvault.mjs +370 -0
- package/lib/init.mjs +143 -1
- package/lib/pay.test.mjs +0 -4
- package/package.json +8 -2
- package/sdk/dist/index.d.ts +20 -3
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +22 -3
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/namespaces/admin.d.ts +0 -5
- package/sdk/dist/namespaces/admin.d.ts.map +1 -1
- package/sdk/dist/namespaces/admin.js +0 -9
- package/sdk/dist/namespaces/admin.js.map +1 -1
- package/sdk/dist/namespaces/assets.d.ts +1 -20
- package/sdk/dist/namespaces/assets.d.ts.map +1 -1
- package/sdk/dist/namespaces/assets.js +0 -27
- package/sdk/dist/namespaces/assets.js.map +1 -1
- package/sdk/dist/namespaces/auth.js +1 -1
- package/sdk/dist/namespaces/auth.js.map +1 -1
- package/sdk/dist/namespaces/domains.d.ts +0 -19
- package/sdk/dist/namespaces/domains.d.ts.map +1 -1
- package/sdk/dist/namespaces/domains.js +0 -19
- package/sdk/dist/namespaces/domains.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.crypto.d.ts +319 -0
- package/sdk/dist/namespaces/gitvault.crypto.d.ts.map +1 -0
- package/sdk/dist/namespaces/gitvault.crypto.js +690 -0
- package/sdk/dist/namespaces/gitvault.crypto.js.map +1 -0
- package/sdk/dist/namespaces/gitvault.d.ts +473 -0
- package/sdk/dist/namespaces/gitvault.d.ts.map +1 -0
- package/sdk/dist/namespaces/gitvault.js +714 -0
- package/sdk/dist/namespaces/gitvault.js.map +1 -0
- package/sdk/dist/namespaces/gitvault.types.d.ts +481 -0
- package/sdk/dist/namespaces/gitvault.types.d.ts.map +1 -0
- package/sdk/dist/namespaces/gitvault.types.js +19 -0
- package/sdk/dist/namespaces/gitvault.types.js.map +1 -0
- package/sdk/dist/namespaces/org.d.ts +1 -3
- package/sdk/dist/namespaces/org.d.ts.map +1 -1
- package/sdk/dist/namespaces/org.js +6 -10
- package/sdk/dist/namespaces/org.js.map +1 -1
- package/sdk/dist/namespaces/pay.d.ts +0 -8
- package/sdk/dist/namespaces/pay.d.ts.map +1 -1
- package/sdk/dist/namespaces/pay.js.map +1 -1
- package/sdk/dist/namespaces/projects.d.ts +2 -2
- package/sdk/dist/namespaces/projects.d.ts.map +1 -1
- package/sdk/dist/namespaces/projects.js +4 -12
- package/sdk/dist/namespaces/projects.js.map +1 -1
- package/sdk/dist/namespaces/secrets.d.ts +0 -2
- package/sdk/dist/namespaces/secrets.d.ts.map +1 -1
- package/sdk/dist/namespaces/secrets.js +3 -10
- package/sdk/dist/namespaces/secrets.js.map +1 -1
- package/sdk/dist/namespaces/subdomains.d.ts +0 -2
- package/sdk/dist/namespaces/subdomains.d.ts.map +1 -1
- package/sdk/dist/namespaces/subdomains.js +5 -16
- package/sdk/dist/namespaces/subdomains.js.map +1 -1
- package/sdk/dist/namespaces/transfers.d.ts +0 -2
- package/sdk/dist/namespaces/transfers.d.ts.map +1 -1
- package/sdk/dist/namespaces/transfers.js +8 -10
- package/sdk/dist/namespaces/transfers.js.map +1 -1
- package/sdk/dist/namespaces/wallets.d.ts +0 -12
- package/sdk/dist/namespaces/wallets.d.ts.map +1 -1
- package/sdk/dist/namespaces/wallets.js +0 -14
- package/sdk/dist/namespaces/wallets.js.map +1 -1
- package/sdk/dist/node/gitvault-creation-journal.d.ts +222 -0
- package/sdk/dist/node/gitvault-creation-journal.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-creation-journal.js +365 -0
- package/sdk/dist/node/gitvault-creation-journal.js.map +1 -0
- package/sdk/dist/node/gitvault-deploy.d.ts +211 -0
- package/sdk/dist/node/gitvault-deploy.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-deploy.js +292 -0
- package/sdk/dist/node/gitvault-deploy.js.map +1 -0
- package/sdk/dist/node/gitvault-keystore.d.ts +207 -0
- package/sdk/dist/node/gitvault-keystore.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-keystore.js +529 -0
- package/sdk/dist/node/gitvault-keystore.js.map +1 -0
- package/sdk/dist/node/gitvault-prune.d.ts +341 -0
- package/sdk/dist/node/gitvault-prune.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-prune.js +410 -0
- package/sdk/dist/node/gitvault-prune.js.map +1 -0
- package/sdk/dist/node/gitvault-publication.d.ts +730 -0
- package/sdk/dist/node/gitvault-publication.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-publication.js +1475 -0
- package/sdk/dist/node/gitvault-publication.js.map +1 -0
- package/sdk/dist/node/gitvault-snapshot.d.ts +190 -0
- package/sdk/dist/node/gitvault-snapshot.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-snapshot.js +505 -0
- package/sdk/dist/node/gitvault-snapshot.js.map +1 -0
- package/sdk/dist/node/index.d.ts +11 -0
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +9 -0
- 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 +0 -4
- package/sdk/dist/node/paid-fetch.js.map +1 -1
- package/sdk/dist/node/sites-node.d.ts +1 -8
- package/sdk/dist/node/sites-node.d.ts.map +1 -1
- package/sdk/dist/node/sites-node.js +1 -7
- package/sdk/dist/node/sites-node.js.map +1 -1
- package/sdk/dist/scoped.d.ts +4 -35
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +9 -74
- package/sdk/dist/scoped.js.map +1 -1
- package/lib/sender-domain.mjs +0 -36
- package/sdk/dist/deprecate.d.ts +0 -23
- package/sdk/dist/deprecate.d.ts.map +0 -1
- package/sdk/dist/deprecate.js +0 -42
- package/sdk/dist/deprecate.js.map +0 -1
- package/sdk/dist/namespaces/sender-domain.d.ts +0 -47
- package/sdk/dist/namespaces/sender-domain.d.ts.map +0 -1
- package/sdk/dist/namespaces/sender-domain.js +0 -45
- package/sdk/dist/namespaces/sender-domain.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wallets.js","sourceRoot":"","sources":["../../src/namespaces/wallets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;
|
|
1
|
+
{"version":3,"file":"wallets.js","sourceRoot":"","sources":["../../src/namespaces/wallets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AASH,sFAAsF;AACtF,KAAK,UAAU,SAAS,CAAC,MAAc,EAAE,OAAe;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAC9B,eAAe,kBAAkB,CAAC,OAAO,CAAC,QAAQ,EAClD,EAAE,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,KAAK,EAAE,CACrD,CAAC;QACF,OAAO,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,uFAAuF;AACvF,KAAK,UAAU,QAAQ,CAAC,MAAc,EAAE,OAAe,EAAE,KAAa;IACpE,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,CAClB,eAAe,kBAAkB,CAAC,OAAO,CAAC,QAAQ,EAClD,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,CACrF,CAAC;QACF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,MAAM,OAAO,OAAO;IACW;IAA7B,YAA6B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAE/C;;;OAGG;IACH,KAAK,CAAC,QAAQ,CAAC,OAAe;QAC5B,OAAO,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,OAAO,YAAY;IACM;IAAiC;IAA9D,YAA6B,MAAc,EAAmB,OAAe;QAAhD,WAAM,GAAN,MAAM,CAAQ;QAAmB,YAAO,GAAP,OAAO,CAAQ;IAAG,CAAC;IAEjF,qDAAqD;IACrD,QAAQ;QACN,OAAO,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,sEAAsE;IACtE,QAAQ,CAAC,KAAa;QACpB,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACpD,CAAC;CACF"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gitvault — the six-stage crash-safe creation journal (protocol rev 40 §5.2;
|
|
3
|
+
* task 5.3).
|
|
4
|
+
*
|
|
5
|
+
* LOCAL_KEYS_PREPARED identity + client_creation_id (no ciphertext yet —
|
|
6
|
+
* ALLOCATED verified allocation: repo_id, nonce, gen repo_id is a KDF input)
|
|
7
|
+
* OBJECTS_PREPARED exact object ids, nonces, framed bytes, hashes, sizes — fsynced BEFORE any PUT
|
|
8
|
+
* OBJECTS_FINALIZED server receipts, compared to the local manifest
|
|
9
|
+
* GENESIS_PREPARED exact genesis stored bytes + hash
|
|
10
|
+
* ACTIVE admitted; pin + recovery receipt recorded
|
|
11
|
+
*
|
|
12
|
+
* The ordering is the round-3 H5 invariant made structural: `K_repo` is
|
|
13
|
+
* generated and the creator's `key_envelope` is sealed ONLY in the
|
|
14
|
+
* OBJECTS_PREPARED step, which cannot run until ALLOCATED has journaled a
|
|
15
|
+
* `repo_id` — because `repo_id` is an HKDF input and an HPKE AAD member, no
|
|
16
|
+
* ciphertext can exist before allocation. Each stage is written to
|
|
17
|
+
* `journal/<client_creation_id>.json` with the keystore's atomic+fsync write
|
|
18
|
+
* before the next step starts.
|
|
19
|
+
*
|
|
20
|
+
* Restart reconciliation (`resume`) dispatches on the durable stage:
|
|
21
|
+
* - OBJECTS_PREPARED with a PUT possibly in flight → read-and-compare the
|
|
22
|
+
* object against the journaled bytes; equal → finalized; present-but-
|
|
23
|
+
* different → `VAULT_CREATION_CONFLICT`; absent → PUT the SAME bytes.
|
|
24
|
+
* Never re-encrypt under the same id (a fresh seal would be a second
|
|
25
|
+
* ciphertext under a single-use key label).
|
|
26
|
+
* - GENESIS_PREPARED → read the admitted genesis back; equal → ACTIVE;
|
|
27
|
+
* foreign → `VAULT_CREATION_CONFLICT`, never overwritten.
|
|
28
|
+
* - a `superseded` allocation anywhere → `ALLOCATION_SUPERSEDED`; the client
|
|
29
|
+
* does not publish.
|
|
30
|
+
* - anything the journal cannot explain → refuse the destructive retry.
|
|
31
|
+
*
|
|
32
|
+
* The control-plane calls ride an injectable {@link GitvaultCreationTransport}
|
|
33
|
+
* — task 5.4 wires the HTTP one; tests supply an in-memory bucket.
|
|
34
|
+
*/
|
|
35
|
+
import { GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT, GITVAULT_TERMINAL_LOSS_STATEMENT } from "../namespaces/gitvault.crypto.js";
|
|
36
|
+
import type { GitvaultAllocation, GitvaultKeyEnvelopeReceipt, GitvaultRecoveryReceipt, GitvaultVaultGenesis } from "../namespaces/gitvault.types.js";
|
|
37
|
+
import { GitvaultKeystore } from "./gitvault-keystore.js";
|
|
38
|
+
export declare const GITVAULT_CREATION_STAGES: readonly ["LOCAL_KEYS_PREPARED", "ALLOCATED", "OBJECTS_PREPARED", "OBJECTS_FINALIZED", "GENESIS_PREPARED", "ACTIVE"];
|
|
39
|
+
export type GitvaultCreationStage = (typeof GITVAULT_CREATION_STAGES)[number];
|
|
40
|
+
/** One prepared object: exact bytes + identity, durable before any PUT. */
|
|
41
|
+
export interface GitvaultJournaledObject {
|
|
42
|
+
object_kind: "key_envelope";
|
|
43
|
+
/** Storage path relative to the vault root (`envelopes/<epoch>/<recipient_fingerprint>`). */
|
|
44
|
+
path: string;
|
|
45
|
+
/** The exact stored bytes, base64url (the §1 "base64url-jcs" convention). */
|
|
46
|
+
stored_bytes_b64u: string;
|
|
47
|
+
stored_bytes_sha256: string;
|
|
48
|
+
size_bytes: string;
|
|
49
|
+
/** The genesis receipt for this object. */
|
|
50
|
+
receipt: GitvaultKeyEnvelopeReceipt;
|
|
51
|
+
/** Set once the server receipt was compared equal to the local manifest. */
|
|
52
|
+
finalized: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** `journal/<client_creation_id>.json`. Stage-monotonic; every field from an earlier stage survives. */
|
|
55
|
+
export interface GitvaultCreationJournal {
|
|
56
|
+
version: 1;
|
|
57
|
+
stage: GitvaultCreationStage;
|
|
58
|
+
client_creation_id: string;
|
|
59
|
+
org_id: string;
|
|
60
|
+
project_id: string;
|
|
61
|
+
creator_signing_fingerprint: string;
|
|
62
|
+
creator_encryption_fingerprint: string;
|
|
63
|
+
created_at: string;
|
|
64
|
+
updated_at: string;
|
|
65
|
+
/** ALLOCATED — the verified allocation verbatim. */
|
|
66
|
+
allocation: GitvaultAllocation | null;
|
|
67
|
+
/** OBJECTS_PREPARED — K_repo (hex) lives ONLY here until ACTIVE moves it to the repo file. */
|
|
68
|
+
k_repo_hex: string | null;
|
|
69
|
+
objects: GitvaultJournaledObject[];
|
|
70
|
+
/** GENESIS_PREPARED — the exact signed genesis and its stored-bytes hash. */
|
|
71
|
+
genesis: GitvaultVaultGenesis | null;
|
|
72
|
+
genesis_sha256: string | null;
|
|
73
|
+
/** ACTIVE — the emitted recovery receipt. */
|
|
74
|
+
recovery_receipt: GitvaultRecoveryReceipt | null;
|
|
75
|
+
/** A terminal refusal, if reconciliation hit one (the journal is kept for diagnosis, never retried destructively). */
|
|
76
|
+
refusal: {
|
|
77
|
+
code: "VAULT_CREATION_CONFLICT" | "ALLOCATION_SUPERSEDED";
|
|
78
|
+
at: string;
|
|
79
|
+
details?: Record<string, unknown>;
|
|
80
|
+
} | null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* `POST /gitvault/v1/vaults` — the allocate REQUEST.
|
|
84
|
+
*
|
|
85
|
+
* READ THIS BEFORE CHANGING THESE FIELD NAMES. The request carries the raw
|
|
86
|
+
* PUBLIC KEYS; the signed `allocation` RECORD the gateway returns carries the
|
|
87
|
+
* FINGERPRINTS derived from them. The two shapes differ on exactly these two
|
|
88
|
+
* fields, so building the request from `schemas/allocation.json` — the obvious
|
|
89
|
+
* thing to do — produces a body the gateway ignores, and it answers
|
|
90
|
+
* `400 VALIDATION_FAILED field=creator_signing_pubkey` as if the field were
|
|
91
|
+
* simply missing. That is the production failure this comment exists to stop
|
|
92
|
+
* from recurring.
|
|
93
|
+
*
|
|
94
|
+
* Pubkeys, not fingerprints, because a fingerprint is one-way: every later head
|
|
95
|
+
* signature is verified against the stored creator signing key, and a hash
|
|
96
|
+
* cannot verify a signature. The gateway derives the fingerprints itself, and
|
|
97
|
+
* `checkAllocation` compares the record's fingerprints back against this
|
|
98
|
+
* principal's — which is what proves the keys we sent are the keys it stored.
|
|
99
|
+
*/
|
|
100
|
+
export interface GitvaultAllocateRequest {
|
|
101
|
+
client_creation_id: string;
|
|
102
|
+
org_id: string;
|
|
103
|
+
project_id: string;
|
|
104
|
+
/** Raw Ed25519 public key, canonical base64url (43 chars, decodes to 32 bytes). */
|
|
105
|
+
creator_signing_pubkey: string;
|
|
106
|
+
/** Raw X25519 public key, canonical base64url (43 chars, decodes to 32 bytes). */
|
|
107
|
+
creator_encryption_pubkey: string;
|
|
108
|
+
}
|
|
109
|
+
export interface GitvaultPutObjectRequest {
|
|
110
|
+
repo_id: string;
|
|
111
|
+
path: string;
|
|
112
|
+
bytes: Uint8Array;
|
|
113
|
+
/** What the client expects the server to acknowledge — the server's receipt is compared against it. */
|
|
114
|
+
expected_sha256: string;
|
|
115
|
+
expected_size_bytes: string;
|
|
116
|
+
}
|
|
117
|
+
export interface GitvaultObjectReceipt {
|
|
118
|
+
stored_bytes_sha256: string;
|
|
119
|
+
size_bytes: string;
|
|
120
|
+
}
|
|
121
|
+
export interface GitvaultAdmitGenesisRequest {
|
|
122
|
+
repo_id: string;
|
|
123
|
+
allocation_generation: string;
|
|
124
|
+
stored_bytes: Uint8Array;
|
|
125
|
+
stored_bytes_sha256: string;
|
|
126
|
+
}
|
|
127
|
+
export type GitvaultAdmitGenesisResult = {
|
|
128
|
+
outcome: "admitted";
|
|
129
|
+
admitted_sha256: string;
|
|
130
|
+
}
|
|
131
|
+
/** Someone already canonized generation zero — the resume path decides whether it is ours (read-back) or foreign. */
|
|
132
|
+
| {
|
|
133
|
+
outcome: "already_admitted";
|
|
134
|
+
admitted_sha256: string;
|
|
135
|
+
} | {
|
|
136
|
+
outcome: "allocation_superseded";
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* The control-plane + bucket operations creation needs. Every method is
|
|
140
|
+
* idempotent from the journal's point of view; the journal never relies on a
|
|
141
|
+
* call having NOT happened.
|
|
142
|
+
*/
|
|
143
|
+
export interface GitvaultCreationTransport {
|
|
144
|
+
/** Idempotent on `client_creation_id`; returns the current representation (which may be `superseded`). */
|
|
145
|
+
allocate(request: GitvaultAllocateRequest): Promise<GitvaultAllocation>;
|
|
146
|
+
/** Create-only PUT; on a pre-existing object the server MAY return its receipt instead of overwriting. */
|
|
147
|
+
putObject(request: GitvaultPutObjectRequest): Promise<GitvaultObjectReceipt>;
|
|
148
|
+
/** Read an object back (`null` when absent) — the read-and-compare primitive. */
|
|
149
|
+
getObject(request: {
|
|
150
|
+
repo_id: string;
|
|
151
|
+
path: string;
|
|
152
|
+
}): Promise<Uint8Array | null>;
|
|
153
|
+
/** Generation-zero admission (the §5A machine at generation zero). */
|
|
154
|
+
admitGenesis(request: GitvaultAdmitGenesisRequest): Promise<GitvaultAdmitGenesisResult>;
|
|
155
|
+
/** Read the admitted genesis bytes back (`null` when none). */
|
|
156
|
+
getGenesis(request: {
|
|
157
|
+
repo_id: string;
|
|
158
|
+
}): Promise<Uint8Array | null>;
|
|
159
|
+
}
|
|
160
|
+
export interface GitvaultCreationOptions {
|
|
161
|
+
keystore: GitvaultKeystore;
|
|
162
|
+
transport: GitvaultCreationTransport;
|
|
163
|
+
org_id: string;
|
|
164
|
+
project_id: string;
|
|
165
|
+
/** Resume an existing journal, or pin the idempotency key (tests). Fresh CSPRNG when omitted. */
|
|
166
|
+
client_creation_id?: string;
|
|
167
|
+
/** Clock injection. */
|
|
168
|
+
now?: () => Date;
|
|
169
|
+
/** Optional pinned service public key for allocation-signature verification (5.4 supplies it from the registry). */
|
|
170
|
+
service_public_key?: Uint8Array | string;
|
|
171
|
+
/** Test hook: called after each stage is durable, BEFORE the next step — throw to simulate a crash. */
|
|
172
|
+
onStage?: (stage: GitvaultCreationStage, journal: GitvaultCreationJournal) => void | Promise<void>;
|
|
173
|
+
}
|
|
174
|
+
export interface GitvaultCreationResult {
|
|
175
|
+
repo_id: string;
|
|
176
|
+
genesis_sha256: string;
|
|
177
|
+
recovery_receipt: GitvaultRecoveryReceipt;
|
|
178
|
+
journal: GitvaultCreationJournal;
|
|
179
|
+
/** `created` on the first pass; `reconciled` when a restart completed an earlier attempt. */
|
|
180
|
+
how: "created" | "reconciled";
|
|
181
|
+
}
|
|
182
|
+
/** Journal file for one creation attempt. */
|
|
183
|
+
export declare function gitvaultJournalPath(keystore: GitvaultKeystore, clientCreationId: string): string;
|
|
184
|
+
export declare function readGitvaultJournal(keystore: GitvaultKeystore, clientCreationId: string): GitvaultCreationJournal | null;
|
|
185
|
+
/** Every journal on disk that has not reached ACTIVE (what `doctor` lists as "creation in progress"). */
|
|
186
|
+
export declare function listIncompleteGitvaultJournals(keystore: GitvaultKeystore): GitvaultCreationJournal[];
|
|
187
|
+
export declare class GitvaultCreation {
|
|
188
|
+
private readonly keystore;
|
|
189
|
+
private readonly transport;
|
|
190
|
+
private readonly now;
|
|
191
|
+
private readonly options;
|
|
192
|
+
private journal;
|
|
193
|
+
private resumed;
|
|
194
|
+
private constructor();
|
|
195
|
+
/**
|
|
196
|
+
* Open a creation: resume the journal for `client_creation_id` when one
|
|
197
|
+
* exists, else write stage 1 (LOCAL_KEYS_PREPARED). Nothing here touches the
|
|
198
|
+
* network; no ciphertext exists yet.
|
|
199
|
+
*/
|
|
200
|
+
static open(options: GitvaultCreationOptions): GitvaultCreation;
|
|
201
|
+
get current(): GitvaultCreationJournal;
|
|
202
|
+
private persist;
|
|
203
|
+
private advance;
|
|
204
|
+
private refuse;
|
|
205
|
+
/**
|
|
206
|
+
* Drive the journal to ACTIVE from whatever stage is durable. Safe to call
|
|
207
|
+
* again after any crash; a refused journal stays refused.
|
|
208
|
+
*/
|
|
209
|
+
run(): Promise<GitvaultCreationResult>;
|
|
210
|
+
private verifyAllocation;
|
|
211
|
+
}
|
|
212
|
+
/** Convenience: open + run in one call. */
|
|
213
|
+
export declare function createGitvault(options: GitvaultCreationOptions): Promise<GitvaultCreationResult>;
|
|
214
|
+
/** What `doctor`/`status` print about V0-A recovery — the verbatim statement plus the pointers it must carry. */
|
|
215
|
+
export interface GitvaultDoctorRecoveryText {
|
|
216
|
+
statement: typeof GITVAULT_TERMINAL_LOSS_STATEMENT;
|
|
217
|
+
doctor_text: typeof GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT;
|
|
218
|
+
/** The platform's custodial restore of deployed artifacts (the deploy lane's CAS) — the support path when every principal envelope is lost. */
|
|
219
|
+
cas_restore_pointer: string;
|
|
220
|
+
}
|
|
221
|
+
export declare function gitvaultDoctorRecoveryText(): GitvaultDoctorRecoveryText;
|
|
222
|
+
//# sourceMappingURL=gitvault-creation-journal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitvault-creation-journal.d.ts","sourceRoot":"","sources":["../../src/node/gitvault-creation-journal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gitvault — the six-stage crash-safe creation journal (protocol rev 40 §5.2;
|
|
3
|
+
* task 5.3).
|
|
4
|
+
*
|
|
5
|
+
* LOCAL_KEYS_PREPARED identity + client_creation_id (no ciphertext yet —
|
|
6
|
+
* ALLOCATED verified allocation: repo_id, nonce, gen repo_id is a KDF input)
|
|
7
|
+
* OBJECTS_PREPARED exact object ids, nonces, framed bytes, hashes, sizes — fsynced BEFORE any PUT
|
|
8
|
+
* OBJECTS_FINALIZED server receipts, compared to the local manifest
|
|
9
|
+
* GENESIS_PREPARED exact genesis stored bytes + hash
|
|
10
|
+
* ACTIVE admitted; pin + recovery receipt recorded
|
|
11
|
+
*
|
|
12
|
+
* The ordering is the round-3 H5 invariant made structural: `K_repo` is
|
|
13
|
+
* generated and the creator's `key_envelope` is sealed ONLY in the
|
|
14
|
+
* OBJECTS_PREPARED step, which cannot run until ALLOCATED has journaled a
|
|
15
|
+
* `repo_id` — because `repo_id` is an HKDF input and an HPKE AAD member, no
|
|
16
|
+
* ciphertext can exist before allocation. Each stage is written to
|
|
17
|
+
* `journal/<client_creation_id>.json` with the keystore's atomic+fsync write
|
|
18
|
+
* before the next step starts.
|
|
19
|
+
*
|
|
20
|
+
* Restart reconciliation (`resume`) dispatches on the durable stage:
|
|
21
|
+
* - OBJECTS_PREPARED with a PUT possibly in flight → read-and-compare the
|
|
22
|
+
* object against the journaled bytes; equal → finalized; present-but-
|
|
23
|
+
* different → `VAULT_CREATION_CONFLICT`; absent → PUT the SAME bytes.
|
|
24
|
+
* Never re-encrypt under the same id (a fresh seal would be a second
|
|
25
|
+
* ciphertext under a single-use key label).
|
|
26
|
+
* - GENESIS_PREPARED → read the admitted genesis back; equal → ACTIVE;
|
|
27
|
+
* foreign → `VAULT_CREATION_CONFLICT`, never overwritten.
|
|
28
|
+
* - a `superseded` allocation anywhere → `ALLOCATION_SUPERSEDED`; the client
|
|
29
|
+
* does not publish.
|
|
30
|
+
* - anything the journal cannot explain → refuse the destructive retry.
|
|
31
|
+
*
|
|
32
|
+
* The control-plane calls ride an injectable {@link GitvaultCreationTransport}
|
|
33
|
+
* — task 5.4 wires the HTTP one; tests supply an in-memory bucket.
|
|
34
|
+
*/
|
|
35
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
36
|
+
import { join } from "node:path";
|
|
37
|
+
import { LocalError } from "../errors.js";
|
|
38
|
+
import { GITVAULT_GENESIS_EPOCH, GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT, GITVAULT_TERMINAL_LOSS_STATEMENT, buildRecoveryReceipt, buildVaultGenesis, bytesToHex, checkAllocation, checkGenesisKeyBindings, formatGitvaultTimestamp, newHex32, parseGitvaultStrict, randomBytes, sealKeyEnvelope, sha256Hex, storedBytes, } from "../namespaces/gitvault.crypto.js";
|
|
39
|
+
import { readFileNoFollow, writeFileAtomic0600 } from "./gitvault-keystore.js";
|
|
40
|
+
// ─── Stages + journal shape ──────────────────────────────────────────────────
|
|
41
|
+
export const GITVAULT_CREATION_STAGES = [
|
|
42
|
+
"LOCAL_KEYS_PREPARED",
|
|
43
|
+
"ALLOCATED",
|
|
44
|
+
"OBJECTS_PREPARED",
|
|
45
|
+
"OBJECTS_FINALIZED",
|
|
46
|
+
"GENESIS_PREPARED",
|
|
47
|
+
"ACTIVE",
|
|
48
|
+
];
|
|
49
|
+
function fail(code, message, context, details) {
|
|
50
|
+
throw new LocalError(message, context, { code, details });
|
|
51
|
+
}
|
|
52
|
+
function envelopePath(epoch, recipientFingerprint) {
|
|
53
|
+
return `envelopes/${epoch}/${recipientFingerprint}`;
|
|
54
|
+
}
|
|
55
|
+
/** Journal file for one creation attempt. */
|
|
56
|
+
export function gitvaultJournalPath(keystore, clientCreationId) {
|
|
57
|
+
if (!/^[0-9a-f]{32}$/.test(clientCreationId))
|
|
58
|
+
fail("GITVAULT_BAD_ID", "client_creation_id must be 32 lowercase hex", "resolving gitvault journal path");
|
|
59
|
+
return join(keystore.journalDir, `${clientCreationId}.json`);
|
|
60
|
+
}
|
|
61
|
+
export function readGitvaultJournal(keystore, clientCreationId) {
|
|
62
|
+
const text = readFileNoFollow(gitvaultJournalPath(keystore, clientCreationId));
|
|
63
|
+
if (!text)
|
|
64
|
+
return null;
|
|
65
|
+
const journal = JSON.parse(text);
|
|
66
|
+
if (journal.version !== 1 || !GITVAULT_CREATION_STAGES.includes(journal.stage)) {
|
|
67
|
+
fail("GITVAULT_JOURNAL_CORRUPT", "creation journal is not a version-1 gitvault journal", "reading gitvault creation journal", { client_creation_id: clientCreationId });
|
|
68
|
+
}
|
|
69
|
+
return journal;
|
|
70
|
+
}
|
|
71
|
+
/** Every journal on disk that has not reached ACTIVE (what `doctor` lists as "creation in progress"). */
|
|
72
|
+
export function listIncompleteGitvaultJournals(keystore) {
|
|
73
|
+
if (!existsSync(keystore.journalDir))
|
|
74
|
+
return [];
|
|
75
|
+
const out = [];
|
|
76
|
+
for (const entry of readdirSync(keystore.journalDir)) {
|
|
77
|
+
if (!entry.endsWith(".json"))
|
|
78
|
+
continue;
|
|
79
|
+
const id = entry.slice(0, -5);
|
|
80
|
+
if (!/^[0-9a-f]{32}$/.test(id))
|
|
81
|
+
continue;
|
|
82
|
+
const j = readGitvaultJournal(keystore, id);
|
|
83
|
+
if (j && j.stage !== "ACTIVE")
|
|
84
|
+
out.push(j);
|
|
85
|
+
}
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
88
|
+
export class GitvaultCreation {
|
|
89
|
+
keystore;
|
|
90
|
+
transport;
|
|
91
|
+
now;
|
|
92
|
+
options;
|
|
93
|
+
journal;
|
|
94
|
+
resumed = false;
|
|
95
|
+
constructor(options, journal, resumed) {
|
|
96
|
+
this.options = options;
|
|
97
|
+
this.keystore = options.keystore;
|
|
98
|
+
this.transport = options.transport;
|
|
99
|
+
this.now = options.now ?? (() => new Date());
|
|
100
|
+
this.journal = journal;
|
|
101
|
+
this.resumed = resumed;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Open a creation: resume the journal for `client_creation_id` when one
|
|
105
|
+
* exists, else write stage 1 (LOCAL_KEYS_PREPARED). Nothing here touches the
|
|
106
|
+
* network; no ciphertext exists yet.
|
|
107
|
+
*/
|
|
108
|
+
static open(options) {
|
|
109
|
+
const ks = options.keystore;
|
|
110
|
+
const identity = ks.ensureIdentity();
|
|
111
|
+
const signing = ks.signingKeypair(identity);
|
|
112
|
+
const encryption = ks.encryptionKeypair(identity);
|
|
113
|
+
if (!signing || !encryption) {
|
|
114
|
+
fail("GITVAULT_READ_ONLY", "this principal cannot create a vault: a private key is missing from identity.json", "opening gitvault creation", { signing_key_present: Boolean(signing), encryption_key_present: Boolean(encryption) });
|
|
115
|
+
}
|
|
116
|
+
const id = options.client_creation_id ?? newHex32();
|
|
117
|
+
const existing = readGitvaultJournal(ks, id);
|
|
118
|
+
if (existing) {
|
|
119
|
+
if (existing.org_id !== options.org_id || existing.project_id !== options.project_id) {
|
|
120
|
+
fail("VAULT_CREATION_CONFLICT", "journal belongs to a different org/project", "resuming gitvault creation", { client_creation_id: id });
|
|
121
|
+
}
|
|
122
|
+
if (existing.creator_signing_fingerprint !== identity.signing_fingerprint || existing.creator_encryption_fingerprint !== identity.encryption_fingerprint) {
|
|
123
|
+
fail("VAULT_CREATION_CONFLICT", "journal was prepared by a different identity; refusing the destructive retry", "resuming gitvault creation", { client_creation_id: id });
|
|
124
|
+
}
|
|
125
|
+
return new GitvaultCreation(options, existing, true);
|
|
126
|
+
}
|
|
127
|
+
const at = formatGitvaultTimestamp((options.now ?? (() => new Date()))());
|
|
128
|
+
const journal = {
|
|
129
|
+
version: 1,
|
|
130
|
+
stage: "LOCAL_KEYS_PREPARED",
|
|
131
|
+
client_creation_id: id,
|
|
132
|
+
org_id: options.org_id,
|
|
133
|
+
project_id: options.project_id,
|
|
134
|
+
creator_signing_fingerprint: identity.signing_fingerprint,
|
|
135
|
+
creator_encryption_fingerprint: identity.encryption_fingerprint,
|
|
136
|
+
created_at: at,
|
|
137
|
+
updated_at: at,
|
|
138
|
+
allocation: null,
|
|
139
|
+
k_repo_hex: null,
|
|
140
|
+
objects: [],
|
|
141
|
+
genesis: null,
|
|
142
|
+
genesis_sha256: null,
|
|
143
|
+
recovery_receipt: null,
|
|
144
|
+
refusal: null,
|
|
145
|
+
};
|
|
146
|
+
const c = new GitvaultCreation(options, journal, false);
|
|
147
|
+
c.persist();
|
|
148
|
+
return c;
|
|
149
|
+
}
|
|
150
|
+
get current() {
|
|
151
|
+
return this.journal;
|
|
152
|
+
}
|
|
153
|
+
persist() {
|
|
154
|
+
this.journal = { ...this.journal, updated_at: formatGitvaultTimestamp(this.now()) };
|
|
155
|
+
writeFileAtomic0600(gitvaultJournalPath(this.keystore, this.journal.client_creation_id), JSON.stringify(this.journal, null, 2));
|
|
156
|
+
this.keystore.audit("journal_stage", this.journal.allocation?.repo_id, { client_creation_id: this.journal.client_creation_id, stage: this.journal.stage });
|
|
157
|
+
}
|
|
158
|
+
async advance(stage, patch) {
|
|
159
|
+
this.journal = { ...this.journal, ...patch, stage };
|
|
160
|
+
this.persist();
|
|
161
|
+
await this.options.onStage?.(stage, this.journal);
|
|
162
|
+
}
|
|
163
|
+
refuse(code, message, details) {
|
|
164
|
+
this.journal = { ...this.journal, refusal: { code, at: formatGitvaultTimestamp(this.now()), ...(details ? { details } : {}) } };
|
|
165
|
+
this.persist();
|
|
166
|
+
fail(code, message, "reconciling gitvault creation", { client_creation_id: this.journal.client_creation_id, ...details });
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Drive the journal to ACTIVE from whatever stage is durable. Safe to call
|
|
170
|
+
* again after any crash; a refused journal stays refused.
|
|
171
|
+
*/
|
|
172
|
+
async run() {
|
|
173
|
+
if (this.journal.refusal) {
|
|
174
|
+
fail(this.journal.refusal.code, "this creation attempt was refused earlier; start a new attempt (the journal is kept for diagnosis)", "resuming gitvault creation", {
|
|
175
|
+
client_creation_id: this.journal.client_creation_id,
|
|
176
|
+
refused_at: this.journal.refusal.at,
|
|
177
|
+
...this.journal.refusal.details,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
const identity = this.keystore.ensureIdentity();
|
|
181
|
+
const signing = this.keystore.signingKeypair(identity);
|
|
182
|
+
const encryption = this.keystore.encryptionKeypair(identity);
|
|
183
|
+
// ── 2. ALLOCATED ──
|
|
184
|
+
if (this.journal.stage === "LOCAL_KEYS_PREPARED") {
|
|
185
|
+
const allocation = await this.transport.allocate({
|
|
186
|
+
client_creation_id: this.journal.client_creation_id,
|
|
187
|
+
org_id: this.journal.org_id,
|
|
188
|
+
project_id: this.journal.project_id,
|
|
189
|
+
// PUBKEYS on the request; the returned record carries the fingerprints
|
|
190
|
+
// the gateway derives from them. See GitvaultAllocateRequest.
|
|
191
|
+
creator_signing_pubkey: identity.signing_pubkey,
|
|
192
|
+
creator_encryption_pubkey: identity.encryption_pubkey,
|
|
193
|
+
});
|
|
194
|
+
this.verifyAllocation(allocation);
|
|
195
|
+
await this.advance("ALLOCATED", { allocation });
|
|
196
|
+
}
|
|
197
|
+
const allocation = this.journal.allocation;
|
|
198
|
+
const repoId = allocation.repo_id;
|
|
199
|
+
const epoch = GITVAULT_GENESIS_EPOCH;
|
|
200
|
+
// ── 3. OBJECTS_PREPARED — the FIRST point at which ciphertext exists ──
|
|
201
|
+
if (this.journal.stage === "ALLOCATED") {
|
|
202
|
+
const kRepo = randomBytes(32);
|
|
203
|
+
const sealed = await sealKeyEnvelope({
|
|
204
|
+
k_repo: kRepo,
|
|
205
|
+
repo_id: repoId,
|
|
206
|
+
epoch,
|
|
207
|
+
recipient_public_key: encryption.public_key,
|
|
208
|
+
signer: signing,
|
|
209
|
+
created_at: formatGitvaultTimestamp(this.now()),
|
|
210
|
+
});
|
|
211
|
+
const object = {
|
|
212
|
+
object_kind: "key_envelope",
|
|
213
|
+
path: envelopePath(epoch, sealed.receipt.recipient_fingerprint),
|
|
214
|
+
stored_bytes_b64u: b64u(sealed.stored_bytes),
|
|
215
|
+
stored_bytes_sha256: sealed.stored_bytes_sha256,
|
|
216
|
+
size_bytes: sealed.size_bytes,
|
|
217
|
+
receipt: sealed.receipt,
|
|
218
|
+
finalized: false,
|
|
219
|
+
};
|
|
220
|
+
await this.advance("OBJECTS_PREPARED", { k_repo_hex: bytesToHex(kRepo), objects: [object] });
|
|
221
|
+
}
|
|
222
|
+
// ── 4. OBJECTS_FINALIZED — PUT (or read-and-compare after a crash), never re-encrypt ──
|
|
223
|
+
if (this.journal.stage === "OBJECTS_PREPARED") {
|
|
224
|
+
const objects = this.journal.objects.map((o) => ({ ...o }));
|
|
225
|
+
for (const object of objects) {
|
|
226
|
+
if (object.finalized)
|
|
227
|
+
continue;
|
|
228
|
+
const bytes = unb64u(object.stored_bytes_b64u);
|
|
229
|
+
if (sha256Hex(bytes) !== object.stored_bytes_sha256 || String(bytes.length) !== object.size_bytes) {
|
|
230
|
+
this.refuse("VAULT_CREATION_CONFLICT", "journaled object bytes do not match their journaled hash; refusing the destructive retry", { path: object.path });
|
|
231
|
+
}
|
|
232
|
+
const remote = await this.transport.getObject({ repo_id: repoId, path: object.path });
|
|
233
|
+
if (remote) {
|
|
234
|
+
if (!bytesEqual(remote, bytes)) {
|
|
235
|
+
this.refuse("VAULT_CREATION_CONFLICT", "an object already exists at this path with different bytes", { path: object.path, remote_sha256: sha256Hex(remote) });
|
|
236
|
+
}
|
|
237
|
+
object.finalized = true;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
const receipt = await this.transport.putObject({ repo_id: repoId, path: object.path, bytes, expected_sha256: object.stored_bytes_sha256, expected_size_bytes: object.size_bytes });
|
|
241
|
+
if (receipt.stored_bytes_sha256 !== object.stored_bytes_sha256 || receipt.size_bytes !== object.size_bytes) {
|
|
242
|
+
this.refuse("VAULT_CREATION_CONFLICT", "the server's finalization receipt does not match the local manifest", { path: object.path, receipt });
|
|
243
|
+
}
|
|
244
|
+
object.finalized = true;
|
|
245
|
+
}
|
|
246
|
+
await this.advance("OBJECTS_FINALIZED", { objects });
|
|
247
|
+
}
|
|
248
|
+
// ── 5. GENESIS_PREPARED — exact stored bytes + hash journaled before the admission PUT ──
|
|
249
|
+
if (this.journal.stage === "OBJECTS_FINALIZED") {
|
|
250
|
+
const envelopeObject = this.journal.objects.find((o) => o.object_kind === "key_envelope");
|
|
251
|
+
if (!envelopeObject)
|
|
252
|
+
this.refuse("VAULT_CREATION_CONFLICT", "journal has no finalized key_envelope");
|
|
253
|
+
const genesis = buildVaultGenesis({
|
|
254
|
+
repo_id: repoId,
|
|
255
|
+
org_id: this.journal.org_id,
|
|
256
|
+
project_id: this.journal.project_id,
|
|
257
|
+
allocation_nonce: allocation.allocation_nonce,
|
|
258
|
+
creator_signing: signing,
|
|
259
|
+
creator_encryption_public_key: encryption.public_key,
|
|
260
|
+
envelope_receipt: envelopeObject.receipt,
|
|
261
|
+
created_at: formatGitvaultTimestamp(this.now()),
|
|
262
|
+
});
|
|
263
|
+
const storedEnvelope = parseGitvaultStrict(new TextDecoder().decode(unb64u(envelopeObject.stored_bytes_b64u)));
|
|
264
|
+
const bindings = checkGenesisKeyBindings(genesis, storedEnvelope);
|
|
265
|
+
if (bindings.length > 0)
|
|
266
|
+
this.refuse("VAULT_CREATION_CONFLICT", "prepared genesis fails its own key bindings", { problems: bindings });
|
|
267
|
+
await this.advance("GENESIS_PREPARED", { genesis, genesis_sha256: sha256Hex(storedBytes(genesis)) });
|
|
268
|
+
}
|
|
269
|
+
// ── 6. ACTIVE — admit; on resume read back; foreign genesis is a refusal ──
|
|
270
|
+
if (this.journal.stage === "GENESIS_PREPARED") {
|
|
271
|
+
const genesis = this.journal.genesis;
|
|
272
|
+
const bytes = storedBytes(genesis);
|
|
273
|
+
const hash = sha256Hex(bytes);
|
|
274
|
+
if (hash !== this.journal.genesis_sha256)
|
|
275
|
+
this.refuse("VAULT_CREATION_CONFLICT", "journaled genesis bytes do not match their journaled hash");
|
|
276
|
+
const existing = await this.transport.getGenesis({ repo_id: repoId });
|
|
277
|
+
if (existing) {
|
|
278
|
+
if (!bytesEqual(existing, bytes)) {
|
|
279
|
+
this.refuse("VAULT_CREATION_CONFLICT", "a different genesis is already admitted for this repo_id (foreign genesis); never overwritten", { admitted_sha256: sha256Hex(existing) });
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
const result = await this.transport.admitGenesis({ repo_id: repoId, allocation_generation: allocation.allocation_generation, stored_bytes: bytes, stored_bytes_sha256: hash });
|
|
284
|
+
if (result.outcome === "allocation_superseded") {
|
|
285
|
+
this.refuse("ALLOCATION_SUPERSEDED", "the allocation was reclaimed by the owner; this client must not publish", { allocation_generation: allocation.allocation_generation });
|
|
286
|
+
}
|
|
287
|
+
if (result.admitted_sha256 !== hash) {
|
|
288
|
+
this.refuse("VAULT_CREATION_CONFLICT", "admission canonized a different genesis than the one prepared here", { admitted_sha256: result.admitted_sha256 });
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
const receipt = buildRecoveryReceipt({
|
|
292
|
+
repo_id: repoId,
|
|
293
|
+
org_id: this.journal.org_id,
|
|
294
|
+
project_id: this.journal.project_id,
|
|
295
|
+
genesis_sha256: hash,
|
|
296
|
+
creator_signing: signing,
|
|
297
|
+
creator_encryption_public_key: encryption.public_key,
|
|
298
|
+
});
|
|
299
|
+
// Pin + K_repo move into the repo file, then the receipt, then the journal flips — so a
|
|
300
|
+
// crash between them leaves a GENESIS_PREPARED journal whose resume is an idempotent read-back.
|
|
301
|
+
this.keystore.saveRepo({
|
|
302
|
+
repo_id: repoId,
|
|
303
|
+
org_id: this.journal.org_id,
|
|
304
|
+
project_id: this.journal.project_id,
|
|
305
|
+
k_repo_hex: this.journal.k_repo_hex,
|
|
306
|
+
epoch,
|
|
307
|
+
genesis_sha256: hash,
|
|
308
|
+
head_pin: null,
|
|
309
|
+
last_ref_transaction: null,
|
|
310
|
+
provenance: "created",
|
|
311
|
+
});
|
|
312
|
+
this.keystore.saveRecoveryReceipt(receipt);
|
|
313
|
+
await this.advance("ACTIVE", { recovery_receipt: receipt });
|
|
314
|
+
}
|
|
315
|
+
return {
|
|
316
|
+
repo_id: repoId,
|
|
317
|
+
genesis_sha256: this.journal.genesis_sha256,
|
|
318
|
+
recovery_receipt: this.journal.recovery_receipt,
|
|
319
|
+
journal: this.journal,
|
|
320
|
+
how: this.resumed ? "reconciled" : "created",
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
verifyAllocation(allocation) {
|
|
324
|
+
const problems = checkAllocation(allocation, {
|
|
325
|
+
client_creation_id: this.journal.client_creation_id,
|
|
326
|
+
creator_signing_fingerprint: this.journal.creator_signing_fingerprint,
|
|
327
|
+
creator_encryption_fingerprint: this.journal.creator_encryption_fingerprint,
|
|
328
|
+
org_id: this.journal.org_id,
|
|
329
|
+
project_id: this.journal.project_id,
|
|
330
|
+
}, this.options.service_public_key);
|
|
331
|
+
if (problems.length > 0) {
|
|
332
|
+
fail("GITVAULT_ALLOCATION_INVALID", "allocation does not match this creation attempt", "verifying gitvault allocation", { problems });
|
|
333
|
+
}
|
|
334
|
+
if (allocation.status === "superseded") {
|
|
335
|
+
this.refuse("ALLOCATION_SUPERSEDED", "the allocation was reclaimed by the owner; this client must not resume", { allocation_generation: allocation.allocation_generation });
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
/** Convenience: open + run in one call. */
|
|
340
|
+
export async function createGitvault(options) {
|
|
341
|
+
return GitvaultCreation.open(options).run();
|
|
342
|
+
}
|
|
343
|
+
export function gitvaultDoctorRecoveryText() {
|
|
344
|
+
return {
|
|
345
|
+
statement: GITVAULT_TERMINAL_LOSS_STATEMENT,
|
|
346
|
+
doctor_text: GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT,
|
|
347
|
+
cas_restore_pointer: "The platform custodially holds the plaintext source artifacts of every DEPLOY in its CAS; ask support for a custodial restore of deployed artifacts. Vault HISTORY (commits never deployed) is not recoverable without a surviving principal keystore.",
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
// ─── helpers ────────────────────────────────────────────────────────────────
|
|
351
|
+
function b64u(bytes) {
|
|
352
|
+
return Buffer.from(bytes).toString("base64url");
|
|
353
|
+
}
|
|
354
|
+
function unb64u(text) {
|
|
355
|
+
return new Uint8Array(Buffer.from(text, "base64url"));
|
|
356
|
+
}
|
|
357
|
+
function bytesEqual(a, b) {
|
|
358
|
+
if (a.length !== b.length)
|
|
359
|
+
return false;
|
|
360
|
+
let diff = 0;
|
|
361
|
+
for (let i = 0; i < a.length; i++)
|
|
362
|
+
diff |= a[i] ^ b[i];
|
|
363
|
+
return diff === 0;
|
|
364
|
+
}
|
|
365
|
+
//# sourceMappingURL=gitvault-creation-journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitvault-creation-journal.js","sourceRoot":"","sources":["../../src/node/gitvault-creation-journal.ts"],"names":[],"mappings":"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"}
|