run402 4.68.3 → 4.69.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 +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-snapshot.d.ts +1 -2
- package/sdk/dist/node/gitvault-snapshot.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-snapshot.js +1 -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 +4 -0
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +20 -1
- 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
|
@@ -277,9 +277,15 @@ export declare function checkChainLink(input: GitvaultChainLinkInput): void;
|
|
|
277
277
|
* rotation is ACTIVATED") — `checkChainLink`'s own D194 epoch-continuity
|
|
278
278
|
* check already validates its structural admissibility, and
|
|
279
279
|
* {@link parseRotateEpochPayload} / the caller's own envelope-open step
|
|
280
|
-
* (`GitvaultVault.verifyToNewest`) handle it fully.
|
|
281
|
-
*
|
|
282
|
-
*
|
|
280
|
+
* (`GitvaultVault.verifyToNewest`) handle it fully. `add_writer_key` is
|
|
281
|
+
* EXEMPT as of rev 47 (gitvault-multi-writer) the same way — {@link
|
|
282
|
+
* parseAddWriterKeyPayload} + `validateAddWriterKeyPayload`
|
|
283
|
+
* (`gitvault-writer-state.js`) handle it fully, INSIDE `verifyToNewest`'s
|
|
284
|
+
* own loop, BEFORE this function ever runs on that head (so a transition
|
|
285
|
+
* that fails writer validation never reaches here at all — this function
|
|
286
|
+
* only ever sees ones that already passed). The other two kinds
|
|
287
|
+
* (`add_envelope`, `transfer_binding`) remain genuinely unactivated and stay
|
|
288
|
+
* fail-closed exactly as before.
|
|
283
289
|
*/
|
|
284
290
|
export declare function assertNoTransition(head: GitvaultHead): void;
|
|
285
291
|
/** One object to upload — identity fixed BEFORE the PUT; the receipt is compared against it. */
|
|
@@ -439,8 +445,7 @@ export interface GitvaultCompactionGrant {
|
|
|
439
445
|
* client-declared. NOTE the byte fields arrive as STRINGS on the wire (the
|
|
440
446
|
* gateway serializes Postgres BIGINTs as strings, verified live) — consumers
|
|
441
447
|
* MUST `Number(...)` before arithmetic; `Number.isFinite` on the raw value
|
|
442
|
-
* is false and silently discards the grant
|
|
443
|
-
* run caught on 2026-08-31).
|
|
448
|
+
* is false and silently discards the grant.
|
|
444
449
|
*/
|
|
445
450
|
granted_bytes: number | string;
|
|
446
451
|
expires_at: string;
|
|
@@ -799,8 +804,8 @@ export interface GitvaultTransport extends GitvaultCreationTransport {
|
|
|
799
804
|
*
|
|
800
805
|
* The gateway route (`GET /orgs/v1/:org_id/encryption-keys`, `routes/org.ts`
|
|
801
806
|
* in run402-private) returns `public_key` on every row — the raw key
|
|
802
|
-
* material is what makes the directory usable for wrapping at all
|
|
803
|
-
*
|
|
807
|
+
* material is what makes the directory usable for wrapping at all.
|
|
808
|
+
* The field stays OPTIONAL in this wire type the
|
|
804
809
|
* same way `desired[]` does on {@link GitvaultEnvelopeRecipientsResponse}:
|
|
805
810
|
* a response is network data, and an older/rolling-deploy gateway that
|
|
806
811
|
* omits the field must degrade to a per-entry `skipped` report
|
|
@@ -815,6 +820,16 @@ export interface GitvaultOrgEncryptionKeyEntry {
|
|
|
815
820
|
created_at: string;
|
|
816
821
|
/** Raw base64url X25519 public key. Present on every current-gateway row; tolerated as absent (per-entry `missing_public_key` skip) for wire robustness only. */
|
|
817
822
|
public_key?: string;
|
|
823
|
+
/**
|
|
824
|
+
* gitvault-multi-writer (rev 47) D9 — the SAME row's vault-WRITER signing
|
|
825
|
+
* half (`routes/org.ts` in run402-private, deployed alongside `public_key`
|
|
826
|
+
* D9). Raw base64url Ed25519 public key; `null` when this principal has
|
|
827
|
+
* never published a signing half (a pre-rev47 or encryption-only
|
|
828
|
+
* enrollment), absent entirely on an older gateway that predates D9.
|
|
829
|
+
*/
|
|
830
|
+
signing_pubkey?: string | null;
|
|
831
|
+
signing_fingerprint?: string | null;
|
|
832
|
+
signing_possession_verified_at?: string | null;
|
|
818
833
|
[key: string]: unknown;
|
|
819
834
|
}
|
|
820
835
|
/** `GET /orgs/v1/:org_id/encryption-keys` — {@link GitvaultTransport.listOrgEncryptionKeys}'s result. */
|
|
@@ -905,11 +920,79 @@ export interface GitvaultVaultRecord {
|
|
|
905
920
|
} | null;
|
|
906
921
|
pending_repair_attempt_id: string | null;
|
|
907
922
|
};
|
|
923
|
+
/**
|
|
924
|
+
* gitvault-multi-writer (rev 47) task 3.7 — the writer chain state's read
|
|
925
|
+
* surface, mirrored client-side from the gateway's `VaultRecord` (see
|
|
926
|
+
* `services/gitvault/reads.ts` in run402-private for the authoritative doc
|
|
927
|
+
* comment). `writer_set` is the on-chain-recognized set exactly as the
|
|
928
|
+
* chain itself would verify (regardless of any gateway-only block — that's
|
|
929
|
+
* `ineligible_members`). `pending_writers` is the reverse direction:
|
|
930
|
+
* active org members at role developer+ with a published,
|
|
931
|
+
* possession-verified signing key who are NOT yet in `writer_set.writers`
|
|
932
|
+
* — candidates for the "writer"-door `add_writer_key` (task 5.7's
|
|
933
|
+
* `reconcile()`). `ineligible_members` is a chain-recognized active writer
|
|
934
|
+
* the gateway has flagged for removal, still active on-chain pending the
|
|
935
|
+
* next `rotate_epoch{writer_set_update}`.
|
|
936
|
+
*/
|
|
937
|
+
writer_set?: {
|
|
938
|
+
version: string;
|
|
939
|
+
sha256: string | null;
|
|
940
|
+
writers: GitvaultVaultWriterSetEntry[];
|
|
941
|
+
};
|
|
942
|
+
pending_writers?: GitvaultVaultPendingWriter[];
|
|
943
|
+
ineligible_members?: GitvaultVaultIneligibleMember[];
|
|
944
|
+
/** `gitvault_vaults.read_only_terminal_at IS NOT NULL` — the D228 forced sole-writer-removal terminal state: no further writer-authenticated push is admissible. Absent (never `undefined`-checked as `true`) on an older gateway — treat as `false`. */
|
|
945
|
+
read_only_terminal?: boolean;
|
|
946
|
+
/**
|
|
947
|
+
* gitvault-multi-writer (rev 47) D6/D227, task 5.9 — decimal-string
|
|
948
|
+
* uint64 counter, bumped by the gateway every time a membership/role/key
|
|
949
|
+
* change gateway-blocks one or more writer keys. A client building a
|
|
950
|
+
* `writer_set_update` freezes THIS value into `rotation_attempt_
|
|
951
|
+
* descriptor.writer_revocation_version` at its own admission fence —
|
|
952
|
+
* there is no writer-side "declare" round-trip (unlike the encryption
|
|
953
|
+
* side's `declareRecipientKeyRevoked`), so this read is the only source.
|
|
954
|
+
* Absent on an older gateway that predates this field.
|
|
955
|
+
*/
|
|
956
|
+
writer_revocation_version?: string;
|
|
908
957
|
warnings: {
|
|
909
958
|
kind: string;
|
|
910
959
|
message: string;
|
|
911
960
|
}[];
|
|
912
961
|
created_at: string | null;
|
|
962
|
+
/**
|
|
963
|
+
* The control plane's SIGNED allocation record for the vault (present on
|
|
964
|
+
* gateways that wrap it into the vault read; `null`/absent otherwise).
|
|
965
|
+
* gitvault-agent-envelopes D4: a cold open compares genesis's creator
|
|
966
|
+
* fingerprints against these — platform-attested consistency, never
|
|
967
|
+
* independent authentication (the platform serves both sides).
|
|
968
|
+
*/
|
|
969
|
+
allocation?: {
|
|
970
|
+
creator_signing_fingerprint: string;
|
|
971
|
+
creator_encryption_fingerprint: string;
|
|
972
|
+
status?: string;
|
|
973
|
+
service_key_id?: string;
|
|
974
|
+
[key: string]: unknown;
|
|
975
|
+
} | null;
|
|
976
|
+
}
|
|
977
|
+
/** One chain-recognized active writer on {@link GitvaultVaultRecord.writer_set} — the on-chain shape only; `gateway_blocked_at` (gateway-only) rides {@link GitvaultVaultIneligibleMember} instead. */
|
|
978
|
+
export interface GitvaultVaultWriterSetEntry {
|
|
979
|
+
writer_key_id: string;
|
|
980
|
+
principal_id: string;
|
|
981
|
+
authorization_kind: "writer" | "handoff";
|
|
982
|
+
admitted_generation: string;
|
|
983
|
+
admitted_head_sha256: string;
|
|
984
|
+
}
|
|
985
|
+
/** An org member eligible to become a writer (active membership at role developer+, a published possession-verified signing key) who is NOT yet in {@link GitvaultVaultRecord.writer_set}'s `writers` — a candidate for the "writer"-door `add_writer_key` ({@link GitvaultVault.reconcileWriterAdmissions}). */
|
|
986
|
+
export interface GitvaultVaultPendingWriter {
|
|
987
|
+
principal_id: string;
|
|
988
|
+
writer_key_id: string;
|
|
989
|
+
}
|
|
990
|
+
/** A chain-recognized active writer the gateway has flagged for removal — still active on-chain, pending the next `rotate_epoch{writer_set_update}`. */
|
|
991
|
+
export interface GitvaultVaultIneligibleMember {
|
|
992
|
+
principal_id: string;
|
|
993
|
+
writer_key_id: string;
|
|
994
|
+
gateway_blocked_at: string | null;
|
|
995
|
+
reason: "membership_revoked" | "role_below_developer" | "encryption_key_revoked" | "gateway_blocked_pending_removal";
|
|
913
996
|
}
|
|
914
997
|
/**
|
|
915
998
|
* {@link GitvaultTransport.getState}'s result — the SAME bytes the per-object
|
|
@@ -1080,6 +1163,26 @@ export declare const GITVAULT_AUTO_GC_GENERATIONS_DEFAULT = 32;
|
|
|
1080
1163
|
export declare function readGitvaultAutoGcThreshold(targetRepoDir: string): Promise<number>;
|
|
1081
1164
|
/** Set this checkout's auto-gc threshold. `0` disables auto-gc entirely. */
|
|
1082
1165
|
export declare function writeGitvaultAutoGcThreshold(targetRepoDir: string, generations: number): Promise<void>;
|
|
1166
|
+
/**
|
|
1167
|
+
* {@link GitvaultVault.ensureRepoState}'s report when a cold keystore was
|
|
1168
|
+
* restored from its own envelope (gitvault-agent-envelopes D4). `trust` is
|
|
1169
|
+
* `receipt` only when a creator-held recovery receipt pinned genesis;
|
|
1170
|
+
* `platform_attested` means the control plane's signed allocation matched —
|
|
1171
|
+
* consistency the platform itself vouches for, so `independently_verified`
|
|
1172
|
+
* is `false` there and this label must never be read as end-to-end
|
|
1173
|
+
* authentication. `continuity` is `pinned` when this keystore had already
|
|
1174
|
+
* seen this genesis (a later open), `first_seen` on the first.
|
|
1175
|
+
*/
|
|
1176
|
+
export interface GitvaultColdOpenResult {
|
|
1177
|
+
repo_id: string;
|
|
1178
|
+
org_id: string;
|
|
1179
|
+
provenance: "restored_from_envelope";
|
|
1180
|
+
trust: "receipt" | "platform_attested" | "unauthenticated_salvage";
|
|
1181
|
+
continuity: "first_seen" | "pinned";
|
|
1182
|
+
independently_verified: boolean;
|
|
1183
|
+
epoch: string;
|
|
1184
|
+
recipient_fingerprint: string;
|
|
1185
|
+
}
|
|
1083
1186
|
export interface GitvaultVaultOptions {
|
|
1084
1187
|
keystore: GitvaultKeystore;
|
|
1085
1188
|
transport: GitvaultTransport;
|
|
@@ -1092,6 +1195,15 @@ export interface GitvaultVaultOptions {
|
|
|
1092
1195
|
conflict_retries?: number;
|
|
1093
1196
|
/** The signing service key resolved through the registry — when supplied, control-plane-signed messages (cutoff tickets) are signature-checked. */
|
|
1094
1197
|
service_public_key?: Uint8Array | string;
|
|
1198
|
+
/**
|
|
1199
|
+
* Consult round 2 §5: an ordinary open REFUSES a cold restore whose genesis
|
|
1200
|
+
* the control plane cannot attest (no signed allocation on the vault
|
|
1201
|
+
* record) — a data-path that cannot forge the allocation could otherwise
|
|
1202
|
+
* simply omit it and hand the client a fabricated vault. Only the explicit
|
|
1203
|
+
* recovery flow sets this, and the result still says
|
|
1204
|
+
* `unauthenticated_salvage`.
|
|
1205
|
+
*/
|
|
1206
|
+
allow_unauthenticated_salvage?: boolean;
|
|
1095
1207
|
}
|
|
1096
1208
|
/** How a checkpoint-bearing head binds a `retention_cutoff` ticket and expires roots (§4.5a / §4.5). */
|
|
1097
1209
|
export interface GitvaultCutoffOptions {
|
|
@@ -1110,6 +1222,19 @@ export interface GitvaultEncounteredRotation {
|
|
|
1110
1222
|
/** == `payload.new_epoch` == the head's own `epoch`. */
|
|
1111
1223
|
epoch: string;
|
|
1112
1224
|
payload: GitvaultRotateEpochPayload;
|
|
1225
|
+
/**
|
|
1226
|
+
* gitvault-multi-writer rev 47 — the writer who actually signed THIS
|
|
1227
|
+
* rotation head (already resolved + signature-verified by the forward
|
|
1228
|
+
* chain walk at the point this was collected — never the vault's fixed
|
|
1229
|
+
* genesis creator in a multi-writer vault). Optional: the BACKWARD
|
|
1230
|
+
* catch-up walk in `verifyToNewest` (decrypt-lag recovery) does not yet
|
|
1231
|
+
* resolve this for a rotation it discovers walking `prev_sha256`
|
|
1232
|
+
* backward from `lastHead` — a documented, narrower remaining gap
|
|
1233
|
+
* distinct from the forward walk's own full fix; `openEpochRotationForRecipient`
|
|
1234
|
+
* falls back to the vault's genesis-creator key when absent, byte-identical
|
|
1235
|
+
* to this field's pre-rev-47 non-existence.
|
|
1236
|
+
*/
|
|
1237
|
+
signing_pubkey?: string;
|
|
1113
1238
|
}
|
|
1114
1239
|
/** Named detail for a reader's own `GITVAULT_EPOCH_NOT_OPENABLE` / decrypt stop point (Part C: `repos fsck`'s honest `chain_verified_to` vs `decryptable_to` split). */
|
|
1115
1240
|
export interface GitvaultEpochDecryptFailure {
|
|
@@ -1185,6 +1310,51 @@ export interface GitvaultReconcileEnvelopeRecipientsResult {
|
|
|
1185
1310
|
/** Directory entries this call could not (or, for `pinned_key_mismatch`, would not) wrap. */
|
|
1186
1311
|
skipped: GitvaultReconcileEnvelopeRecipientsSkipped[];
|
|
1187
1312
|
}
|
|
1313
|
+
/** One `pending_writers[]` entry {@link GitvaultVault.reconcileWriterAdmissions} admitted via a fresh `add_writer_key{"writer"}` head. */
|
|
1314
|
+
export interface GitvaultReconcileWriterAdmissionsAdmitted {
|
|
1315
|
+
principal_id: string;
|
|
1316
|
+
writer_key_id: string;
|
|
1317
|
+
generation: string;
|
|
1318
|
+
}
|
|
1319
|
+
/** Why {@link GitvaultVault.reconcileWriterAdmissions} did NOT admit a `pending_writers[]` entry it otherwise would have. */
|
|
1320
|
+
export type GitvaultReconcileWriterAdmissionsSkipReason = "missing_signing_pubkey" | "invalid_signing_pubkey";
|
|
1321
|
+
export interface GitvaultReconcileWriterAdmissionsSkipped {
|
|
1322
|
+
principal_id: string;
|
|
1323
|
+
writer_key_id: string;
|
|
1324
|
+
reason: GitvaultReconcileWriterAdmissionsSkipReason;
|
|
1325
|
+
}
|
|
1326
|
+
/**
|
|
1327
|
+
* {@link GitvaultVault.reconcileWriterAdmissions}'s full per-candidate
|
|
1328
|
+
* breakdown (task 5.7). Structurally parallel to
|
|
1329
|
+
* {@link GitvaultReconcileEnvelopeRecipientsResult} (same repo/wrapped-or-
|
|
1330
|
+
* admitted/already-covered/skipped shape), but this reconcile submits a REAL
|
|
1331
|
+
* chain head per admission (one `add_writer_key{"writer"}` transition per
|
|
1332
|
+
* candidate — the protocol allows only one added writer per head) rather
|
|
1333
|
+
* than an out-of-band object upload, so it is never fully parallel: each
|
|
1334
|
+
* admission materializes fresh against the PRIOR admission's own updated
|
|
1335
|
+
* writer set.
|
|
1336
|
+
*/
|
|
1337
|
+
export interface GitvaultReconcileWriterAdmissionsResult {
|
|
1338
|
+
repo_id: string;
|
|
1339
|
+
org_id: string;
|
|
1340
|
+
/**
|
|
1341
|
+
* `false` exactly when THIS session's own key is not (or is no longer) an
|
|
1342
|
+
* active writer — the "writer" door's authorization is the carrying
|
|
1343
|
+
* head's own signer, so an ineligible session cannot admit anyone, and
|
|
1344
|
+
* this call returns immediately with every other field empty. Distinct
|
|
1345
|
+
* from a genuinely empty `pending_writers[]` (still `eligible: true`,
|
|
1346
|
+
* there was simply nothing to do) — otherwise both cases produce the
|
|
1347
|
+
* SAME all-empty shape and a caller could not tell "nothing needed
|
|
1348
|
+
* doing" from "I have no authority to do anything here."
|
|
1349
|
+
*/
|
|
1350
|
+
eligible: boolean;
|
|
1351
|
+
/** `pending_writers[]` entries this call admitted this call, each via its own head. */
|
|
1352
|
+
admitted: GitvaultReconcileWriterAdmissionsAdmitted[];
|
|
1353
|
+
/** `writer_key_id`s already active before (or, for a raced admission, as of) this call — no action taken. */
|
|
1354
|
+
already_covered: string[];
|
|
1355
|
+
/** `pending_writers[]` entries this call could not admit. */
|
|
1356
|
+
skipped: GitvaultReconcileWriterAdmissionsSkipped[];
|
|
1357
|
+
}
|
|
1188
1358
|
export interface GitvaultPushOptions {
|
|
1189
1359
|
transaction: GitvaultRefTransaction;
|
|
1190
1360
|
/** New `HEAD` target for the published ref_state; carried forward when omitted. */
|
|
@@ -1294,9 +1464,22 @@ export interface GitvaultRotationResult {
|
|
|
1294
1464
|
stored_bytes_sha256: string;
|
|
1295
1465
|
principal_ids: string[];
|
|
1296
1466
|
} | null;
|
|
1467
|
+
/**
|
|
1468
|
+
* gitvault-multi-writer (task 5.9, D6/D227) — writer keys this SAME head
|
|
1469
|
+
* removed via a folded `writer_set_update`, each with the reason it was
|
|
1470
|
+
* removed for. Empty (never omitted) when nothing needed removing — the
|
|
1471
|
+
* common case, matching `excluded_keyless_principal_ids`' own
|
|
1472
|
+
* always-present-possibly-empty shape rather than `pin_manifest_published`'s
|
|
1473
|
+
* `| null`.
|
|
1474
|
+
*/
|
|
1475
|
+
writers_removed: {
|
|
1476
|
+
writer_key_id: string;
|
|
1477
|
+
principal_id: string;
|
|
1478
|
+
reason: "member_removed" | "writer_key_revoked" | "epoch_secret_exposed";
|
|
1479
|
+
}[];
|
|
1297
1480
|
}
|
|
1298
1481
|
/**
|
|
1299
|
-
* What {@link GitvaultVault.planPush} reports
|
|
1482
|
+
* What {@link GitvaultVault.planPush} reports — a REAL
|
|
1300
1483
|
* local computation, not an estimate: every number here comes from actually
|
|
1301
1484
|
* building the packs (or checkpoint set) and actually sealing/encrypting
|
|
1302
1485
|
* them, exactly as a real `push` would. `would_admit_generation` is what this
|
|
@@ -1360,6 +1543,7 @@ export interface GitvaultBuiltCheckpoint {
|
|
|
1360
1543
|
}
|
|
1361
1544
|
/** A transport-agnostic view of git ops the publication needs (the local repository). */
|
|
1362
1545
|
export declare class GitvaultVault {
|
|
1546
|
+
#private;
|
|
1363
1547
|
readonly keystore: GitvaultKeystore;
|
|
1364
1548
|
readonly transport: GitvaultTransport;
|
|
1365
1549
|
readonly repoId: string;
|
|
@@ -1405,6 +1589,7 @@ export declare class GitvaultVault {
|
|
|
1405
1589
|
private stateRestorePlan;
|
|
1406
1590
|
private readonly retries;
|
|
1407
1591
|
private readonly servicePublicKey;
|
|
1592
|
+
private readonly allowUnauthenticatedSalvage;
|
|
1408
1593
|
private genesisCache;
|
|
1409
1594
|
/**
|
|
1410
1595
|
* gitvault-byo-primary-bucket task 3.2 — this vault's resolved BYO write
|
|
@@ -1419,6 +1604,40 @@ export declare class GitvaultVault {
|
|
|
1419
1604
|
constructor(options: GitvaultVaultOptions);
|
|
1420
1605
|
static open(options: GitvaultVaultOptions): GitvaultVault;
|
|
1421
1606
|
repoFile(): GitvaultRepoFile;
|
|
1607
|
+
/**
|
|
1608
|
+
* gitvault-agent-envelopes D4 — the COLD OPEN. A keystore that holds an
|
|
1609
|
+
* identity but no repo file for this vault (a member joining from a fresh
|
|
1610
|
+
* machine, or a creator whose repo file was lost) restores `K_repo` from
|
|
1611
|
+
* its OWN `key_envelope` instead of dying `GITVAULT_REPO_STATE_MISSING`:
|
|
1612
|
+
*
|
|
1613
|
+
* 1. genesis (the writer-key source) is fetched and signature-verified;
|
|
1614
|
+
* 2. its creator fingerprints are compared against the control plane's
|
|
1615
|
+
* SIGNED allocation record — `platform_attested`, never `receipt`
|
|
1616
|
+
* (the platform serves both sides of that comparison; a substituted
|
|
1617
|
+
* genesis needs a substituted allocation, which the org's owners can
|
|
1618
|
+
* see — TOFU + audit, human-envelopes D4's tier);
|
|
1619
|
+
* 3. the envelope-recipients read says whether THIS fingerprint is
|
|
1620
|
+
* covered — if not, `GITVAULT_ENVELOPE_PENDING` names the key-holders
|
|
1621
|
+
* who can fulfil and the exact next actions (never a terminal error:
|
|
1622
|
+
* the desired state already records this member; any key-holder's
|
|
1623
|
+
* next gitvault operation wraps);
|
|
1624
|
+
* 4. the base envelope is fetched, opened, and the repo file written
|
|
1625
|
+
* `restored_from_envelope` with the genesis hash PINNED (a later open
|
|
1626
|
+
* seeing a different genesis for this repo_id refuses
|
|
1627
|
+
* `VAULT_CREATION_CONFLICT`).
|
|
1628
|
+
*
|
|
1629
|
+
* Rotation epochs are NOT opened here — `verifyToNewest` walks them and
|
|
1630
|
+
* opens each rotation-scoped envelope this identity is included in, exactly
|
|
1631
|
+
* as it does for every other reader (`openEpochRotationForRecipient`).
|
|
1632
|
+
*
|
|
1633
|
+
* Returns `null` when the repo file already existed (nothing restored).
|
|
1634
|
+
*/
|
|
1635
|
+
ensureRepoState(): Promise<GitvaultColdOpenResult | null>;
|
|
1636
|
+
/** {@link open}, but a missing repo file triggers {@link ensureRepoState} first. */
|
|
1637
|
+
static openOrRestore(options: GitvaultVaultOptions): Promise<{
|
|
1638
|
+
vault: GitvaultVault;
|
|
1639
|
+
restored: GitvaultColdOpenResult | null;
|
|
1640
|
+
}>;
|
|
1422
1641
|
private kRepo;
|
|
1423
1642
|
private epoch;
|
|
1424
1643
|
/**
|
|
@@ -1660,10 +1879,9 @@ export declare class GitvaultVault {
|
|
|
1660
1879
|
* **This is task 1.1's residual WORKAROUND, not the design D5 ideal.** D5
|
|
1661
1880
|
* describes a recipient-set change as an epoch rotation — "history epochs
|
|
1662
1881
|
* stay wrapped as they were; a new member reads from their first covered
|
|
1663
|
-
* epoch forward" — which needs a protocol revision
|
|
1664
|
-
*
|
|
1665
|
-
*
|
|
1666
|
-
* speak of yet). What this method actually does, legally, without any
|
|
1882
|
+
* epoch forward" — which needs a protocol revision: V0 pins `epoch` to
|
|
1883
|
+
* the single constant `GITVAULT_GENESIS_EPOCH` on every head, so there
|
|
1884
|
+
* is no "forward" to speak of. What this method actually does, legally, without any
|
|
1667
1885
|
* protocol change: `key_envelope` objects are never head-referenced (not
|
|
1668
1886
|
* even genesis's own envelope is), so uploading an ADDITIONAL one at
|
|
1669
1887
|
* `envelopes/<current epoch>/<recipient fingerprint>` for a missing
|
|
@@ -1686,7 +1904,7 @@ export declare class GitvaultVault {
|
|
|
1686
1904
|
* this SDK does not make unattended.
|
|
1687
1905
|
*
|
|
1688
1906
|
* **The gateway directory route carries `public_key` on every row**
|
|
1689
|
-
* (`GET /orgs/v1/:org_id/encryption-keys
|
|
1907
|
+
* (`GET /orgs/v1/:org_id/encryption-keys` — see the
|
|
1690
1908
|
* doc comment on {@link GitvaultOrgEncryptionKeyEntry}), so against a
|
|
1691
1909
|
* current gateway entries actually wrap. A directory entry that arrives
|
|
1692
1910
|
* WITHOUT the field (an older/rolling-deploy gateway) is still tolerated
|
|
@@ -1719,6 +1937,35 @@ export declare class GitvaultVault {
|
|
|
1719
1937
|
*/
|
|
1720
1938
|
signer(): Uint8Array;
|
|
1721
1939
|
private writerKeyId;
|
|
1940
|
+
/**
|
|
1941
|
+
* gitvault-multi-writer (task 5.8) — the push pre-check: before signing an
|
|
1942
|
+
* ORDINARY head (any operation that expects this session to already be an
|
|
1943
|
+
* active writer), refuse EARLY and LOCALLY when this session's own key is
|
|
1944
|
+
* not (or is no longer) an active writer, rather than let real
|
|
1945
|
+
* crypto/upload work run only to be refused by the gateway with a less
|
|
1946
|
+
* specific message once the head finally reaches it. Reads the FRESHLY-
|
|
1947
|
+
* pinned `writer_set_pin`; every call site below calls this immediately
|
|
1948
|
+
* after its own `materialize()`/`verifyToNewest()` (same generation the
|
|
1949
|
+
* caller is about to build against), so this performs no verification of
|
|
1950
|
+
* its own — it only reads what the caller already froze.
|
|
1951
|
+
*
|
|
1952
|
+
* `removedMidRace` (design D8/D10) distinguishes the two shapes this
|
|
1953
|
+
* refusal takes: `false` (the default) is the ORDINARY pre-check — this
|
|
1954
|
+
* session was never (or is not currently) an admitted writer, thrown as
|
|
1955
|
+
* `GITVAULT_WRITER_NOT_ADMITTED`. `true` is the CAS-LOSER path
|
|
1956
|
+
* specifically: a retry, after re-materializing from the winner, that
|
|
1957
|
+
* discovers THIS session's own key was removed by whatever won the race —
|
|
1958
|
+
* "stop if removed" in D8's loser-rule sequence (fetch winner → verify →
|
|
1959
|
+
* apply writer transition → stop if removed → rebase → rebuild → bounded
|
|
1960
|
+
* backoff) — thrown as the more specific, client-local
|
|
1961
|
+
* `GITVAULT_WRITER_REMOVED` (D10) instead: a real prior attempt just lost
|
|
1962
|
+
* to a removal, not a caller who was never eligible.
|
|
1963
|
+
*
|
|
1964
|
+
* Deliberately NOT called for a "handoff"-door `add_writer_key` head
|
|
1965
|
+
* ({@link submitWriterActivationHead}): there the signer is BY DESIGN not
|
|
1966
|
+
* yet a writer — becoming one is what that exact head does.
|
|
1967
|
+
*/
|
|
1968
|
+
private assertCallerIsWriter;
|
|
1722
1969
|
/** The owner's full signing keypair, or `GITVAULT_READ_ONLY` — same refusal path as {@link signer}, which returns only the seed; {@link sealKeyEnvelope} needs both halves. */
|
|
1723
1970
|
private signingKeypair;
|
|
1724
1971
|
private buildRefState;
|
|
@@ -1833,7 +2080,7 @@ export declare class GitvaultVault {
|
|
|
1833
2080
|
*/
|
|
1834
2081
|
push(options: GitvaultPushOptions): Promise<GitvaultPublishResult>;
|
|
1835
2082
|
/**
|
|
1836
|
-
* A REAL preview of what {@link push} would publish
|
|
2083
|
+
* A REAL preview of what {@link push} would publish
|
|
1837
2084
|
* — runs the SAME local pipeline `push` runs (materialize → evaluate →
|
|
1838
2085
|
* evolve retention roots → build refState/retentionRoots → build packs or a
|
|
1839
2086
|
* checkpoint set → seal/encrypt) and stops BEFORE the two network
|
|
@@ -1925,9 +2172,9 @@ export declare class GitvaultVault {
|
|
|
1925
2172
|
* `POST …/object-reads` rejected every `recipient_pin_manifest` read
|
|
1926
2173
|
* (its null-`idScalar` validation was hardcoded to `key_envelope`'s
|
|
1927
2174
|
* `{epoch, recipient_fingerprint}` shape, never generalized when D197
|
|
1928
|
-
* shipped the second path-addressed kind),
|
|
1929
|
-
*
|
|
1930
|
-
*
|
|
2175
|
+
* shipped the second path-addressed kind), which 400'd the network
|
|
2176
|
+
* fallback below. That gateway bug is fixed: the network path works for
|
|
2177
|
+
* any keystore, including
|
|
1931
2178
|
* §4.11's fresh-client "SEEDS its local pin file from it" onboarding.
|
|
1932
2179
|
* The cache stays purely as the round-trip saver described above.
|
|
1933
2180
|
*/
|
|
@@ -2012,10 +2259,10 @@ export declare class GitvaultVault {
|
|
|
2012
2259
|
* `publishPinManifestUpdate` is an ORDINARY admission (`transition:
|
|
2013
2260
|
* null`) and is therefore itself refused `EPOCH_ROTATION_REQUIRED` while
|
|
2014
2261
|
* this vault has an urgent/migration condition outstanding — the exact
|
|
2015
|
-
* state a `rotateEpoch` call is being made to clear.
|
|
2016
|
-
*
|
|
2017
|
-
*
|
|
2018
|
-
*
|
|
2262
|
+
* state a `rotateEpoch` call is being made to clear. On an
|
|
2263
|
+
* `epoch_secret_exposed` rekey `/confirm` mints a receipt server-side,
|
|
2264
|
+
* but the ordinary push that would publish it never admits. Pass the
|
|
2265
|
+
* pending receipted updates
|
|
2019
2266
|
* here instead — they ride the SAME head as this rotation's `transition`,
|
|
2020
2267
|
* which IS `EPOCH_ROTATION_REQUIRED`'s own escape valve, so the publish
|
|
2021
2268
|
* is no longer blocked. **This does NOT include these principals in
|
|
@@ -2050,6 +2297,19 @@ export declare class GitvaultVault {
|
|
|
2050
2297
|
ek_fingerprint: string;
|
|
2051
2298
|
receipt: GitvaultRecipientConfirmationReceipt;
|
|
2052
2299
|
}[];
|
|
2300
|
+
/**
|
|
2301
|
+
* gitvault-multi-writer (task 5.9, D7/D228) — an outstanding
|
|
2302
|
+
* gateway-blocked writer set (`ineligible_members`, checked fresh on
|
|
2303
|
+
* every call — see the `writer_set_update` fold-in below) is ALWAYS
|
|
2304
|
+
* folded into this rotation automatically; this flag is the EXPLICIT
|
|
2305
|
+
* owner + step-up acknowledgment D7 requires ONLY when that fold-in
|
|
2306
|
+
* would empty the vault's writer set entirely (the sole surviving
|
|
2307
|
+
* writer was itself gateway-blocked) — the declared read-only terminal.
|
|
2308
|
+
* Every OTHER case that would empty the writer set is refused
|
|
2309
|
+
* `EPOCH_ROTATION_WOULD_LEAVE_VAULT_UNCOVERED` regardless of this flag;
|
|
2310
|
+
* it widens nothing beyond that one specific, named exception.
|
|
2311
|
+
*/
|
|
2312
|
+
force_empty_writer_set?: boolean;
|
|
2053
2313
|
}): Promise<GitvaultRotationResult>;
|
|
2054
2314
|
/**
|
|
2055
2315
|
* The ONE fully self-contained rotation entry point: declares
|
|
@@ -2060,6 +2320,104 @@ export declare class GitvaultVault {
|
|
|
2060
2320
|
rotateEpochForKeyRevocation(principalId: string, options?: {
|
|
2061
2321
|
client_idempotency_key?: string;
|
|
2062
2322
|
}): Promise<GitvaultRotationResult>;
|
|
2323
|
+
/**
|
|
2324
|
+
* Submit a REF-NEUTRAL `add_writer_key{authorization.kind:"handoff"}`
|
|
2325
|
+
* activation head — no ref/checkpoint/repair changes ride it (protocol
|
|
2326
|
+
* §4.17's own "ref-neutral head shape... for the activation head" rule),
|
|
2327
|
+
* built by `publishGeneration` the SAME way every ordinary no-op push
|
|
2328
|
+
* would be (`refs`/`head_target` carried forward from `base` UNCHANGED),
|
|
2329
|
+
* just with `transition` set. Retries `HEAD_CAS_CONFLICT` like every
|
|
2330
|
+
* other publish path here. The caller (`resume()`) has already built and
|
|
2331
|
+
* locally sanity-checked the grant + acceptance; this method only reads
|
|
2332
|
+
* the FRESHLY-verified `writer_set_pin` (set by the `materialize()` this
|
|
2333
|
+
* same call performs, mirroring `push()`'s own base-then-retry shape) to
|
|
2334
|
+
* compute `base_writer_set`/`next_writer_set`, signs the head under
|
|
2335
|
+
* `this.signer()` (the ADDED key itself — protocol §4.17's "head signed
|
|
2336
|
+
* by the added key" — since `signer()` reads straight from THIS
|
|
2337
|
+
* keystore's identity, and `resume()` mints/loads that identity before
|
|
2338
|
+
* ever reaching this call), and advances the local `writer_set_pin` on
|
|
2339
|
+
* success so a subsequent read reflects the new writer without a second
|
|
2340
|
+
* chain walk.
|
|
2341
|
+
*
|
|
2342
|
+
* Crash-resumable (task 5.6): the chain burns `handoff_id` single-use, so
|
|
2343
|
+
* a naive resubmission after a crash between a prior attempt's successful
|
|
2344
|
+
* admission and this checkout learning about it would be refused
|
|
2345
|
+
* VALIDATION_FAILED. Returns `{outcome:"already_admitted", generation}`
|
|
2346
|
+
* instead of submitting anything whenever the freshly-verified writer set
|
|
2347
|
+
* ALREADY contains `input.addedWriterKeyId` — the caller treats both
|
|
2348
|
+
* outcomes as success (the writer IS active either way) and proceeds.
|
|
2349
|
+
*/
|
|
2350
|
+
submitWriterActivationHead(input: {
|
|
2351
|
+
addedWriterKeyId: string;
|
|
2352
|
+
addedSigningPubkeyB64u: string;
|
|
2353
|
+
addedPrincipalId: string;
|
|
2354
|
+
handoffId: string;
|
|
2355
|
+
grant: Record<string, unknown>;
|
|
2356
|
+
acceptance: Record<string, unknown>;
|
|
2357
|
+
}): Promise<{
|
|
2358
|
+
outcome: "activated";
|
|
2359
|
+
result: GitvaultPublishResult;
|
|
2360
|
+
} | {
|
|
2361
|
+
outcome: "already_admitted";
|
|
2362
|
+
generation: string;
|
|
2363
|
+
}>;
|
|
2364
|
+
/**
|
|
2365
|
+
* gitvault-multi-writer (task 5.7) — the "writer"-door twin of {@link
|
|
2366
|
+
* submitWriterActivationHead}: an ALREADY-ACTIVE writer (this vault
|
|
2367
|
+
* session's own key) admits `input`, an eligible org member with a
|
|
2368
|
+
* published signing key but no writer standing yet, via a fresh
|
|
2369
|
+
* `add_writer_key{"writer"}` head. No grant/acceptance — the carrying
|
|
2370
|
+
* head's own signer being an active writer at the predecessor generation
|
|
2371
|
+
* IS the authorization (`validateAddWriterKeyPayload`'s `"writer"`
|
|
2372
|
+
* branch), re-verified admission-side by `checkTransitionAdmissible`.
|
|
2373
|
+
* Task 5.8 adds the SAME local pre-check every other head-signing path
|
|
2374
|
+
* gets: if THIS session's own key is not (or is no longer) an active
|
|
2375
|
+
* writer, refuse EARLY and LOCALLY (`GITVAULT_WRITER_NOT_ADMITTED` /
|
|
2376
|
+
* `GITVAULT_WRITER_REMOVED`) rather than let the head reach the gateway
|
|
2377
|
+
* only to be refused there — redundant with `reconcileWriterAdmissions`'s
|
|
2378
|
+
* own upfront gate for that caller, but this method is public and a
|
|
2379
|
+
* direct caller should get the same fast, specific refusal.
|
|
2380
|
+
*/
|
|
2381
|
+
admitPendingWriter(input: {
|
|
2382
|
+
addedWriterKeyId: string;
|
|
2383
|
+
addedSigningPubkeyB64u: string;
|
|
2384
|
+
addedPrincipalId: string;
|
|
2385
|
+
}): Promise<{
|
|
2386
|
+
outcome: "activated";
|
|
2387
|
+
result: GitvaultPublishResult;
|
|
2388
|
+
} | {
|
|
2389
|
+
outcome: "already_admitted";
|
|
2390
|
+
generation: string;
|
|
2391
|
+
}>;
|
|
2392
|
+
/**
|
|
2393
|
+
* gitvault-multi-writer (task 5.7) — the vault's OWN writer-admission
|
|
2394
|
+
* reconcile: reads `pending_writers[]` off the vault record (eligible org
|
|
2395
|
+
* members with no writer standing yet), resolves each candidate's
|
|
2396
|
+
* published signing key off the org's encryption-key directory (the SAME
|
|
2397
|
+
* `/orgs/v1/:org_id/encryption-keys` row {@link
|
|
2398
|
+
* reconcileEnvelopeRecipients} reads, widened D9 to also carry the
|
|
2399
|
+
* signing half), and admits each via {@link admitPendingWriter} — one
|
|
2400
|
+
* `add_writer_key{"writer"}` head per candidate, sequentially: each
|
|
2401
|
+
* admission materializes fresh against the PRIOR one's own updated writer
|
|
2402
|
+
* set, so there is no batched/parallel form.
|
|
2403
|
+
*
|
|
2404
|
+
* Requires THIS session's own key to already be an active writer (the
|
|
2405
|
+
* chain's own authorization rule for the "writer" door) — checked ONCE,
|
|
2406
|
+
* upfront, off the locally-pinned `writer_set_pin` (no network call),
|
|
2407
|
+
* rather than discovered N times over from N identical gateway refusals:
|
|
2408
|
+
* a session that reached this call already pushed successfully as an
|
|
2409
|
+
* active writer in every wired call site (push/snapshot/deploy) OR is a
|
|
2410
|
+
* member that simply is not one yet (session-start/read) — the SAME
|
|
2411
|
+
* "not yet admitted" case {@link Gitvault.push}'s own pre-push check
|
|
2412
|
+
* (task 5.8) names, not a new refusal shape. Returns `{eligible: false}`
|
|
2413
|
+
* with every other field empty (never throws) for that case: every OTHER
|
|
2414
|
+
* `pending_writers[]` entry would fail identically, so there is nothing
|
|
2415
|
+
* this call can usefully do, and "I am not a writer" is not this vault's
|
|
2416
|
+
* fault — but it is distinguishable from "there was nothing pending"
|
|
2417
|
+
* (`eligible: true`, still all empty), which matters to a caller trying
|
|
2418
|
+
* to explain an all-empty result to a human.
|
|
2419
|
+
*/
|
|
2420
|
+
reconcileWriterAdmissions(): Promise<GitvaultReconcileWriterAdmissionsResult>;
|
|
2063
2421
|
/**
|
|
2064
2422
|
* Publish a repair head over `base_generation` (§4.3): superseded tips that
|
|
2065
2423
|
* the repaired state no longer reaches enter the retention-root map with
|