@run402/sdk 4.95.0 → 4.97.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.
Files changed (271) hide show
  1. package/README.md +27 -27
  2. package/core-dist/keystore.d.ts +1 -1
  3. package/core-dist/keystore.js +1 -1
  4. package/dist/errors.d.ts +5 -5
  5. package/dist/errors.d.ts.map +1 -1
  6. package/dist/errors.js +2 -2
  7. package/dist/errors.js.map +1 -1
  8. package/dist/grant-key-credentials.d.ts +38 -0
  9. package/dist/grant-key-credentials.d.ts.map +1 -0
  10. package/dist/grant-key-credentials.js +42 -0
  11. package/dist/grant-key-credentials.js.map +1 -0
  12. package/dist/index.d.ts +16 -23
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +14 -21
  15. package/dist/index.js.map +1 -1
  16. package/dist/namespaces/billing.d.ts +1 -1
  17. package/dist/namespaces/billing.js +1 -1
  18. package/dist/namespaces/buzz.js +1 -1
  19. package/dist/namespaces/buzz.js.map +1 -1
  20. package/dist/namespaces/credentials.d.ts +4 -4
  21. package/dist/namespaces/credentials.js +4 -4
  22. package/dist/namespaces/deploy.d.ts +5 -5
  23. package/dist/namespaces/deploy.d.ts.map +1 -1
  24. package/dist/namespaces/deploy.js +25 -25
  25. package/dist/namespaces/deploy.js.map +1 -1
  26. package/dist/namespaces/deploy.types.d.ts +17 -17
  27. package/dist/namespaces/deploy.types.d.ts.map +1 -1
  28. package/dist/namespaces/domains.d.ts +1 -1
  29. package/dist/namespaces/domains.js +1 -1
  30. package/dist/namespaces/errors.d.ts +1 -1
  31. package/dist/namespaces/errors.js +2 -2
  32. package/dist/namespaces/escalations.d.ts +2 -2
  33. package/dist/namespaces/escalations.js +2 -2
  34. package/dist/namespaces/escalations.types.d.ts +3 -3
  35. package/dist/namespaces/escalations.types.d.ts.map +1 -1
  36. package/dist/namespaces/events.d.ts +1 -1
  37. package/dist/namespaces/events.js +1 -1
  38. package/dist/namespaces/functions.js +1 -1
  39. package/dist/namespaces/functions.js.map +1 -1
  40. package/dist/namespaces/grants.d.ts +43 -9
  41. package/dist/namespaces/grants.d.ts.map +1 -1
  42. package/dist/namespaces/grants.js +99 -10
  43. package/dist/namespaces/grants.js.map +1 -1
  44. package/dist/namespaces/grants.types.d.ts +120 -15
  45. package/dist/namespaces/grants.types.d.ts.map +1 -1
  46. package/dist/namespaces/grants.types.js +12 -3
  47. package/dist/namespaces/grants.types.js.map +1 -1
  48. package/dist/namespaces/identity-links.types.d.ts +2 -2
  49. package/dist/namespaces/identity-links.types.d.ts.map +1 -1
  50. package/dist/namespaces/org.d.ts +3 -3
  51. package/dist/namespaces/org.js +3 -3
  52. package/dist/namespaces/org.types.d.ts +3 -3
  53. package/dist/namespaces/pay.js +1 -1
  54. package/dist/namespaces/projects.d.ts +1 -1
  55. package/dist/namespaces/projects.js +1 -1
  56. package/dist/namespaces/{gitvault.d.ts → repos.d.ts} +436 -449
  57. package/dist/namespaces/repos.d.ts.map +1 -0
  58. package/dist/namespaces/{gitvault.js → repos.js} +452 -460
  59. package/dist/namespaces/repos.js.map +1 -0
  60. package/dist/namespaces/rooms.d.ts +3 -3
  61. package/dist/namespaces/rooms.js +5 -5
  62. package/dist/namespaces/rooms.js.map +1 -1
  63. package/dist/namespaces/session.d.ts +2 -2
  64. package/dist/namespaces/session.d.ts.map +1 -1
  65. package/dist/namespaces/session.js +2 -2
  66. package/dist/namespaces/session.js.map +1 -1
  67. package/dist/namespaces/tier.d.ts +3 -3
  68. package/dist/namespaces/tier.d.ts.map +1 -1
  69. package/dist/namespaces/{gitvault.crypto.d.ts → vault.crypto.d.ts} +141 -141
  70. package/dist/namespaces/vault.crypto.d.ts.map +1 -0
  71. package/dist/namespaces/{gitvault.crypto.js → vault.crypto.js} +173 -173
  72. package/dist/namespaces/vault.crypto.js.map +1 -0
  73. package/dist/namespaces/{gitvault.types.d.ts → vault.types.d.ts} +136 -136
  74. package/dist/namespaces/vault.types.d.ts.map +1 -0
  75. package/dist/namespaces/{gitvault.types.js → vault.types.js} +4 -4
  76. package/dist/namespaces/vault.types.js.map +1 -0
  77. package/dist/node/bearer-redeem-key.d.ts +1 -1
  78. package/dist/node/bearer-redeem-key.js +5 -5
  79. package/dist/node/bearer-redeem-key.js.map +1 -1
  80. package/dist/node/credentials.d.ts +9 -9
  81. package/dist/node/credentials.d.ts.map +1 -1
  82. package/dist/node/credentials.js +12 -12
  83. package/dist/node/credentials.js.map +1 -1
  84. package/dist/node/http-dispatcher.js +5 -5
  85. package/dist/node/http-dispatcher.js.map +1 -1
  86. package/dist/node/index.d.ts +34 -34
  87. package/dist/node/index.d.ts.map +1 -1
  88. package/dist/node/index.js +41 -41
  89. package/dist/node/index.js.map +1 -1
  90. package/dist/node/{gitvault-address.d.ts → vault-address.d.ts} +42 -42
  91. package/dist/node/vault-address.d.ts.map +1 -0
  92. package/dist/node/{gitvault-address.js → vault-address.js} +43 -43
  93. package/dist/node/vault-address.js.map +1 -0
  94. package/dist/node/{gitvault-apply.d.ts → vault-apply.d.ts} +27 -27
  95. package/dist/node/vault-apply.d.ts.map +1 -0
  96. package/dist/node/{gitvault-apply.js → vault-apply.js} +38 -38
  97. package/dist/node/vault-apply.js.map +1 -0
  98. package/dist/node/vault-byo-config.d.ts +29 -0
  99. package/dist/node/vault-byo-config.d.ts.map +1 -0
  100. package/dist/node/{gitvault-byo-config.js → vault-byo-config.js} +18 -18
  101. package/dist/node/vault-byo-config.js.map +1 -0
  102. package/dist/node/vault-byo-probe.d.ts +20 -0
  103. package/dist/node/vault-byo-probe.d.ts.map +1 -0
  104. package/dist/node/vault-byo-probe.js +57 -0
  105. package/dist/node/vault-byo-probe.js.map +1 -0
  106. package/dist/node/{gitvault-creation-journal.d.ts → vault-creation-journal.d.ts} +69 -69
  107. package/dist/node/vault-creation-journal.d.ts.map +1 -0
  108. package/dist/node/{gitvault-creation-journal.js → vault-creation-journal.js} +54 -54
  109. package/dist/node/vault-creation-journal.js.map +1 -0
  110. package/dist/node/{gitvault-degraded-read.d.ts → vault-degraded-read.d.ts} +34 -34
  111. package/dist/node/vault-degraded-read.d.ts.map +1 -0
  112. package/dist/node/{gitvault-degraded-read.js → vault-degraded-read.js} +24 -24
  113. package/dist/node/vault-degraded-read.js.map +1 -0
  114. package/dist/node/{gitvault-deploy.d.ts → vault-deploy.d.ts} +67 -67
  115. package/dist/node/vault-deploy.d.ts.map +1 -0
  116. package/dist/node/{gitvault-deploy.js → vault-deploy.js} +27 -27
  117. package/dist/node/vault-deploy.js.map +1 -0
  118. package/dist/node/{gitvault-edge-fetch.d.ts → vault-edge-fetch.d.ts} +9 -9
  119. package/dist/node/vault-edge-fetch.d.ts.map +1 -0
  120. package/dist/node/{gitvault-edge-fetch.js → vault-edge-fetch.js} +11 -11
  121. package/dist/node/vault-edge-fetch.js.map +1 -0
  122. package/dist/node/{gitvault-handoff.d.ts → vault-handoff.d.ts} +9 -9
  123. package/dist/node/vault-handoff.d.ts.map +1 -0
  124. package/dist/node/{gitvault-handoff.js → vault-handoff.js} +24 -24
  125. package/dist/node/vault-handoff.js.map +1 -0
  126. package/dist/node/{gitvault-keystore.d.ts → vault-keystore.d.ts} +87 -77
  127. package/dist/node/vault-keystore.d.ts.map +1 -0
  128. package/dist/node/{gitvault-keystore.js → vault-keystore.js} +105 -68
  129. package/dist/node/vault-keystore.js.map +1 -0
  130. package/dist/node/{gitvault-member-bundle.d.ts → vault-member-bundle.d.ts} +17 -17
  131. package/dist/node/vault-member-bundle.d.ts.map +1 -0
  132. package/dist/node/{gitvault-member-bundle.js → vault-member-bundle.js} +11 -11
  133. package/dist/node/vault-member-bundle.js.map +1 -0
  134. package/dist/node/{gitvault-mirror-backend.d.ts → vault-mirror-backend.d.ts} +26 -26
  135. package/dist/node/vault-mirror-backend.d.ts.map +1 -0
  136. package/dist/node/{gitvault-mirror-backend.js → vault-mirror-backend.js} +25 -25
  137. package/dist/node/vault-mirror-backend.js.map +1 -0
  138. package/dist/node/{gitvault-mirror-config.d.ts → vault-mirror-config.d.ts} +23 -23
  139. package/dist/node/vault-mirror-config.d.ts.map +1 -0
  140. package/dist/node/{gitvault-mirror-config.js → vault-mirror-config.js} +16 -16
  141. package/dist/node/vault-mirror-config.js.map +1 -0
  142. package/dist/node/{gitvault-mirror.d.ts → vault-mirror.d.ts} +36 -36
  143. package/dist/node/vault-mirror.d.ts.map +1 -0
  144. package/dist/node/{gitvault-mirror.js → vault-mirror.js} +75 -75
  145. package/dist/node/vault-mirror.js.map +1 -0
  146. package/dist/node/{gitvault-native-crypto.d.ts → vault-native-crypto.d.ts} +10 -10
  147. package/dist/node/vault-native-crypto.d.ts.map +1 -0
  148. package/dist/node/{gitvault-native-crypto.js → vault-native-crypto.js} +16 -16
  149. package/dist/node/vault-native-crypto.js.map +1 -0
  150. package/dist/node/{gitvault-open-or-create.d.ts → vault-open-or-create.d.ts} +16 -16
  151. package/dist/node/vault-open-or-create.d.ts.map +1 -0
  152. package/dist/node/{gitvault-open-or-create.js → vault-open-or-create.js} +10 -10
  153. package/dist/node/vault-open-or-create.js.map +1 -0
  154. package/dist/node/{gitvault-prewarm.d.ts → vault-prewarm.d.ts} +13 -13
  155. package/dist/node/vault-prewarm.d.ts.map +1 -0
  156. package/dist/node/{gitvault-prewarm.js → vault-prewarm.js} +25 -25
  157. package/dist/node/vault-prewarm.js.map +1 -0
  158. package/dist/node/{gitvault-profile-scan.d.ts → vault-profile-scan.d.ts} +3 -3
  159. package/dist/node/vault-profile-scan.d.ts.map +1 -0
  160. package/dist/node/{gitvault-profile-scan.js → vault-profile-scan.js} +12 -12
  161. package/dist/node/vault-profile-scan.js.map +1 -0
  162. package/dist/node/{gitvault-prune.d.ts → vault-prune.d.ts} +61 -61
  163. package/dist/node/vault-prune.d.ts.map +1 -0
  164. package/dist/node/{gitvault-prune.js → vault-prune.js} +34 -34
  165. package/dist/node/vault-prune.js.map +1 -0
  166. package/dist/node/{gitvault-publication.d.ts → vault-publication.d.ts} +399 -399
  167. package/dist/node/vault-publication.d.ts.map +1 -0
  168. package/dist/node/{gitvault-publication.js → vault-publication.js} +584 -584
  169. package/dist/node/vault-publication.js.map +1 -0
  170. package/dist/node/{gitvault-push-to-create.d.ts → vault-push-to-create.d.ts} +16 -16
  171. package/dist/node/vault-push-to-create.d.ts.map +1 -0
  172. package/dist/node/{gitvault-push-to-create.js → vault-push-to-create.js} +9 -9
  173. package/dist/node/vault-push-to-create.js.map +1 -0
  174. package/dist/node/{gitvault-recover.d.ts → vault-recover.d.ts} +50 -50
  175. package/dist/node/vault-recover.d.ts.map +1 -0
  176. package/dist/node/{gitvault-recover.js → vault-recover.js} +84 -84
  177. package/dist/node/vault-recover.js.map +1 -0
  178. package/dist/node/{gitvault-restore.d.ts → vault-restore.d.ts} +8 -8
  179. package/dist/node/vault-restore.d.ts.map +1 -0
  180. package/dist/node/{gitvault-restore.js → vault-restore.js} +11 -11
  181. package/dist/node/vault-restore.js.map +1 -0
  182. package/dist/node/{gitvault-snapshot.d.ts → vault-snapshot.d.ts} +48 -48
  183. package/dist/node/vault-snapshot.d.ts.map +1 -0
  184. package/dist/node/{gitvault-snapshot.js → vault-snapshot.js} +61 -61
  185. package/dist/node/vault-snapshot.js.map +1 -0
  186. package/dist/node/{gitvault-writer-state.d.ts → vault-writer-state.d.ts} +8 -8
  187. package/dist/node/vault-writer-state.d.ts.map +1 -0
  188. package/dist/node/{gitvault-writer-state.js → vault-writer-state.js} +15 -15
  189. package/dist/node/vault-writer-state.js.map +1 -0
  190. package/dist/node/workflow-output.js +4 -4
  191. package/dist/node/workflow-output.js.map +1 -1
  192. package/dist/project-auth-classification.d.ts +8 -8
  193. package/dist/project-auth-classification.d.ts.map +1 -1
  194. package/dist/project-auth-classification.js +7 -7
  195. package/dist/project-auth-classification.js.map +1 -1
  196. package/dist/scoped.d.ts +6 -14
  197. package/dist/scoped.d.ts.map +1 -1
  198. package/dist/scoped.js +10 -21
  199. package/dist/scoped.js.map +1 -1
  200. package/package.json +1 -1
  201. package/dist/delegate-credentials.d.ts +0 -37
  202. package/dist/delegate-credentials.d.ts.map +0 -1
  203. package/dist/delegate-credentials.js +0 -41
  204. package/dist/delegate-credentials.js.map +0 -1
  205. package/dist/namespaces/delegates.d.ts +0 -50
  206. package/dist/namespaces/delegates.d.ts.map +0 -1
  207. package/dist/namespaces/delegates.js +0 -99
  208. package/dist/namespaces/delegates.js.map +0 -1
  209. package/dist/namespaces/delegates.types.d.ts +0 -88
  210. package/dist/namespaces/delegates.types.d.ts.map +0 -1
  211. package/dist/namespaces/delegates.types.js +0 -10
  212. package/dist/namespaces/delegates.types.js.map +0 -1
  213. package/dist/namespaces/gitvault.crypto.d.ts.map +0 -1
  214. package/dist/namespaces/gitvault.crypto.js.map +0 -1
  215. package/dist/namespaces/gitvault.d.ts.map +0 -1
  216. package/dist/namespaces/gitvault.js.map +0 -1
  217. package/dist/namespaces/gitvault.types.d.ts.map +0 -1
  218. package/dist/namespaces/gitvault.types.js.map +0 -1
  219. package/dist/node/gitvault-address.d.ts.map +0 -1
  220. package/dist/node/gitvault-address.js.map +0 -1
  221. package/dist/node/gitvault-apply.d.ts.map +0 -1
  222. package/dist/node/gitvault-apply.js.map +0 -1
  223. package/dist/node/gitvault-byo-config.d.ts +0 -29
  224. package/dist/node/gitvault-byo-config.d.ts.map +0 -1
  225. package/dist/node/gitvault-byo-config.js.map +0 -1
  226. package/dist/node/gitvault-byo-probe.d.ts +0 -20
  227. package/dist/node/gitvault-byo-probe.d.ts.map +0 -1
  228. package/dist/node/gitvault-byo-probe.js +0 -57
  229. package/dist/node/gitvault-byo-probe.js.map +0 -1
  230. package/dist/node/gitvault-creation-journal.d.ts.map +0 -1
  231. package/dist/node/gitvault-creation-journal.js.map +0 -1
  232. package/dist/node/gitvault-degraded-read.d.ts.map +0 -1
  233. package/dist/node/gitvault-degraded-read.js.map +0 -1
  234. package/dist/node/gitvault-deploy.d.ts.map +0 -1
  235. package/dist/node/gitvault-deploy.js.map +0 -1
  236. package/dist/node/gitvault-edge-fetch.d.ts.map +0 -1
  237. package/dist/node/gitvault-edge-fetch.js.map +0 -1
  238. package/dist/node/gitvault-handoff.d.ts.map +0 -1
  239. package/dist/node/gitvault-handoff.js.map +0 -1
  240. package/dist/node/gitvault-keystore.d.ts.map +0 -1
  241. package/dist/node/gitvault-keystore.js.map +0 -1
  242. package/dist/node/gitvault-member-bundle.d.ts.map +0 -1
  243. package/dist/node/gitvault-member-bundle.js.map +0 -1
  244. package/dist/node/gitvault-mirror-backend.d.ts.map +0 -1
  245. package/dist/node/gitvault-mirror-backend.js.map +0 -1
  246. package/dist/node/gitvault-mirror-config.d.ts.map +0 -1
  247. package/dist/node/gitvault-mirror-config.js.map +0 -1
  248. package/dist/node/gitvault-mirror.d.ts.map +0 -1
  249. package/dist/node/gitvault-mirror.js.map +0 -1
  250. package/dist/node/gitvault-native-crypto.d.ts.map +0 -1
  251. package/dist/node/gitvault-native-crypto.js.map +0 -1
  252. package/dist/node/gitvault-open-or-create.d.ts.map +0 -1
  253. package/dist/node/gitvault-open-or-create.js.map +0 -1
  254. package/dist/node/gitvault-prewarm.d.ts.map +0 -1
  255. package/dist/node/gitvault-prewarm.js.map +0 -1
  256. package/dist/node/gitvault-profile-scan.d.ts.map +0 -1
  257. package/dist/node/gitvault-profile-scan.js.map +0 -1
  258. package/dist/node/gitvault-prune.d.ts.map +0 -1
  259. package/dist/node/gitvault-prune.js.map +0 -1
  260. package/dist/node/gitvault-publication.d.ts.map +0 -1
  261. package/dist/node/gitvault-publication.js.map +0 -1
  262. package/dist/node/gitvault-push-to-create.d.ts.map +0 -1
  263. package/dist/node/gitvault-push-to-create.js.map +0 -1
  264. package/dist/node/gitvault-recover.d.ts.map +0 -1
  265. package/dist/node/gitvault-recover.js.map +0 -1
  266. package/dist/node/gitvault-restore.d.ts.map +0 -1
  267. package/dist/node/gitvault-restore.js.map +0 -1
  268. package/dist/node/gitvault-snapshot.d.ts.map +0 -1
  269. package/dist/node/gitvault-snapshot.js.map +0 -1
  270. package/dist/node/gitvault-writer-state.d.ts.map +0 -1
  271. package/dist/node/gitvault-writer-state.js.map +0 -1
@@ -1,12 +1,12 @@
1
1
  /**
2
- * `r.gitvault` — the host-blind encrypted Git remote, as the SDK's programmatic
3
- * API (add-gitvault task 5.10).
2
+ * `r.repos` — the host-blind encrypted Git remote, as the SDK's programmatic
3
+ * API (add-vault task 5.10).
4
4
  *
5
5
  * ARCHITECTURAL LAW (client-surface spec, "All protocol logic lives in the
6
6
  * SDK"): every piece of vault protocol behaviour — crypto core, keystore,
7
7
  * creation journal, snapshot + capture, publication state machines, ref
8
8
  * transactions, verification budget, token exchange, repair — is implemented
9
- * ONCE here. `run402 gitvault …`, `git-remote-run402`, and the MCP tools are
9
+ * ONCE here. `run402 repos …`, `git-remote-run402`, and the MCP tools are
10
10
  * adapters over this namespace: argument parsing, TTY output, exit codes, and
11
11
  * local file I/O only. Anything the CLI can do is reachable programmatically
12
12
  * with identical semantics.
@@ -29,9 +29,9 @@
29
29
  * never persisted into an agent-surface result store, and never logged.
30
30
  */
31
31
  import { LocalError, isRun402Error, isNetworkError } from "../errors.js";
32
- import { GITVAULT_BYO_UNMIRRORED_REMEDY_STATEMENT, GITVAULT_DEGRADED_READ_STATEMENT, GITVAULT_DURABILITY_STATEMENT, GITVAULT_MIRROR_KEYSTORE_STILL_REQUIRED_STATEMENT, GITVAULT_MIRROR_VALIDITY_NOT_FRESHNESS_STATEMENT, GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT, GITVAULT_TERMINAL_LOSS_STATEMENT, GITVAULT_UNMIRRORED_FINDING_STATEMENT, bytesToHex, computeKeystorePossessionProof, computeSigningKeyPossessionSignature, ed25519PublicKey, fromBase64url, hexToBytes, jcs, parseGitvaultStrict, randomBytes, sha256Hex, verifyGitvaultObject, toBase64url, } from "./gitvault.crypto.js";
32
+ import { VAULT_BYO_UNMIRRORED_REMEDY_STATEMENT, VAULT_DEGRADED_READ_STATEMENT, VAULT_DURABILITY_STATEMENT, VAULT_MIRROR_KEYSTORE_STILL_REQUIRED_STATEMENT, VAULT_MIRROR_VALIDITY_NOT_FRESHNESS_STATEMENT, VAULT_TERMINAL_LOSS_DOCTOR_TEXT, VAULT_TERMINAL_LOSS_STATEMENT, VAULT_UNMIRRORED_FINDING_STATEMENT, bytesToHex, computeKeystorePossessionProof, computeSigningKeyPossessionSignature, ed25519PublicKey, fromBase64url, hexToBytes, jcs, parseVaultStrict, randomBytes, sha256Hex, verifyVaultObject, toBase64url, } from "./vault.crypto.js";
33
33
  /**
34
- * gitvault-agent-envelopes — per-process memo for the session-start
34
+ * vault-agent-envelopes — per-process memo for the session-start
35
35
  * fulfilment (`<keystore root>|<repo_id>`) and the enroll-if-absent step
36
36
  * (`<keystore root>`), so a process that opens the same vault many times
37
37
  * (a `git push` runs several verbs) reconciles and enrolls once.
@@ -45,8 +45,8 @@ const SESSION_RECONCILED = new Set();
45
45
  * best-effort.
46
46
  */
47
47
  const RECONCILE_FATAL_CODES = new Set([
48
- "GITVAULT_ENVELOPE_ALTERED",
49
- "GITVAULT_SIGNATURE_INVALID",
48
+ "VAULT_ENVELOPE_ALTERED",
49
+ "VAULT_SIGNATURE_INVALID",
50
50
  "VAULT_CREATION_CONFLICT",
51
51
  ]);
52
52
  function rethrowFatalReconcile(e) {
@@ -70,7 +70,7 @@ async function nodeOnly(load, verb) {
70
70
  return await load();
71
71
  }
72
72
  catch (e) {
73
- throw new LocalError(`\`r.gitvault.${verb}\` needs the Node runtime (keystore + git); import it from a Node process, or use the read-only vault methods in a browser.`, `running gitvault ${verb}`, { code: "GITVAULT_NODE_ONLY", details: { cause: e instanceof Error ? e.message : String(e) } });
73
+ throw new LocalError(`\`r.repos.${verb}\` needs the Node runtime (keystore + git); import it from a Node process, or use the read-only vault methods in a browser.`, `running vault ${verb}`, { code: "VAULT_NODE_ONLY", details: { cause: e instanceof Error ? e.message : String(e) } });
74
74
  }
75
75
  }
76
76
  /** Byte counts in the refusal text read as MiB — the unit an operator's tier is quoted in. */
@@ -80,7 +80,7 @@ function mib(bytes) {
80
80
  /**
81
81
  * A client-generated handoff id (RFC 4122 v4), minted BEFORE the mint call
82
82
  * (kygit-handoff design D3): `auth_secret`/`wrap_key` derive off it, so it
83
- * cannot be gateway-assigned the way `internal.gitvault_claims.id` alone
83
+ * cannot be gateway-assigned the way `internal.vault_claims.id` alone
84
84
  * would suggest — this SDK supplies it, mirroring the SAME
85
85
  * client_creation_id/client_open_id convention this protocol family
86
86
  * already uses elsewhere for idempotent creation. `handoff()` refuses if
@@ -96,8 +96,8 @@ function randomHandoffUuid() {
96
96
  /**
97
97
  * The gateway names the vault by its three ids on the wire — `repo_id`,
98
98
  * `org_id`, `project_id` (docs/style.md's API-boundary vocabulary) — on
99
- * BOTH the handoff mint (`POST /gitvault/v1/vaults/:vault_id/handoffs`) and
100
- * claim (`POST /gitvault/v1/handoffs/:handoff_id/redeem`) responses. The SDK
99
+ * BOTH the handoff mint (`POST /vaults/v1/:vault_id/handoffs`) and
100
+ * claim (`POST /vaults/v1/handoffs/:handoff_id/redeem`) responses. The SDK
101
101
  * groups them under `vault` with the `organization_id` spelling every other
102
102
  * SDK result uses. Neither response carries a slug-form address, so
103
103
  * `address` is `null` unless the caller already knows one (a slug-form
@@ -122,8 +122,8 @@ export function handoffMembershipFromWire(wire) {
122
122
  */
123
123
  export const INVITE_DEFAULT_ROLE = "developer";
124
124
  /**
125
- * gitvault-byo-primary-bucket task 3.3 — the number of `{key, object_kind}`
126
- * entries `GITVAULT_BYO_OBJECT_MISSING`'s `details.missing` lists before
125
+ * vault-byo-primary-bucket task 3.3 — the number of `{key, object_kind}`
126
+ * entries `VAULT_BYO_OBJECT_MISSING`'s `details.missing` lists before
127
127
  * truncating (`details.missing_count` always carries the true total, and
128
128
  * `details.missing_truncated` says whether the list above was cut). A
129
129
  * chain-referenced object list can be arbitrarily large; an error envelope
@@ -131,14 +131,14 @@ export const INVITE_DEFAULT_ROLE = "developer";
131
131
  * `sample_keys`-class cap (asset-sync's plan response, `PLATFORM_INCIDENT_
132
132
  * FANOUT_CAP`) rather than inventing a new number.
133
133
  */
134
- export const GITVAULT_BYO_OBJECT_MISSING_LIST_CAP = 50;
134
+ export const VAULT_BYO_OBJECT_MISSING_LIST_CAP = 50;
135
135
  /**
136
136
  * D210 (rev 44) — the decision function behind `fsck`'s best-effort
137
- * proof-of-open submission, factored out of {@link Gitvault}'s private
137
+ * proof-of-open submission, factored out of {@link Repos}'s private
138
138
  * `#submitFsckOpenProof` so it is directly unit-testable with injected
139
139
  * (fake) `resolvePrincipalId`/`submit` dependencies, independent of a real
140
140
  * HTTP-backed vault. `fsck()` itself supplies the REAL dependencies (`GET
141
- * /agent/v1/whoami`, {@link Gitvault.submitProofOfOpen}) — this function
141
+ * /agent/v1/whoami`, {@link Repos.submitProofOfOpen}) — this function
142
142
  * contains no HTTP/transport code of its own.
143
143
  *
144
144
  * Gating (all LOCAL, no network call made when either holds):
@@ -173,8 +173,8 @@ export async function computeOpenProofOutcome(input) {
173
173
  deduplicated: null,
174
174
  receipt: null,
175
175
  error: {
176
- code: "GITVAULT_PROOF_OF_OPEN_PRINCIPAL_UNRESOLVED",
177
- message: "GET /agent/v1/whoami returned no resolvable principal for this credential (delegate bearers are not accepted by whoami) — submit via r.gitvault.submitProofOfOpen(repoId, principalId, evidence) directly instead",
176
+ code: "VAULT_PROOF_OF_OPEN_PRINCIPAL_UNRESOLVED",
177
+ message: "GET /agent/v1/whoami returned no resolvable principal for this credential (grant-key bearers are not accepted by whoami) — submit via r.repos.submitProofOfOpen(repoId, principalId, evidence) directly instead",
178
178
  },
179
179
  };
180
180
  }
@@ -197,8 +197,8 @@ export async function computeOpenProofOutcome(input) {
197
197
  }
198
198
  }
199
199
  /**
200
- * gitvault-byo-primary-bucket task 3.3 (design D6) — the decision function
201
- * behind `fsck`'s BYO presence check, factored out of {@link Gitvault}'s
200
+ * vault-byo-primary-bucket task 3.3 (design D6) — the decision function
201
+ * behind `fsck`'s BYO presence check, factored out of {@link Repos}'s
202
202
  * private `#checkByoPresence` the same way {@link computeOpenProofOutcome}
203
203
  * is factored out of `#submitFsckOpenProof`, so it is directly unit-testable
204
204
  * with an injected (fake) `hasLocalConfig`/`verifyPresence`, independent of
@@ -218,15 +218,15 @@ export async function computeOpenProofOutcome(input) {
218
218
  * NO local credentials configured (`hasLocalConfig()` returns `false`) is
219
219
  * reported, never thrown — a BYO vault this machine cannot reach is an
220
220
  * honest "not checked", not a failure that should break `fsck` for a
221
- * credential-less returning agent (see {@link GitvaultFsckByoPresence}'s
221
+ * credential-less returning agent (see {@link VaultFsckByoPresence}'s
222
222
  * own doc comment). A confirmed absence is the opposite: it THROWS
223
- * `GITVAULT_BYO_OBJECT_MISSING` — the same severity class as {@link
224
- * Gitvault.mirrorVerify}'s own `GITVAULT_MIRROR_NOT_CONFIGURED` throw when
223
+ * `VAULT_BYO_OBJECT_MISSING` — the same severity class as {@link
224
+ * Repos.mirrorVerify}'s own `VAULT_MIRROR_NOT_CONFIGURED` throw when
225
225
  * `--mirror` is requested against an unconfigured vault — this is exactly
226
226
  * the honesty D6 names: "we can tell the customer what SHOULD exist and
227
227
  * does not", stated as a real refusal rather than a silently-embedded
228
228
  * finding. The listed entries are capped at
229
- * {@link GITVAULT_BYO_OBJECT_MISSING_LIST_CAP} (a chain-referenced object
229
+ * {@link VAULT_BYO_OBJECT_MISSING_LIST_CAP} (a chain-referenced object
230
230
  * list can be arbitrarily large and this is an error envelope, not a
231
231
  * report); `missing_count` always carries the true total regardless of how
232
232
  * many are listed.
@@ -250,9 +250,9 @@ export async function computeByoPresenceOutcome(input) {
250
250
  }
251
251
  const report = await input.verifyPresence();
252
252
  if (report.missing.length > 0) {
253
- const missing = report.missing.slice(0, GITVAULT_BYO_OBJECT_MISSING_LIST_CAP);
254
- throw new LocalError(`the BYO destination for ${input.repoId} (${report.destination}) is missing ${report.missing.length} object(s) run402's own signed chain says should exist`, "running gitvault fsck", {
255
- code: "GITVAULT_BYO_OBJECT_MISSING",
253
+ const missing = report.missing.slice(0, VAULT_BYO_OBJECT_MISSING_LIST_CAP);
254
+ throw new LocalError(`the BYO destination for ${input.repoId} (${report.destination}) is missing ${report.missing.length} object(s) run402's own signed chain says should exist`, "running vault fsck", {
255
+ code: "VAULT_BYO_OBJECT_MISSING",
256
256
  details: {
257
257
  repo_id: input.repoId,
258
258
  destination: report.destination,
@@ -272,7 +272,7 @@ export async function computeByoPresenceOutcome(input) {
272
272
  return { verified: true, destination: report.destination, checked_count: report.checked, not_checked_reason: null };
273
273
  }
274
274
  /**
275
- * {@link Gitvault.deploy}'s post-push glue: attach the best-effort
275
+ * {@link Repos.deploy}'s post-push glue: attach the best-effort
276
276
  * mirror/reconcile hooks to a deploy result, gated on whether this deploy
277
277
  * actually landed a new generation in the vault. Extracted as a standalone
278
278
  * function (rather than inlined in `deploy()`) purely so the gating can be
@@ -289,10 +289,10 @@ export async function computeByoPresenceOutcome(input) {
289
289
  * `reconcile_recipients` are OMITTED rather than a faked `skipped_*` value —
290
290
  * there is nothing this deploy did that either hook could report on.
291
291
  */
292
- export async function attachGitvaultDeployHooks(result, mirror, reconcile) {
292
+ export async function attachVaultDeployHooks(result, mirror, reconcile) {
293
293
  if (result.outcome !== "DEPLOYED_AND_VAULTED" && result.outcome !== "DEPLOY_FAILED_VAULTED")
294
294
  return result;
295
- // Sequential, not Promise.all — same ordering push() uses, so a reconcile
295
+ // Sequential, not Promise.all — same ordering capture() uses, so a reconcile
296
296
  // failure can never be misread as a mirror failure in a log line that
297
297
  // assumed ordering.
298
298
  const mirrorPush = await mirror();
@@ -300,7 +300,7 @@ export async function attachGitvaultDeployHooks(result, mirror, reconcile) {
300
300
  return { ...result, mirror_push: mirrorPush, reconcile_recipients: reconcileRecipients };
301
301
  }
302
302
  // ─── The namespace ───────────────────────────────────────────────────────────
303
- export class Gitvault {
303
+ export class Repos {
304
304
  #client;
305
305
  constructor(client) {
306
306
  this.#client = client;
@@ -308,7 +308,7 @@ export class Gitvault {
308
308
  // ── Control-plane reads (isomorphic) ──────────────────────────────────────
309
309
  /** The vault record — policy, allocation generation, storage + maintenance state. */
310
310
  async get(repoId) {
311
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}`, { context: "reading the gitvault record" });
311
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}`, { context: "reading the vault record" });
312
312
  }
313
313
  /**
314
314
  * Resolve a project's vault with no local state. This is the cold-restart
@@ -316,12 +316,12 @@ export class Gitvault {
316
316
  * the project learns its `repo_id` here.
317
317
  */
318
318
  async forProject(projectId) {
319
- return this.#client.request(`/gitvault/v1/vaults?project_id=${encodeURIComponent(projectId)}`, { context: "resolving the project's gitvault" });
319
+ return this.#client.request(`/vaults/v1?project_id=${encodeURIComponent(projectId)}`, { context: "resolving the project's vault" });
320
320
  }
321
321
  /**
322
322
  * Every vault the organization owns, one round trip — `repos list`'s bulk
323
323
  * read. See {@link
324
- * GitvaultOrgVaultsListing}'s doc comment for the FROZEN response shape and
324
+ * VaultOrgVaultsListing}'s doc comment for the FROZEN response shape and
325
325
  * the 404-until-shipped fallback contract.
326
326
  */
327
327
  async listByOrg(orgId) {
@@ -334,7 +334,7 @@ export class Gitvault {
334
334
  const all = [];
335
335
  let cursor;
336
336
  for (let page = 0; page < 100; page++) {
337
- const url = `/gitvault/v1/vaults?org_id=${encodeURIComponent(orgId)}` + (cursor ? `&cursor=${encodeURIComponent(cursor)}` : "");
337
+ const url = `/vaults/v1?org_id=${encodeURIComponent(orgId)}` + (cursor ? `&cursor=${encodeURIComponent(cursor)}` : "");
338
338
  const res = await this.#client.request(url, { context: "listing the organization's vaults" });
339
339
  all.push(...res.vaults);
340
340
  if (!res.has_more || !res.next_cursor)
@@ -345,18 +345,18 @@ export class Gitvault {
345
345
  }
346
346
  /**
347
347
  * Resolve a vault by its address-form `org-slug/name` —
348
- * `GET /gitvault/v1/vaults?repo=<org-slug>/<name>`.
348
+ * `GET /vaults/v1?repo=<org-slug>/<name>`.
349
349
  * `RESOURCE_NOT_FOUND` for no such org OR no such name (deliberately
350
350
  * collapsed — see the design's slug-namespace-probing note);
351
- * `SLUG_RELEASED` (read it with {@link gitvaultSlugReleasedInfo}) while the
351
+ * `SLUG_RELEASED` (read it with {@link vaultSlugReleasedInfo}) while the
352
352
  * slug is in its post-rename cooldown — never auto-followed.
353
353
  */
354
354
  async forRepo(address) {
355
355
  const repo = `${address.org_slug}/${address.repo_name}`;
356
- return this.#client.request(`/gitvault/v1/vaults?repo=${encodeURIComponent(repo)}`, { context: "resolving the gitvault by repo address" });
356
+ return this.#client.request(`/vaults/v1?repo=${encodeURIComponent(repo)}`, { context: "resolving the vault by repo address" });
357
357
  }
358
358
  /**
359
- * Resolve a parsed remote address (`parseGitvaultRemoteUrl`'s output),
359
+ * Resolve a parsed remote address (`parseVaultRemoteUrl`'s output),
360
360
  * dispatching on its form: id-form resolves exactly like
361
361
  * {@link forProject}; slug-form resolves via {@link forRepo}. A pure read —
362
362
  * no pinning, no creation. Node-only callers wanting BOTH should use
@@ -364,7 +364,7 @@ export class Gitvault {
364
364
  * and (opt-in) push-to-create.
365
365
  */
366
366
  async resolveAddress(address) {
367
- return gitvaultRemoteAddressForm(address) === "id"
367
+ return vaultRemoteAddressForm(address) === "id"
368
368
  ? this.forProject(address.project_id)
369
369
  : this.forRepo({ org_slug: address.org_id, repo_name: address.project_id });
370
370
  }
@@ -384,7 +384,7 @@ export class Gitvault {
384
384
  const qs = new URLSearchParams({ after_generation: request.after_generation, limit: request.limit });
385
385
  if (request.cursor !== undefined)
386
386
  qs.set("cursor", request.cursor);
387
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/heads?${qs.toString()}`, { context: "listing gitvault heads" });
387
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/heads?${qs.toString()}`, { context: "listing vault heads" });
388
388
  }
389
389
  /**
390
390
  * Walk the whole listing above the anchor, verifying page coupling, ordering,
@@ -413,10 +413,10 @@ export class Gitvault {
413
413
  * `required`.
414
414
  */
415
415
  async setPolicy(repoId, input) {
416
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/policy`, {
416
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/policy`, {
417
417
  method: "PATCH",
418
- body: { gitvault_policy: input.gitvault_policy, ...(input.reason !== undefined ? { reason: input.reason } : {}) },
419
- context: "setting the gitvault activation policy",
418
+ body: { vault_policy: input.vault_policy, ...(input.reason !== undefined ? { reason: input.reason } : {}) },
419
+ context: "setting the vault activation policy",
420
420
  });
421
421
  }
422
422
  /**
@@ -425,7 +425,7 @@ export class Gitvault {
425
425
  * clears it.
426
426
  */
427
427
  async completeOverride(repoId, input) {
428
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/override-completions`, { method: "POST", body: input, context: "submitting the gitvault override completion" });
428
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/override-completions`, { method: "POST", body: input, context: "submitting the vault override completion" });
429
429
  }
430
430
  /**
431
431
  * Take the owner's maintenance reservation for a compact/prune cycle.
@@ -440,22 +440,22 @@ export class Gitvault {
440
440
  // `gitvault.rotate`) — same "direct #client.request" shape as `setPolicy`/
441
441
  // `completeOverride` above. The actual ROTATION (sampling K_e, sealing
442
442
  // envelopes, submitting the head) needs the Node-only keystore + crypto
443
- // core and lives on `GitvaultVault` (`sdk/src/node/gitvault-publication.ts`);
443
+ // core and lives on `Vault` (`sdk/src/node/vault-publication.ts`);
444
444
  // see {@link rotateEpoch} / {@link rotateEpochForKeyRevocation} below.
445
445
  /** `POST …/recipients/:principal_id/confirm` (D197) — first-seen pin confirmation. */
446
446
  async confirmRecipient(repoId, principalId, newFingerprint) {
447
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/recipients/${encodeURIComponent(principalId)}/confirm`, {
448
- method: "POST", body: { new_fingerprint: newFingerprint }, context: "confirming a gitvault recipient's first pin",
447
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/recipients/${encodeURIComponent(principalId)}/confirm`, {
448
+ method: "POST", body: { new_fingerprint: newFingerprint }, context: "confirming a vault recipient's first pin",
449
449
  });
450
450
  }
451
451
  /** `POST …/recipients/:principal_id/repin` (D197) — re-pin ceremony. */
452
452
  async repinRecipient(repoId, principalId, input) {
453
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/recipients/${encodeURIComponent(principalId)}/repin`, {
454
- method: "POST", body: input, context: "re-pinning a gitvault recipient",
453
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/recipients/${encodeURIComponent(principalId)}/repin`, {
454
+ method: "POST", body: input, context: "re-pinning a vault recipient",
455
455
  });
456
456
  }
457
457
  /**
458
- * gitvault-agent-envelopes D3 — a KEY-HOLDER explicitly accepts a recipient's
458
+ * vault-agent-envelopes D3 — a KEY-HOLDER explicitly accepts a recipient's
459
459
  * CHANGED key. The session-start reconcile refuses to wrap under a
460
460
  * fingerprint that differs from this keystore's TOFU pin
461
461
  * (`pinned_key_mismatch`) — that refusal is the substitution defence and
@@ -471,11 +471,11 @@ export class Gitvault {
471
471
  */
472
472
  async acceptRecipientKeyChange(options) {
473
473
  const repoId = await this.#resolveRepoId(options);
474
- const { GitvaultKeystore } = await this.#keystore();
475
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
474
+ const { VaultKeystore } = await this.#keystore();
475
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
476
476
  const repo = keystore.readRepo(repoId);
477
477
  if (!repo)
478
- throw new LocalError("this keystore holds no repo state for the vault — only a key-holder can accept a recipient's key change", "accepting a recipient key change", { code: "GITVAULT_REPO_STATE_MISSING", details: { repo_id: repoId } });
478
+ throw new LocalError("this keystore holds no repo state for the vault — only a key-holder can accept a recipient's key change", "accepting a recipient key change", { code: "VAULT_REPO_STATE_MISSING", details: { repo_id: repoId } });
479
479
  const record = await this.get(repoId);
480
480
  const directory = await this.#client.request(`/orgs/v1/${encodeURIComponent(record.org_id)}/encryption-keys`, { context: "reading the org encryption-key directory" });
481
481
  const served = directory.keys.find((k) => k.principal_id === options.principal_id)?.ek_fingerprint ?? null;
@@ -504,8 +504,8 @@ export class Gitvault {
504
504
  * fully self-contained entry point.
505
505
  */
506
506
  async declareRecipientKeyRevoked(repoId, principalId) {
507
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/recipients/${encodeURIComponent(principalId)}/key-revocation`, {
508
- method: "POST", body: {}, context: "declaring a gitvault recipient key revoked",
507
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/recipients/${encodeURIComponent(principalId)}/key-revocation`, {
508
+ method: "POST", body: {}, context: "declaring a vault recipient key revoked",
509
509
  });
510
510
  }
511
511
  /**
@@ -519,11 +519,11 @@ export class Gitvault {
519
519
  * comment on the confirmed gap in what the gateway exposes today).
520
520
  */
521
521
  async declareEpochSecretExposed(repoId) {
522
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/epoch-secret-exposure`, { method: "POST", body: {}, context: "declaring a gitvault epoch secret exposed" });
522
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/epoch-secret-exposure`, { method: "POST", body: {}, context: "declaring a vault epoch secret exposed" });
523
523
  }
524
524
  /** `POST …/writer-authority/declare-unavailable` (D202) — an explicit, audited fact that the writer signing key is gone. */
525
525
  async declareWriterAuthorityUnavailable(repoId) {
526
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/writer-authority/declare-unavailable`, { method: "POST", body: {}, context: "declaring gitvault writer authority unavailable" });
526
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/writer-authority/declare-unavailable`, { method: "POST", body: {}, context: "declaring vault writer authority unavailable" });
527
527
  }
528
528
  /**
529
529
  * `POST …/recipients/:principal_id/proof-of-open` (D210, rev 44) — submit
@@ -538,18 +538,18 @@ export class Gitvault {
538
538
  *
539
539
  * Self-match only: the gateway requires `principalId` to equal the
540
540
  * AUTHENTICATED caller, never overridable by any credential class — a
541
- * mismatch is the ordinary 403 `GITVAULT_ACCESS_DENIED`. Idempotent on
541
+ * mismatch is the ordinary 403 `VAULT_ACCESS_DENIED`. Idempotent on
542
542
  * `(repo_id, principal_id, ek_fingerprint, decryptable_to_generation)` —
543
543
  * `deduplicated: true` means the gateway returned the tuple's EXISTING
544
544
  * receipt (HTTP 200) rather than minting a fresh one (HTTP 201).
545
545
  */
546
546
  async submitProofOfOpen(repoId, principalId, evidence) {
547
- const res = await this.#client.requestWithResponse(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/recipients/${encodeURIComponent(principalId)}/proof-of-open`, { method: "POST", body: evidence, context: "submitting a gitvault proof-of-open receipt" });
547
+ const res = await this.#client.requestWithResponse(`/vaults/v1/${encodeURIComponent(repoId)}/recipients/${encodeURIComponent(principalId)}/proof-of-open`, { method: "POST", body: evidence, context: "submitting a vault proof-of-open receipt" });
548
548
  return { receipt: res.body, deduplicated: res.status === 200 };
549
549
  }
550
550
  async acquireMaintenanceLease(request) {
551
551
  const { repo_id, ...body } = request;
552
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repo_id)}/maintenance-leases`, {
552
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repo_id)}/maintenance-leases`, {
553
553
  method: "POST",
554
554
  body: {
555
555
  base_head_sha256: body.base_head_sha256,
@@ -559,7 +559,7 @@ export class Gitvault {
559
559
  p_before_c1_size_bytes: body.p_before_c1_size_bytes ?? "0",
560
560
  p_before_c2_size_bytes: body.p_before_c2_size_bytes ?? "0",
561
561
  },
562
- context: "acquiring the gitvault maintenance lease",
562
+ context: "acquiring the vault maintenance lease",
563
563
  });
564
564
  }
565
565
  // ── Node-only verbs ───────────────────────────────────────────────────────
@@ -569,23 +569,23 @@ export class Gitvault {
569
569
  * surface (ref transactions, repair, checkpoint building).
570
570
  */
571
571
  async open(options = {}) {
572
- const [{ GitvaultVault, createGitvaultHttpTransport }, { GitvaultKeystore }] = await Promise.all([this.#publication(), this.#keystore()]);
572
+ const [{ Vault, createVaultHttpTransport }, { VaultKeystore }] = await Promise.all([this.#publication(), this.#keystore()]);
573
573
  const repoId = await this.#resolveRepoId(options);
574
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
575
- // gitvault-object-host-predial (design D1, task 1.2): this is the ONE
574
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
575
+ // vault-object-host-predial (design D1, task 1.2): this is the ONE
576
576
  // transport whose object reads back the returned handle's vault, so
577
577
  // wiring the origin-observation hook here (and nowhere else `open()`
578
578
  // is reached from — `openOrCreate`'s own allocation-only transport
579
579
  // never serves object reads) covers every read path.
580
- const transport = createGitvaultHttpTransport(this.#client, {
580
+ const transport = createVaultHttpTransport(this.#client, {
581
581
  onObjectStoreOriginObserved: (rid, origins) => keystore.recordObjectStoreOrigins(rid, origins),
582
582
  byoBackend: await this.#byoBackendResolver(keystore),
583
583
  });
584
- // gitvault-agent-envelopes D3: enroll the keystore's key if this principal
584
+ // vault-agent-envelopes D3: enroll the keystore's key if this principal
585
585
  // has none (publish + possession proof, one round trip each); a differing
586
586
  // current key REFUSES here — rotation is never automatic.
587
587
  const enrollment = await this.#ensureEnrolled(keystore);
588
- const vault = new GitvaultVault({
588
+ const vault = new Vault({
589
589
  keystore,
590
590
  transport,
591
591
  repo_id: repoId,
@@ -594,13 +594,13 @@ export class Gitvault {
594
594
  ...(options.service_public_key !== undefined ? { service_public_key: options.service_public_key } : {}),
595
595
  });
596
596
  // D4: a cold keystore restores from its own envelope (or fails
597
- // GITVAULT_ENVELOPE_PENDING with the exact next actions). The lazy
597
+ // VAULT_ENVELOPE_PENDING with the exact next actions). The lazy
598
598
  // fallback is an ALLOWLIST of typed transport/absence states, not a
599
599
  // denylist of known verdicts (consult round 2 §5): a network fault, an
600
600
  // older gateway missing the route (404/501), or a vault with no admitted
601
601
  // genesis yet (CHAIN_BROKEN — not born, nothing to restore or disclose)
602
602
  // leave the handle lazy so the verb fails exactly where it always did
603
- // (`GITVAULT_REPO_STATE_MISSING` at first use). EVERYTHING else —
603
+ // (`VAULT_REPO_STATE_MISSING` at first use). EVERYTHING else —
604
604
  // integrity failures, parse failures, programming errors — propagates.
605
605
  // A keystore with NO identity has nothing to restore and nothing that
606
606
  // could be disclosed — stay lazy and let the verb hit the ordinary
@@ -674,7 +674,7 @@ export class Gitvault {
674
674
  }
675
675
  }
676
676
  }
677
- // gitvault-multi-writer (task 5.7) — the SAME "session-start"/"read"
677
+ // vault-multi-writer (task 5.7) — the SAME "session-start"/"read"
678
678
  // wiring point as the envelope reconcile above, but a genuinely simpler
679
679
  // policy: no disclosure risk, so only `forbidden` is honored — no
680
680
  // custody gate, no `deferred`/memoization branch.
@@ -682,7 +682,7 @@ export class Gitvault {
682
682
  return { repo_id: repoId, keystore, transport, vault, restored, reconcile_recipients: reconcileRecipients, writer_reconcile: writerReconcile, enrollment };
683
683
  }
684
684
  /**
685
- * gitvault-agent-envelopes D3 — enroll-if-absent, checked FRESH on every
685
+ * vault-agent-envelopes D3 — enroll-if-absent, checked FRESH on every
686
686
  * open (consult round 2 §4: memoizing this decision let a long-lived
687
687
  * process keep trusting a key an owner had since revoked). Reads
688
688
  * `GET /agent/v1/whoami` (the gateway folds the principal's current key
@@ -693,7 +693,7 @@ export class Gitvault {
693
693
  * - current key = this keystore's key, still `pending` → finish the
694
694
  * activation (a crashed earlier enrollment);
695
695
  * - current key = this keystore's key, `active` → no-op;
696
- * - current key ≠ this keystore's key → `GITVAULT_KEY_ROTATION_REQUIRED`.
696
+ * - current key ≠ this keystore's key → `VAULT_KEY_ROTATION_REQUIRED`.
697
697
  * Never published as a rotation: a stolen wallet key must not silently
698
698
  * replace a member's decryption identity. The remedies are the
699
699
  * gateway's — restore the keystore backup; an org owner revokes the
@@ -710,7 +710,7 @@ export class Gitvault {
710
710
  catch (e) {
711
711
  // An older gateway, a credential whoami refuses, or a transport fault:
712
712
  // enrollment is best-effort on the way IN — the verb itself still runs
713
- // (and a cold open will say `GITVAULT_ENVELOPE_PENDING` honestly if it
713
+ // (and a cold open will say `VAULT_ENVELOPE_PENDING` honestly if it
714
714
  // needed an envelope this principal never enrolled for). A keystore
715
715
  // with no identity reaches the ordinary KEYSTORE_MISSING wall unchanged.
716
716
  return { outcome: identity ? "skipped_error" : "skipped_no_identity", ek_fingerprint: identity?.encryption_fingerprint ?? null, signing_fingerprint: identity?.signing_fingerprint ?? null, error: e instanceof Error ? e.message : String(e) };
@@ -725,7 +725,7 @@ export class Gitvault {
725
725
  return { outcome: "skipped_not_enrollable", ek_fingerprint: identity?.encryption_fingerprint ?? null, signing_fingerprint: identity?.signing_fingerprint ?? null };
726
726
  }
727
727
  if (identity?.enrolled_principal_id && identity.enrolled_principal_id !== whoami.principal.id) {
728
- throw new LocalError(`this keystore identity enrolled as principal ${identity.enrolled_principal_id}, but the active credential resolves to ${whoami.principal.id} — refusing cross-profile reuse of a custody identity`, "enrolling the keystore encryption key", { code: "GITVAULT_IDENTITY_PROFILE_MISMATCH", details: { enrolled_principal_id: identity.enrolled_principal_id, principal_id: whoami.principal.id, keystore_root: keystore.rootDir } });
728
+ throw new LocalError(`this keystore identity enrolled as principal ${identity.enrolled_principal_id}, but the active credential resolves to ${whoami.principal.id} — refusing cross-profile reuse of a custody identity`, "enrolling the keystore encryption key", { code: "VAULT_IDENTITY_PROFILE_MISMATCH", details: { enrolled_principal_id: identity.enrolled_principal_id, principal_id: whoami.principal.id, keystore_root: keystore.rootDir } });
729
729
  }
730
730
  const current = whoami.encryption_key ?? null;
731
731
  // A member joining from a FRESH machine has no keystore identity yet.
@@ -739,27 +739,27 @@ export class Gitvault {
739
739
  identity = keystore.ensureIdentity();
740
740
  if (!identity) {
741
741
  throw new LocalError(`this principal has a published encryption key (${current.ek_fingerprint}) but this keystore holds no identity — the keystore that enrolled it is not this one; rotation is never automatic`, "enrolling the keystore encryption key", {
742
- code: "GITVAULT_KEY_ROTATION_REQUIRED",
742
+ code: "VAULT_KEY_ROTATION_REQUIRED",
743
743
  details: { current_ek_fingerprint: current.ek_fingerprint, current_state: current.state, local_ek_fingerprint: null, keystore_root: keystore.rootDir },
744
744
  next_actions: [
745
- { type: "edit_request", why: "restore the keystore backup that holds the current key (~/.config/run402/gitvault or the wallet profile's gitvault dir)" },
746
- { type: "edit_request", why: "have an org owner revoke the stale key: DELETE /orgs/v1/:org_id/members/:principal_id/encryption-key (owner + step-up); your next gitvault operation then enrolls a fresh key" },
745
+ { type: "edit_request", why: "restore the keystore backup that holds the current key (~/.config/run402/vault or the wallet profile's vault dir)" },
746
+ { type: "edit_request", why: "have an org owner revoke the stale key: DELETE /orgs/v1/:org_id/members/:principal_id/encryption-key (owner + step-up); your next vault operation then enrolls a fresh key" },
747
747
  { type: "edit_request", why: "if this principal is the sole custody-eligible member of every org it belongs to: POST /agent/v1/whoami/encryption-key with replace_current: true" },
748
748
  ],
749
749
  });
750
750
  }
751
751
  if (current && current.ek_fingerprint !== identity.encryption_fingerprint) {
752
752
  throw new LocalError(`this principal's published encryption key (${current.ek_fingerprint}) is not this keystore's key (${identity.encryption_fingerprint}); rotation is never automatic`, "enrolling the keystore encryption key", {
753
- code: "GITVAULT_KEY_ROTATION_REQUIRED",
753
+ code: "VAULT_KEY_ROTATION_REQUIRED",
754
754
  details: { current_ek_fingerprint: current.ek_fingerprint, current_state: current.state, local_ek_fingerprint: identity.encryption_fingerprint, keystore_root: keystore.rootDir },
755
755
  next_actions: [
756
- { type: "edit_request", why: "restore the keystore backup that holds the current key (~/.config/run402/gitvault or the wallet profile's gitvault dir)" },
757
- { type: "edit_request", why: "have an org owner revoke the stale key: DELETE /orgs/v1/:org_id/members/:principal_id/encryption-key (owner + step-up); your next gitvault operation then enrolls this key" },
756
+ { type: "edit_request", why: "restore the keystore backup that holds the current key (~/.config/run402/vault or the wallet profile's vault dir)" },
757
+ { type: "edit_request", why: "have an org owner revoke the stale key: DELETE /orgs/v1/:org_id/members/:principal_id/encryption-key (owner + step-up); your next vault operation then enrolls this key" },
758
758
  { type: "edit_request", why: "if this principal is the sole custody-eligible member of every org it belongs to: POST /agent/v1/whoami/encryption-key with replace_current: true" },
759
759
  ],
760
760
  });
761
761
  }
762
- // gitvault-multi-writer rev 47 (task 5.3, design D9) — the signing half's
762
+ // vault-multi-writer rev 47 (task 5.3, design D9) — the signing half's
763
763
  // OWN continuity check, parallel to the encryption half's: does the
764
764
  // directory's currently-published signing_fingerprint already equal
765
765
  // this keystore's? UNLIKE the encryption half this is never a rotation
@@ -773,7 +773,7 @@ export class Gitvault {
773
773
  }
774
774
  const keypair = keystore.encryptionKeypair(identity);
775
775
  if (!keypair) {
776
- throw new LocalError("the keystore identity has no X25519 private key — it cannot enroll or open envelopes", "enrolling the keystore encryption key", { code: "VAULT_UNRECOVERABLE", details: { statement: GITVAULT_TERMINAL_LOSS_STATEMENT } });
776
+ throw new LocalError("the keystore identity has no X25519 private key — it cannot enroll or open envelopes", "enrolling the keystore encryption key", { code: "VAULT_UNRECOVERABLE", details: { statement: VAULT_TERMINAL_LOSS_STATEMENT } });
777
777
  }
778
778
  // The signing half rides the SAME publish call as the encryption half
779
779
  // (task 4.1's gateway contract: one round trip, both halves, all-or-
@@ -838,7 +838,7 @@ export class Gitvault {
838
838
  * allocation on first push).
839
839
  *
840
840
  * This is the ONE primitive the remote helper and the capture lane
841
- * (`run402 gitvault push`/`snapshot`) drive so that a push against an
841
+ * (`run402 repos capture`/`snapshot`) drive so that a push against an
842
842
  * unallocated project runs the six-stage creation journal inline instead of
843
843
  * refusing: it resolves `repo_id` from `project_id` exactly like
844
844
  * {@link open}, and when that resolution fails, tries to create the vault —
@@ -858,19 +858,19 @@ export class Gitvault {
858
858
  */
859
859
  async openOrCreate(options) {
860
860
  if (!options.repo_id && !options.project_id) {
861
- throw new LocalError("pass repo_id, or project_id to resolve it from the control plane", "opening the gitvault", { code: "GITVAULT_VAULT_UNRESOLVED" });
861
+ throw new LocalError("pass repo_id, or project_id to resolve it from the control plane", "opening the vault", { code: "VAULT_UNRESOLVED" });
862
862
  }
863
863
  // An explicit repo_id addresses the vault directly — there is nothing to
864
864
  // resolve or lazily create from an id alone, so this degrades to a plain
865
865
  // open (matches `open()`'s own precedence: repo_id always wins).
866
866
  if (options.repo_id) {
867
867
  const handle = await this.open(options);
868
- return { handle, found: true, created: null, terminal_loss_statement: GITVAULT_TERMINAL_LOSS_STATEMENT };
868
+ return { handle, found: true, created: null, terminal_loss_statement: VAULT_TERMINAL_LOSS_STATEMENT };
869
869
  }
870
- const [{ createGitvaultHttpTransport }, { GitvaultKeystore }, { openOrCreateGitvault }] = await Promise.all([this.#publication(), this.#keystore(), this.#openOrCreate()]);
871
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
872
- const transport = createGitvaultHttpTransport(this.#client, { byoBackend: await this.#byoBackendResolver(keystore) });
873
- const result = await openOrCreateGitvault({
870
+ const [{ createVaultHttpTransport }, { VaultKeystore }, { openOrCreateVault }] = await Promise.all([this.#publication(), this.#keystore(), this.#openOrCreate()]);
871
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
872
+ const transport = createVaultHttpTransport(this.#client, { byoBackend: await this.#byoBackendResolver(keystore) });
873
+ const result = await openOrCreateVault({
874
874
  keystore,
875
875
  transport,
876
876
  project_id: options.project_id,
@@ -880,29 +880,29 @@ export class Gitvault {
880
880
  });
881
881
  const handle = await this.open({ ...options, repo_id: result.repo_id });
882
882
  return result.found
883
- ? { handle, found: true, created: null, terminal_loss_statement: GITVAULT_TERMINAL_LOSS_STATEMENT }
884
- : { handle, found: false, created: result.created, terminal_loss_statement: GITVAULT_TERMINAL_LOSS_STATEMENT };
883
+ ? { handle, found: true, created: null, terminal_loss_statement: VAULT_TERMINAL_LOSS_STATEMENT }
884
+ : { handle, found: false, created: result.created, terminal_loss_statement: VAULT_TERMINAL_LOSS_STATEMENT };
885
885
  }
886
886
  /**
887
887
  * Resolve a parsed remote address to an OPEN handle, pinning `repo_id` in
888
888
  * local git state on the first successful resolution of EITHER form
889
- * (gitvault-client-round-trips design D4 widens the original slug-form-only
889
+ * (vault-client-round-trips design D4 widens the original slug-form-only
890
890
  * pin to id-form too — an id-form address needs no pin to survive a
891
891
  * rename, but the resolution round trip it skips is the same either way),
892
892
  * and — when `allow_create` is set and resolution misses — push-to-create
893
- * it. This is what the remote helper and `gitvault snapshot` drive for a
893
+ * it. This is what the remote helper and `vault snapshot` drive for a
894
894
  * `run402::<org>/<name>` remote, whichever form it names, so a caller need
895
895
  * not branch on the address's form itself. A pinned id/address that no
896
896
  * longer resolves (404) clears the pin and re-resolves once.
897
897
  *
898
898
  * `SLUG_RELEASED` is NEVER auto-followed — it rethrows unchanged; read it
899
- * with {@link gitvaultSlugReleasedInfo} for the successor slug and cooldown.
899
+ * with {@link vaultSlugReleasedInfo} for the successor slug and cooldown.
900
900
  */
901
901
  async resolveOrCreateAddress(options) {
902
- const [{ createGitvaultHttpTransport }, { GitvaultKeystore }, { resolveGitvaultAddress }] = await Promise.all([this.#publication(), this.#keystore(), this.#address()]);
903
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
904
- const transport = createGitvaultHttpTransport(this.#client, { byoBackend: await this.#byoBackendResolver(keystore) });
905
- const resolution = await resolveGitvaultAddress({
902
+ const [{ createVaultHttpTransport }, { VaultKeystore }, { resolveVaultAddress }] = await Promise.all([this.#publication(), this.#keystore(), this.#address()]);
903
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
904
+ const transport = createVaultHttpTransport(this.#client, { byoBackend: await this.#byoBackendResolver(keystore) });
905
+ const resolution = await resolveVaultAddress({
906
906
  keystore,
907
907
  transport,
908
908
  address: options.address,
@@ -917,13 +917,13 @@ export class Gitvault {
917
917
  handle,
918
918
  found: resolution.via !== "created",
919
919
  created: resolution.created,
920
- terminal_loss_statement: GITVAULT_TERMINAL_LOSS_STATEMENT,
920
+ terminal_loss_statement: VAULT_TERMINAL_LOSS_STATEMENT,
921
921
  resolution,
922
922
  };
923
923
  }
924
924
  /**
925
925
  * Stale-pin recovery for OFFLINE address resolutions
926
- * (gitvault-force-spelling-and-pin-fold): an id-carrying pin resolves with
926
+ * (vault-force-spelling-and-pin-fold): an id-carrying pin resolves with
927
927
  * zero network reads, so a pin gone stale (its vault deleted and the
928
928
  * project re-allocated a new one) surfaces as the VERB's first repo-scoped
929
929
  * read failing rather than as a resolution failure. Call this with that
@@ -935,10 +935,10 @@ export class Gitvault {
935
935
  * an unauthorized caller learns).
936
936
  */
937
937
  async recoverStalePin(options) {
938
- const [{ createGitvaultHttpTransport }, { GitvaultKeystore }, { recoverStaleGitvaultPin }] = await Promise.all([this.#publication(), this.#keystore(), this.#address()]);
939
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
940
- const transport = createGitvaultHttpTransport(this.#client, { byoBackend: await this.#byoBackendResolver(keystore) });
941
- const fresh = await recoverStaleGitvaultPin({
938
+ const [{ createVaultHttpTransport }, { VaultKeystore }, { recoverStaleVaultPin }] = await Promise.all([this.#publication(), this.#keystore(), this.#address()]);
939
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
940
+ const transport = createVaultHttpTransport(this.#client, { byoBackend: await this.#byoBackendResolver(keystore) });
941
+ const fresh = await recoverStaleVaultPin({
942
942
  keystore,
943
943
  transport,
944
944
  address: options.address,
@@ -953,7 +953,7 @@ export class Gitvault {
953
953
  handle,
954
954
  found: true,
955
955
  created: null,
956
- terminal_loss_statement: GITVAULT_TERMINAL_LOSS_STATEMENT,
956
+ terminal_loss_statement: VAULT_TERMINAL_LOSS_STATEMENT,
957
957
  resolution: fresh,
958
958
  };
959
959
  }
@@ -970,22 +970,22 @@ export class Gitvault {
970
970
  * named `run402` is added.
971
971
  */
972
972
  async init(options) {
973
- const [{ createGitvaultHttpTransport }, { GitvaultKeystore }, { createGitvault }] = await Promise.all([this.#publication(), this.#keystore(), this.#creation()]);
973
+ const [{ createVaultHttpTransport }, { VaultKeystore }, { createVault }] = await Promise.all([this.#publication(), this.#keystore(), this.#creation()]);
974
974
  const { parseMirrorDestinationUrl, formatMirrorDestination } = await this.#mirrorConfig();
975
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
976
- const transport = createGitvaultHttpTransport(this.#client, { byoBackend: await this.#byoBackendResolver(keystore) });
975
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
976
+ const transport = createVaultHttpTransport(this.#client, { byoBackend: await this.#byoBackendResolver(keystore) });
977
977
  let byoWriteTarget;
978
978
  let byoDestinationAddress;
979
979
  if (options.byo) {
980
980
  const destination = parseMirrorDestinationUrl(options.byo.destination_url, { region: options.byo.region, endpoint: options.byo.endpoint });
981
981
  byoWriteTarget = { destination, ...(options.byo.credential ? { credential: options.byo.credential } : {}) };
982
982
  byoDestinationAddress = formatMirrorDestination(destination);
983
- // gitvault-byo-primary-bucket task 3.1 (design D6) — probe BEFORE any
983
+ // vault-byo-primary-bucket task 3.1 (design D6) — probe BEFORE any
984
984
  // allocation request; a failed probe throws and nothing is created.
985
- const { probeGitvaultByoDestination } = await this.#byoProbe();
986
- await probeGitvaultByoDestination(destination, options.byo.credential);
985
+ const { probeVaultByoDestination } = await this.#byoProbe();
986
+ await probeVaultByoDestination(destination, options.byo.credential);
987
987
  }
988
- const created = await createGitvault({
988
+ const created = await createVault({
989
989
  keystore,
990
990
  transport,
991
991
  org_id: options.org_id,
@@ -1005,7 +1005,7 @@ export class Gitvault {
1005
1005
  ...(options.remote_url !== undefined ? { remote_url: options.remote_url } : {}),
1006
1006
  });
1007
1007
  }
1008
- // gitvault-byo-primary-bucket task 3.1/3.5 — read back the AUTHORITATIVE
1008
+ // vault-byo-primary-bucket task 3.1/3.5 — read back the AUTHORITATIVE
1009
1009
  // storage_profile from the vault record rather than trusting what THIS
1010
1010
  // call requested: an idempotent replay against a pre-existing vault
1011
1011
  // (a different client_creation_id, a different machine) can legitimately
@@ -1037,7 +1037,7 @@ export class Gitvault {
1037
1037
  genesis_sha256: created.genesis_sha256,
1038
1038
  remote,
1039
1039
  deduplicated: created.how === "reconciled",
1040
- terminal_loss_statement: GITVAULT_TERMINAL_LOSS_STATEMENT,
1040
+ terminal_loss_statement: VAULT_TERMINAL_LOSS_STATEMENT,
1041
1041
  storage_profile: storageProfile,
1042
1042
  byo_destination: byoDestination,
1043
1043
  };
@@ -1078,7 +1078,7 @@ export class Gitvault {
1078
1078
  */
1079
1079
  async scaffoldRemote(options) {
1080
1080
  const { hardenedGit } = await this.#snapshot();
1081
- const url = options.remote_url ?? gitvaultRemoteUrl(options.org_id, options.project_id);
1081
+ const url = options.remote_url ?? vaultRemoteUrl(options.org_id, options.project_id);
1082
1082
  let createdRepository = false;
1083
1083
  let enclosingToplevel = null;
1084
1084
  // The scaffold acts on the APP ROOT only (first-deploy-agent-dx, design
@@ -1218,7 +1218,7 @@ export class Gitvault {
1218
1218
  * Append `/<relative path of nestedDir from toplevel>/` to the enclosing
1219
1219
  * repository's LOCAL `.git/info/exclude` — never `.gitignore`, which is
1220
1220
  * tracked content (the same discipline as `excludeMessagingCacheFromGit`
1221
- * in `gitvault-restore.ts`). Located via `rev-parse --git-path
1221
+ * in `vault-restore.ts`). Located via `rev-parse --git-path
1222
1222
  * info/exclude` so a linked worktree resolves to its common dir. Creates
1223
1223
  * the file when absent; idempotent when the line is already there.
1224
1224
  * Returns whether the line is in place — `false` (never a throw) when the
@@ -1264,9 +1264,9 @@ export class Gitvault {
1264
1264
  * is stated verbatim exactly as for any other vault.
1265
1265
  */
1266
1266
  async status(options = {}) {
1267
- const { GitvaultKeystore } = await this.#keystore();
1267
+ const { VaultKeystore } = await this.#keystore();
1268
1268
  const { listPendingOverrideJournals } = await this.#deploy();
1269
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
1269
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
1270
1270
  let repoId = options.repo_id ?? null;
1271
1271
  let record = null;
1272
1272
  if (!repoId && options.project_id) {
@@ -1324,7 +1324,7 @@ export class Gitvault {
1324
1324
  let coveringRecipients = null;
1325
1325
  if (repoId && record) {
1326
1326
  try {
1327
- const coverage = await this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/envelope-recipients`, { context: "reading the gitvault envelope recipients" });
1327
+ const coverage = await this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/envelope-recipients`, { context: "reading the vault envelope recipients" });
1328
1328
  coveringRecipients = coverage.recipient_fingerprints.length;
1329
1329
  }
1330
1330
  catch {
@@ -1336,7 +1336,7 @@ export class Gitvault {
1336
1336
  if (keystorePresent && !canSign) {
1337
1337
  warnings.push({ kind: "read_only", message: "the signing key is missing from identity.json — this principal can decrypt and verify but cannot publish a new head" });
1338
1338
  }
1339
- if (record?.gitvault_policy === "grandfathered") {
1339
+ if (record?.vault_policy === "grandfathered") {
1340
1340
  warnings.push({ kind: "policy_grandfathered", message: "activation does not require vault admission on this project; return it to `required` when the migration is done" });
1341
1341
  }
1342
1342
  // D7 (repo-first-onramp task 2.7): a vault that has accrued enough value
@@ -1349,13 +1349,13 @@ export class Gitvault {
1349
1349
  // claims terminal loss (dogfood item 2: the single-principal premise
1350
1350
  // behind `terminal_loss_risk` is provably false for this vault).
1351
1351
  if (record) {
1352
- const trip = gitvaultLossWarningTrip(record);
1353
- if (gitvaultLossWarningTripped(trip)) {
1352
+ const trip = vaultLossWarningTrip(record);
1353
+ if (vaultLossWarningTripped(trip)) {
1354
1354
  if (isMultiPrincipal) {
1355
- warnings.push({ kind: "keystore_backup_reminder", message: gitvaultKeystoreBackupReminderMessage(trip, coveringRecipients) });
1355
+ warnings.push({ kind: "keystore_backup_reminder", message: vaultKeystoreBackupReminderMessage(trip, coveringRecipients) });
1356
1356
  }
1357
1357
  else {
1358
- warnings.push({ kind: "terminal_loss_risk", message: gitvaultLossWarningMessage(trip) });
1358
+ warnings.push({ kind: "terminal_loss_risk", message: vaultLossWarningMessage(trip) });
1359
1359
  }
1360
1360
  }
1361
1361
  }
@@ -1369,8 +1369,8 @@ export class Gitvault {
1369
1369
  // `.run402/` — a pure read, computed alongside the pin.
1370
1370
  let messagingCacheExcluded = null;
1371
1371
  if (options.repo_dir) {
1372
- const { readPinnedGitvaultRepo } = await this.#address();
1373
- const p = await readPinnedGitvaultRepo(options.repo_dir);
1372
+ const { readPinnedVaultRepo } = await this.#address();
1373
+ const p = await readPinnedVaultRepo(options.repo_dir);
1374
1374
  pinned = p ? { repo_id: p.repo_id, resolved_from: p.resolved_from, room: p.room } : null;
1375
1375
  const { isMessagingCacheExcludedFromGit } = await this.#restore();
1376
1376
  messagingCacheExcluded = await isMessagingCacheExcludedFromGit(options.repo_dir);
@@ -1400,10 +1400,16 @@ export class Gitvault {
1400
1400
  }
1401
1401
  if (!url)
1402
1402
  continue;
1403
- const parsed = parseGitvaultRemoteUrl(url);
1403
+ let parsed;
1404
+ try {
1405
+ parsed = parseVaultRemoteUrl(url);
1406
+ }
1407
+ catch {
1408
+ continue; // another scheme's remote — not a vault remote
1409
+ }
1404
1410
  if (!parsed)
1405
1411
  continue;
1406
- if (gitvaultRemoteAddressForm(parsed) === "id") {
1412
+ if (vaultRemoteAddressForm(parsed) === "id") {
1407
1413
  // Id-form: the URL's second half IS the real project id — the
1408
1414
  // pre-existing, always-correct comparison.
1409
1415
  remote = { name, url, matches: project === null || parsed.project_id === project, reason: null };
@@ -1440,7 +1446,7 @@ export class Gitvault {
1440
1446
  else if (options.refs === true && !holdsRepoKey) {
1441
1447
  warnings.push({ kind: "refs_unavailable", message: "this machine does not hold K_repo for the vault, so its ref map cannot be decrypted here" });
1442
1448
  }
1443
- // gitvault-agent-envelopes D3/D5: a KEY-HOLDER's ordinary read is a
1449
+ // vault-agent-envelopes D3/D5: a KEY-HOLDER's ordinary read is a
1444
1450
  // session start — enroll this keystore's key if absent and fulfil every
1445
1451
  // pending desired recipient once per process (best-effort, reported,
1446
1452
  // never folded into the observation above). `status` on a machine that
@@ -1464,7 +1470,7 @@ export class Gitvault {
1464
1470
  if (!record)
1465
1471
  nextActions.push({ action: "allocate the project's vault", command: "run402 repos create --project <project_id>" });
1466
1472
  else if (pending.length > 0)
1467
- nextActions.push({ action: `complete ${pending.length} unvaulted-override journal(s)`, command: "run402 repos snapshot" });
1473
+ nextActions.push({ action: `complete ${pending.length} unvaulted-override journal(s)`, command: "run402 repos capture" });
1468
1474
  else if (record && !holdsRepoKey)
1469
1475
  nextActions.push({ action: "this machine holds no key for the vault — allocate resolves to the existing vault and is idempotent", command: "run402 repos create --project <project_id>" });
1470
1476
  return {
@@ -1497,12 +1503,12 @@ export class Gitvault {
1497
1503
  refs,
1498
1504
  head_target: headTarget,
1499
1505
  pins: { highest_authenticated: authenticated, highest_materialized: materialized },
1500
- gitvault_policy: record?.gitvault_policy ?? null,
1506
+ vault_policy: record?.vault_policy ?? null,
1501
1507
  pending_overrides: pending.length,
1502
1508
  covering_recipients: coveringRecipients,
1503
- terminal_loss_statement: isMultiPrincipal ? null : GITVAULT_TERMINAL_LOSS_STATEMENT,
1504
- terminal_loss_detail: isMultiPrincipal ? null : GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT,
1505
- durability_statement: isMultiPrincipal ? GITVAULT_DURABILITY_STATEMENT : null,
1509
+ terminal_loss_statement: isMultiPrincipal ? null : VAULT_TERMINAL_LOSS_STATEMENT,
1510
+ terminal_loss_detail: isMultiPrincipal ? null : VAULT_TERMINAL_LOSS_DOCTOR_TEXT,
1511
+ durability_statement: isMultiPrincipal ? VAULT_DURABILITY_STATEMENT : null,
1506
1512
  warnings,
1507
1513
  next_actions: nextActions,
1508
1514
  };
@@ -1520,7 +1526,7 @@ export class Gitvault {
1520
1526
  * charges with reproducing them ("the helper SHALL reproduce the exact set of
1521
1527
  * objects reachable from the declared canonical refs (`refs/heads/*`,
1522
1528
  * `refs/tags/*`, protocol-owned `refs/run402/*`), plus the `HEAD` target" —
1523
- * gitvault-client-surface, "Faithful helper"; `run402 gitvault push` is
1529
+ * vault-client-surface, "Faithful helper"; `run402 repos capture` is
1524
1530
  * separately defined as "capture and push outside a deploy" under "Source
1525
1531
  * verbs"). The split is forced by §6.6: a dirty tree captures as a SYNTHETIC
1526
1532
  * commit that sits on no branch, so moving `refs/heads/main` onto it would
@@ -1536,8 +1542,8 @@ export class Gitvault {
1536
1542
  * against its expected manifest and reads the admitted head back from
1537
1543
  * storage. A 200 alone is never enough (§0 client obligations).
1538
1544
  */
1539
- async push(options) {
1540
- const [{ deployRefTransaction }, { captureSnapshot, gitvaultCommitLine }] = await Promise.all([this.#publication(), this.#snapshot()]);
1545
+ async capture(options) {
1546
+ const [{ deployRefTransaction }, { captureSnapshot, vaultCommitLine }] = await Promise.all([this.#publication(), this.#snapshot()]);
1541
1547
  const openedByAddress = options.address ? await this.resolveOrCreateAddress({ ...options, address: options.address, allow_create: true }) : null;
1542
1548
  const opened = openedByAddress ?? (await this.openOrCreate(options));
1543
1549
  const addressResolution = openedByAddress?.resolution ?? null;
@@ -1546,7 +1552,7 @@ export class Gitvault {
1546
1552
  let handle = opened.handle;
1547
1553
  const repoDir = options.repo_dir ?? process.cwd();
1548
1554
  const snapshot = await captureSnapshot({ dir: repoDir, ...(options.snapshot ?? {}) });
1549
- const line = gitvaultCommitLine(snapshot);
1555
+ const line = vaultCommitLine(snapshot);
1550
1556
  options.onCommitLine?.(line);
1551
1557
  // An OFFLINE (id-carrying pin) resolution discovers a stale pin on this
1552
1558
  // first repo-scoped read — recover once and retry against the fresh
@@ -1580,28 +1586,28 @@ export class Gitvault {
1580
1586
  // above (already returned/committed) — a mirror failure is a named
1581
1587
  // pending finding reported BESIDE the vault result, on its own field.
1582
1588
  const mirrorPush = await this.#tryMirrorPush(handle.repo_id, handle.keystore);
1583
- // gitvault-byo-primary-bucket task 3.3 — the SAME non-blocking contract,
1589
+ // vault-byo-primary-bucket task 3.3 — the SAME non-blocking contract,
1584
1590
  // fired right beside the mirror hook (skipped_no_mirror with no network
1585
1591
  // call for any managed vault or any machine with no local BYO config).
1586
1592
  const byoChainCopy = await this.#tryByoChainCopyPush(handle.repo_id, handle.keystore);
1587
1593
  // Deploy-time reconcile hook: fires on every successful push,
1588
1594
  // best-effort — a reconcile failure (including a read-only principal
1589
1595
  // with no signing key) is reported BESIDE the vault result, never a
1590
- // `push()` throw, same non-blocking contract as the mirror hook above.
1596
+ // `capture()` throw, same non-blocking contract as the mirror hook above.
1591
1597
  const reconcileRecipients = await this.#tryReconcileEnvelopeRecipients(handle.vault);
1592
- // gitvault-multi-writer (task 5.7) — the SAME best-effort contract,
1598
+ // vault-multi-writer (task 5.7) — the SAME best-effort contract,
1593
1599
  // fired right beside the encryption-recipient reconcile above: a fresh
1594
1600
  // push proves this session's own key is an active writer, so this is
1595
1601
  // the natural place a just-admitted member's own next push clears
1596
1602
  // whatever candidacy it left behind for OTHER pending members too.
1597
1603
  const writerReconcile = await this.#tryReconcileWriterAdmissions(handle.vault);
1598
- return { ...result, snapshot, gitvault_commit: snapshot.oid, gitvault_commit_line: line, mirror_push: mirrorPush, byo_chain_copy: byoChainCopy, reconcile_recipients: reconcileRecipients, writer_reconcile: writerReconcile };
1604
+ return { ...result, snapshot, vault_commit: snapshot.oid, vault_commit_line: line, mirror_push: mirrorPush, byo_chain_copy: byoChainCopy, reconcile_recipients: reconcileRecipients, writer_reconcile: writerReconcile };
1599
1605
  }
1600
1606
  // ── Handoff / resume (kygit-handoff design D1-D10) ─────────────────────────
1601
1607
  /**
1602
1608
  * Mint a Handoff Key: capture a stash-shaped checkpoint (design D1),
1603
- * push it (retained, on no branch — {@link GITVAULT_DEPLOY_REF} carries
1604
- * it exactly like an ordinary `push()`, never `refs/heads/*`), seal the
1609
+ * push it (retained, on no branch — {@link VAULT_DEPLOY_REF} carries
1610
+ * it exactly like an ordinary `capture()`, never `refs/heads/*`), seal the
1605
1611
  * vault's current epoch key under a fresh `wrap_key`, and mint through
1606
1612
  * the gateway. The assembled `kgh1_…` key is returned exactly ONCE —
1607
1613
  * nothing here or downstream persists it.
@@ -1617,10 +1623,10 @@ export class Gitvault {
1617
1623
  const repoDir = options.repo_dir ?? process.cwd();
1618
1624
  const repoFile = handle.keystore.readRepo(handle.repo_id);
1619
1625
  if (!repoFile) {
1620
- throw new LocalError(`no local key material for ${handle.repo_id} — this principal is not yet a member with a materialized envelope (push once first)`, "minting a handoff", { code: "GITVAULT_VAULT_UNRESOLVED" });
1626
+ throw new LocalError(`no local key material for ${handle.repo_id} — this principal is not yet a member with a materialized envelope (push once first)`, "minting a handoff", { code: "VAULT_UNRESOLVED" });
1621
1627
  }
1622
1628
  const kRepo = hexToBytes(repoFile.k_repo_hex);
1623
- // gitvault-multi-writer rev 47 (task 5.5, design D4): only an ACTIVE
1629
+ // vault-multi-writer rev 47 (task 5.5, design D4): only an ACTIVE
1624
1630
  // WRITER may mint — the gateway enforces this authoritatively at mint
1625
1631
  // time (`403 HANDOFF_MINT_REQUIRES_WRITER`), but failing that late
1626
1632
  // would mean this call already paid for a checkpoint capture + push +
@@ -1632,20 +1638,20 @@ export class Gitvault {
1632
1638
  const identity = handle.keystore.readIdentity();
1633
1639
  const localWriterKeyId = identity?.signing_fingerprint ?? null;
1634
1640
  if (!localWriterKeyId || !repoFile.writer_set_pin?.writers.some((w) => w.writer_key_id === localWriterKeyId)) {
1635
- throw new LocalError("this keystore's signing key is not an admitted writer of this vault — minting a handoff requires an ACTIVE writer (design D4); an existing writer must add this key first (`run402 orgs members add` / repos access sync), or push once to reconcile if a pending admission already exists", "minting a handoff", { code: "GITVAULT_WRITER_NOT_ADMITTED" });
1641
+ throw new LocalError("this keystore's signing key is not an admitted writer of this vault — minting a handoff requires an ACTIVE writer (design D4); an existing writer must add this key first (`run402 orgs members add` / repos access sync), or push once to reconcile if a pending admission already exists", "minting a handoff", { code: "VAULT_WRITER_NOT_ADMITTED" });
1636
1642
  }
1637
1643
  // The grant's `minted_role` must EXACTLY predict what the gateway's own
1638
- // role-attenuation (`services/gitvault/claims.ts mintHandoff`) will
1644
+ // role-attenuation (`services/vault/claims.ts mintHandoff`) will
1639
1645
  // compute, or the grant fails VALIDATION_FAILED after this call has
1640
1646
  // already paid for the checkpoint push below — `predictMintedRole`
1641
1647
  // mirrors that formula against the SAME `ORG_ROLE_RANK` lattice
1642
- // `gitvault-writer-state.ts` already uses elsewhere in this codebase.
1648
+ // `vault-writer-state.ts` already uses elsewhere in this codebase.
1643
1649
  const { predictMintedRole } = await this.#writerState();
1644
1650
  const vaultRecord = await this.get(handle.repo_id);
1645
1651
  const who = await this.#client.request("/agent/v1/whoami", { context: "resolving this principal's org role for the handoff grant" });
1646
1652
  const membership = who.memberships.find((m) => m.org_id === vaultRecord.org_id && m.status === "active");
1647
1653
  if (!membership) {
1648
- throw new LocalError(`this principal has no active membership on ${vaultRecord.org_id} — an active writer must also be an active org member to mint a handoff`, "minting a handoff", { code: "GITVAULT_ACCESS_DENIED" });
1654
+ throw new LocalError(`this principal has no active membership on ${vaultRecord.org_id} — an active writer must also be an active org member to mint a handoff`, "minting a handoff", { code: "VAULT_ACCESS_DENIED" });
1649
1655
  }
1650
1656
  const grantMintedRole = predictMintedRole(options.role, membership.role);
1651
1657
  const snapshot = await captureHandoffSnapshot({
@@ -1686,7 +1692,7 @@ export class Gitvault {
1686
1692
  const handoffId = randomHandoffUuid();
1687
1693
  const { key, handoff_id_bytes, master_secret } = assembleHandoffKey(handoffId, randomBytes(32));
1688
1694
  const secrets = deriveHandoffSecrets(handoff_id_bytes, master_secret);
1689
- // gitvault-multi-writer rev 47 (task 5.5, design D4) — the MINTER's own
1695
+ // vault-multi-writer rev 47 (task 5.5, design D4) — the MINTER's own
1690
1696
  // writer key signs `writer_admission_grant`, authorizing whoever redeems
1691
1697
  // this handoff to become a writer (D224/D225). This is a HARD
1692
1698
  // requirement distinct from the earlier `writer_set_pin` presence
@@ -1732,7 +1738,7 @@ export class Gitvault {
1732
1738
  // the pre-rotation generations too ("membership grants FULL history"),
1733
1739
  // and no rotation ever re-wraps old epochs to a principal that did not
1734
1740
  // exist then. Found live: a recipient redeemed a post-removal handoff
1735
- // and its clone died GITVAULT_EPOCH_NOT_OPENABLE at generation 1.
1741
+ // and its clone died VAULT_EPOCH_NOT_OPENABLE at generation 1.
1736
1742
  epoch_keys: { ...(repoFile.epoch_keys ?? {}), [repoFile.epoch]: repoFile.k_repo_hex },
1737
1743
  checkpoint: { generation: pushResult.generation, commit_oid: snapshot.oid },
1738
1744
  note_schema: "kygit.handoff-note.v1",
@@ -1743,7 +1749,7 @@ export class Gitvault {
1743
1749
  // `project_id`, a verbatim `warning` sentence plus its machine-readable
1744
1750
  // `warnings[]` twin. Read those names exactly — an SDK-side spelling
1745
1751
  // that the gateway never sends surfaces as "role undefined" at the CLI.
1746
- const response = await this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(handle.repo_id)}/handoffs`, {
1752
+ const response = await this.#client.request(`/vaults/v1/${encodeURIComponent(handle.repo_id)}/handoffs`, {
1747
1753
  method: "POST",
1748
1754
  body: {
1749
1755
  handoff_id: handoffId,
@@ -1775,7 +1781,7 @@ export class Gitvault {
1775
1781
  expires_at: response.expires_at,
1776
1782
  // A slug-form remote is the one address the minter already knows;
1777
1783
  // an id-form one carries nothing a directory name should be built from.
1778
- vault: handoffVaultFromWire(response, options.address && gitvaultRemoteAddressForm(options.address) === "slug" ? `${options.address.org_id}/${options.address.project_id}` : null),
1784
+ vault: handoffVaultFromWire(response, options.address && vaultRemoteAddressForm(options.address) === "slug" ? `${options.address.org_id}/${options.address.project_id}` : null),
1779
1785
  checkpoint: response.checkpoint,
1780
1786
  capture: {
1781
1787
  modified_captured: snapshot.modified_captured.length,
@@ -1791,17 +1797,17 @@ export class Gitvault {
1791
1797
  /** List a vault's handoffs (ids, kind, state, role, expiry, redeemed_by — never the hash or envelope). */
1792
1798
  async listHandoffs(options) {
1793
1799
  const repoId = await this.#resolveRepoId(options);
1794
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/handoffs`, { context: "listing handoffs" });
1800
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/handoffs`, { context: "listing handoffs" });
1795
1801
  }
1796
1802
  /** Revoke a handoff (idempotent — a second revoke of an already-revoked/redeemed/expired row still answers `200`). */
1797
1803
  async revokeHandoff(handoffId, options) {
1798
1804
  const repoId = await this.#resolveRepoId(options);
1799
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/handoffs/${encodeURIComponent(handoffId)}`, { method: "DELETE", context: "revoking a handoff" });
1805
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/handoffs/${encodeURIComponent(handoffId)}`, { method: "DELETE", context: "revoking a handoff" });
1800
1806
  }
1801
1807
  // ── Invite / join (kygit-invite design D1-D10) ─────────────────────────────
1802
1808
  /**
1803
1809
  * Mint an Invite Key: capture a stash-shaped checkpoint exactly as
1804
- * {@link Gitvault.handoff} does (design D1), push it (retained, on no
1810
+ * {@link Repos.handoff} does (design D1), push it (retained, on no
1805
1811
  * branch), register the INVITER's own presence in the invite's room
1806
1812
  * (design D4 — before the mint, so the row can carry
1807
1813
  * `inviter_presence_id`; a registration failure is reported and the mint
@@ -1821,16 +1827,16 @@ export class Gitvault {
1821
1827
  */
1822
1828
  async invite(options) {
1823
1829
  const [{ deployRefTransaction }, { captureHandoffSnapshot, snapshotCommitment }] = await Promise.all([this.#publication(), this.#snapshot()]);
1824
- const ho = await nodeOnly(() => import("../node/gitvault-handoff.js"), "invite");
1830
+ const ho = await nodeOnly(() => import("../node/vault-handoff.js"), "invite");
1825
1831
  const { assembleInviteKey, deriveInviteSecrets, sealInviteEnvelope, assertInviteNoteHasNoSecret, buildWriterAdmissionGrant, deriveInviteWriterAdmissionSeed, INVITE_ENVELOPE_V2_KIND } = ho;
1826
1832
  const handle = options.address ? (await this.resolveOrCreateAddress({ ...options, address: options.address, allow_create: false })).handle : await this.open(options);
1827
1833
  const repoDir = options.repo_dir ?? process.cwd();
1828
1834
  const repoFile = handle.keystore.readRepo(handle.repo_id);
1829
1835
  if (!repoFile) {
1830
- throw new LocalError(`no local key material for ${handle.repo_id} — this principal is not yet a member with a materialized envelope (push once first)`, "minting an invite", { code: "GITVAULT_VAULT_UNRESOLVED" });
1836
+ throw new LocalError(`no local key material for ${handle.repo_id} — this principal is not yet a member with a materialized envelope (push once first)`, "minting an invite", { code: "VAULT_UNRESOLVED" });
1831
1837
  }
1832
1838
  const kRepo = hexToBytes(repoFile.k_repo_hex);
1833
- // gitvault-multi-writer rev 47 (kygit-invite design D4): only an ACTIVE
1839
+ // vault-multi-writer rev 47 (kygit-invite design D4): only an ACTIVE
1834
1840
  // WRITER may mint — the gateway enforces it authoritatively
1835
1841
  // (`403 INVITE_MINT_REQUIRES_WRITER`, carrying `request_writer_sync`),
1836
1842
  // but failing that late would mean this call already paid for a
@@ -1841,7 +1847,7 @@ export class Gitvault {
1841
1847
  const identity = handle.keystore.readIdentity();
1842
1848
  const localWriterKeyId = identity?.signing_fingerprint ?? null;
1843
1849
  if (!localWriterKeyId || !repoFile.writer_set_pin?.writers.some((w) => w.writer_key_id === localWriterKeyId)) {
1844
- throw new LocalError("this keystore's signing key is not an admitted writer of this vault — minting an invite requires an ACTIVE writer (the gateway's own refusal is INVITE_MINT_REQUIRES_WRITER); run `run402 repos access sync` from a live writer, or push once to reconcile if a pending admission already exists", "minting an invite", { code: "GITVAULT_WRITER_NOT_ADMITTED", details: { next_action: "request_writer_sync", command: "run402 repos access sync" } });
1850
+ throw new LocalError("this keystore's signing key is not an admitted writer of this vault — minting an invite requires an ACTIVE writer (the gateway's own refusal is INVITE_MINT_REQUIRES_WRITER); run `run402 repos access sync` from a live writer, or push once to reconcile if a pending admission already exists", "minting an invite", { code: "VAULT_WRITER_NOT_ADMITTED", details: { next_action: "request_writer_sync", command: "run402 repos access sync" } });
1845
1851
  }
1846
1852
  // The grant's `minted_role` must EXACTLY predict what the gateway's own
1847
1853
  // role attenuation will compute (invite defaults to `developer` rather
@@ -1853,7 +1859,7 @@ export class Gitvault {
1853
1859
  const whoMints = await this.#client.request("/agent/v1/whoami", { context: "resolving this principal's org role for the invite grant" });
1854
1860
  const inviterMembership = whoMints.memberships.find((m) => m.org_id === vaultRecord.org_id && m.status === "active");
1855
1861
  if (!inviterMembership) {
1856
- throw new LocalError(`this principal has no active membership on ${vaultRecord.org_id} — an active writer must also be an active org member to mint an invite`, "minting an invite", { code: "GITVAULT_ACCESS_DENIED" });
1862
+ throw new LocalError(`this principal has no active membership on ${vaultRecord.org_id} — an active writer must also be an active org member to mint an invite`, "minting an invite", { code: "VAULT_ACCESS_DENIED" });
1857
1863
  }
1858
1864
  const grantMintedRole = predictMintedRole(options.role ?? INVITE_DEFAULT_ROLE, inviterMembership.role);
1859
1865
  const snapshot = await captureHandoffSnapshot({
@@ -1912,7 +1918,7 @@ export class Gitvault {
1912
1918
  const inviteId = randomHandoffUuid();
1913
1919
  const { key, invite_id_bytes, master_secret } = assembleInviteKey(inviteId, randomBytes(32));
1914
1920
  const secrets = deriveInviteSecrets(invite_id_bytes, master_secret);
1915
- // gitvault-multi-writer rev 47 (kygit-invite design D4) — the MINTER's
1921
+ // vault-multi-writer rev 47 (kygit-invite design D4) — the MINTER's
1916
1922
  // own writer key signs `writer_admission_grant`, authorizing whoever
1917
1923
  // redeems this invite to become a writer under its OWN key. Built and
1918
1924
  // SIGNED BEFORE the envelope is sealed ("no hash cycle: grant first,
@@ -1960,10 +1966,10 @@ export class Gitvault {
1960
1966
  writer_admission_grant_sha256: grantSha256Local,
1961
1967
  });
1962
1968
  // The wire shape mirrors the handoff mint's documented one (llms-full.txt
1963
- // "Handoff / resume", gitvault-invite spec): `role` (the minted role),
1969
+ // "Handoff / resume", vault-invite spec): `role` (the minted role),
1964
1970
  // `repo_id` / `org_id` / `project_id`, `room`, a verbatim `warning`
1965
1971
  // sentence plus its machine-readable `warnings[]` twin.
1966
- const response = await this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(handle.repo_id)}/invites`, {
1972
+ const response = await this.#client.request(`/vaults/v1/${encodeURIComponent(handle.repo_id)}/invites`, {
1967
1973
  method: "POST",
1968
1974
  body: {
1969
1975
  invite_id: inviteId,
@@ -2015,14 +2021,10 @@ export class Gitvault {
2015
2021
  }
2016
2022
  const nextActions = [...(response.next_actions ?? [])];
2017
2023
  if (!nextActions.some((a) => a.type === "join_invite")) {
2018
- // design D9: "CLI-synthesized, the recipient's exact command" —
2019
- // rendered by DOOR, same as every other remote-facing command this
2020
- // module renders (`gitvaultRemoteScheme()` is the one place that
2021
- // decides `run402` vs `kygit`, per `RUN402_REMOTE_SCHEME`).
2022
- const door = gitvaultRemoteScheme();
2024
+ // design D9: "CLI-synthesized, the recipient's exact command".
2023
2025
  nextActions.push({
2024
2026
  type: "join_invite",
2025
- command: door === "kygit" ? `kygit join ${key}` : `run402 repos join ${key}`,
2027
+ command: `run402 repos join ${key}`,
2026
2028
  why: "Run this on the other agent's machine to redeem the invite.",
2027
2029
  safe_to_auto_execute: false,
2028
2030
  });
@@ -2036,7 +2038,7 @@ export class Gitvault {
2036
2038
  kind: response.kind,
2037
2039
  minted_role: response.role,
2038
2040
  expires_at: response.expires_at,
2039
- vault: handoffVaultFromWire(response, options.address && gitvaultRemoteAddressForm(options.address) === "slug" ? `${options.address.org_id}/${options.address.project_id}` : null),
2041
+ vault: handoffVaultFromWire(response, options.address && vaultRemoteAddressForm(options.address) === "slug" ? `${options.address.org_id}/${options.address.project_id}` : null),
2040
2042
  room: { organization_id: response.room?.org_id ?? repoFile.org_id, room_key: response.room?.room_key ?? roomKey },
2041
2043
  checkpoint: response.checkpoint,
2042
2044
  capture: {
@@ -2055,12 +2057,12 @@ export class Gitvault {
2055
2057
  /** List a vault's invites (ids, kind, state, role, room, expiry, redeemed_by — never the hash or envelope). */
2056
2058
  async listInvites(options) {
2057
2059
  const repoId = await this.#resolveRepoId(options);
2058
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/invites`, { context: "listing invites" });
2060
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/invites`, { context: "listing invites" });
2059
2061
  }
2060
2062
  /** Revoke an invite (idempotent — a second revoke of an already-revoked/redeemed/expired row still answers `200`). */
2061
2063
  async revokeInvite(inviteId, options) {
2062
2064
  const repoId = await this.#resolveRepoId(options);
2063
- return this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/invites/${encodeURIComponent(inviteId)}`, { method: "DELETE", context: "revoking an invite" });
2065
+ return this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/invites/${encodeURIComponent(inviteId)}`, { method: "DELETE", context: "revoking an invite" });
2064
2066
  }
2065
2067
  /**
2066
2068
  * Create this machine's wallet (the wallet file) when the credentials
@@ -2089,7 +2091,7 @@ export class Gitvault {
2089
2091
  * envelope supersedes the bearer one.
2090
2092
  */
2091
2093
  /**
2092
- * gitvault-multi-writer rev 47 (task 5.6, design D4/D5) — order: parse →
2094
+ * vault-multi-writer rev 47 (task 5.6, design D4/D5) — order: parse →
2093
2095
  * ensure wallet → ensure identity → derive auth/wrap/admission → build
2094
2096
  * acceptance → redeem → verify grant → open envelope → check the grant
2095
2097
  * hash → persist repo file with `pending_writer_admission` → clone →
@@ -2112,14 +2114,14 @@ export class Gitvault {
2112
2114
  * "not yet a writer" refuses; here "already a writer" means skip.
2113
2115
  */
2114
2116
  async resume(options) {
2115
- const [ho, { GitvaultKeystore }, restore] = await Promise.all([this.#handoff(), this.#keystore(), this.#restore()]);
2117
+ const [ho, { VaultKeystore }, restore] = await Promise.all([this.#handoff(), this.#keystore(), this.#restore()]);
2116
2118
  const { parseHandoffKey, deriveHandoffSecrets, deriveWriterAdmissionSeed, buildWriterAcceptance, openHandoffEnvelopeV2 } = ho;
2117
- const { cloneGitvaultRemote, applyHandoffCheckpoint, resolveResumeTargetDir, readGitCommitMessage, excludeMessagingCacheFromGit } = restore;
2119
+ const { cloneVaultRemote, applyHandoffCheckpoint, resolveResumeTargetDir, readGitCommitMessage, excludeMessagingCacheFromGit } = restore;
2118
2120
  // parse
2119
2121
  const parsed = parseHandoffKey(options.key);
2120
2122
  // ensure wallet — A fresh machine has no wallet, and the redeem route
2121
2123
  // accepts ONLY a SIWX wallet signature (a control-plane session,
2122
- // delegate, or service key is refused HANDOFF_REDEEM_REQUIRES_WALLET —
2124
+ // grant key, or service key is refused HANDOFF_REDEEM_REQUIRES_WALLET —
2123
2125
  // the keystore key the redemption publishes is what makes the recipient a
2124
2126
  // real key-holder). Nothing upstream creates the wallet for an
2125
2127
  // unpaid request, so `resume` does it here, exactly as `repos resume
@@ -2131,11 +2133,11 @@ export class Gitvault {
2131
2133
  await this.#ensureLocalWallet(options.onLine);
2132
2134
  // ensure identity — BEFORE redeem (D5): the acceptance below needs this
2133
2135
  // checkout's own signing key, which the redeem REQUEST body carries.
2134
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
2136
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
2135
2137
  const identity = keystore.ensureIdentity();
2136
2138
  const signingKeypair = keystore.signingKeypair(identity);
2137
2139
  if (!signingKeypair) {
2138
- throw new LocalError("this keystore has no local signing seed — resuming a gitvault-multi-writer handoff requires signing writer_acceptance with a full Ed25519 seed, which a read-only recovery identity does not hold", "resuming a handoff", { code: "VAULT_UNRECOVERABLE" });
2140
+ throw new LocalError("this keystore has no local signing seed — resuming a vault-multi-writer handoff requires signing writer_acceptance with a full Ed25519 seed, which a read-only recovery identity does not hold", "resuming a handoff", { code: "VAULT_UNRECOVERABLE" });
2139
2141
  }
2140
2142
  const redeemerEncryptionPubkeyRaw = fromBase64url(identity.encryption_pubkey, "identity.encryption_pubkey");
2141
2143
  // derive auth/wrap/admission
@@ -2152,7 +2154,7 @@ export class Gitvault {
2152
2154
  redeemer_encryption_pubkey_raw: redeemerEncryptionPubkeyRaw,
2153
2155
  });
2154
2156
  // claim
2155
- const redeem = await this.#client.request(`/gitvault/v1/handoffs/${encodeURIComponent(parsed.handoff_id)}/redeem`, {
2157
+ const redeem = await this.#client.request(`/vaults/v1/handoffs/${encodeURIComponent(parsed.handoff_id)}/redeem`, {
2156
2158
  method: "POST",
2157
2159
  // Base64url, per the documented wire contract (openapi: "Base64url — the
2158
2160
  // HKDF-derived auth_secret half of the parsed kgh1_ key"). The gateway
@@ -2193,7 +2195,7 @@ export class Gitvault {
2193
2195
  // open envelope — v2 (task 5.4): the v2 payload's own
2194
2196
  // writer_admission_grant_sha256 is what the next step cross-checks;
2195
2197
  // opening under the SAME v1/v2-requiring rule that refuses a
2196
- // pre-gitvault-multi-writer mint's envelope outright.
2198
+ // pre-vault-multi-writer mint's envelope outright.
2197
2199
  const payload = openHandoffEnvelopeV2(parsed.handoff_id_bytes, secrets.wrap_key, redeem.sealed_envelope, redeem.envelope_kind);
2198
2200
  if (payload.repo_id !== vault.vault_id) {
2199
2201
  throw new LocalError("the opened envelope's repo_id does not match the redeem response's vault — refusing", "resuming a handoff", { code: "HANDOFF_ENVELOPE_INVALID" });
@@ -2207,18 +2209,18 @@ export class Gitvault {
2207
2209
  throw new LocalError(`the redeem response's writer_admission_grant (sha256 ${grantSha256}) does not match the hash sealed into the envelope at mint time (${payload.writer_admission_grant_sha256}) — refusing to activate under a substituted grant`, "resuming a handoff", { code: "HANDOFF_REDEEM_WRITER_KEY_MISMATCH", details: { expected: payload.writer_admission_grant_sha256, received: grantSha256 } });
2208
2210
  }
2209
2211
  // Genesis must be pinned before ANY materialize call can succeed
2210
- // (`GitvaultVault.genesis()` requires a keystore repo file — this is
2212
+ // (`Vault.genesis()` requires a keystore repo file — this is
2211
2213
  // the one read that happens BEFORE one exists, via the transport
2212
2214
  // directly, mirroring `restoreRepoFromEnvelope`'s own signature check).
2213
- const { createGitvaultHttpTransport } = await this.#publication();
2214
- const transport = createGitvaultHttpTransport(this.#client);
2215
+ const { createVaultHttpTransport } = await this.#publication();
2216
+ const transport = createVaultHttpTransport(this.#client);
2215
2217
  const genesisBytes = await transport.getGenesis({ repo_id: vault.vault_id });
2216
2218
  if (!genesisBytes) {
2217
2219
  throw new LocalError("the vault has no admitted genesis", "resuming a handoff", { code: "CHAIN_BROKEN", details: { repo_id: vault.vault_id } });
2218
2220
  }
2219
- const genesis = parseGitvaultStrict(new TextDecoder().decode(genesisBytes));
2220
- if (!verifyGitvaultObject(genesis, genesis.creator_signing_pubkey)) {
2221
- throw new LocalError("vault_genesis signature does not verify", "resuming a handoff", { code: "GITVAULT_SIGNATURE_INVALID", details: { repo_id: vault.vault_id } });
2221
+ const genesis = parseVaultStrict(new TextDecoder().decode(genesisBytes));
2222
+ if (!verifyVaultObject(genesis, genesis.creator_signing_pubkey)) {
2223
+ throw new LocalError("vault_genesis signature does not verify", "resuming a handoff", { code: "VAULT_SIGNATURE_INVALID", details: { repo_id: vault.vault_id } });
2222
2224
  }
2223
2225
  const genesisSha = sha256Hex(genesisBytes);
2224
2226
  // persist repo file with pending_writer_admission — BEFORE clone/chain
@@ -2245,14 +2247,14 @@ export class Gitvault {
2245
2247
  });
2246
2248
  const targetDir = await resolveResumeTargetDir(options.to, vault.address, vault.vault_id);
2247
2249
  options.onLine?.(`resuming into ${targetDir}`);
2248
- const remoteUrl = gitvaultRemoteUrl(vault.organization_id, vault.project_id);
2249
- await cloneGitvaultRemote(remoteUrl, targetDir);
2250
+ const remoteUrl = vaultRemoteUrl(vault.organization_id, vault.project_id);
2251
+ await cloneVaultRemote(remoteUrl, targetDir);
2250
2252
  // Local-only pins (design D10) — never a worktree file, never the
2251
2253
  // global active project. Reuses the SAME pin-writer every other
2252
- // gitvault resolution path uses, which also writes `r402.room`.
2253
- const { pinGitvaultRepo } = await this.#address();
2254
+ // vault resolution path uses, which also writes `r402.room`.
2255
+ const { pinVaultRepo } = await this.#address();
2254
2256
  const addressParts = vault.address ? vault.address.split("/") : null;
2255
- await pinGitvaultRepo(targetDir, vault.vault_id, addressParts && addressParts.length === 2 ? { org_slug: addressParts[0], repo_name: addressParts[1] } : undefined, { project_id: vault.project_id, org_id: vault.organization_id });
2257
+ await pinVaultRepo(targetDir, vault.vault_id, addressParts && addressParts.length === 2 ? { org_slug: addressParts[0], repo_name: addressParts[1] } : undefined, { project_id: vault.project_id, org_id: vault.organization_id });
2256
2258
  // kygit-invite design D5: restore is kind-agnostic, so the same
2257
2259
  // `.git/info/exclude` write `join` performs happens on `resume` too —
2258
2260
  // best-effort, never a `resume()` throw.
@@ -2262,7 +2264,7 @@ export class Gitvault {
2262
2264
  catch {
2263
2265
  // Best-effort: an unwritable checkout still completes the resume.
2264
2266
  }
2265
- // verify chain — `open()` here mainly constructs the `GitvaultVault`
2267
+ // verify chain — `open()` here mainly constructs the `Vault`
2266
2268
  // instance: its own `ensureRepoState()` (the cold-open restore path)
2267
2269
  // no-ops the instant it sees a repo file already on disk — and the
2268
2270
  // `saveRepo` call above just wrote one. The chain walk this method
@@ -2294,10 +2296,10 @@ export class Gitvault {
2294
2296
  // Clearing pending_writer_admission now that the activation head is
2295
2297
  // (or already was — the idempotent-skip case) admitted mirrors
2296
2298
  // writer_status flipping to "active" at the same moment, per this
2297
- // field's own doc comment in gitvault-keystore.ts.
2299
+ // field's own doc comment in vault-keystore.ts.
2298
2300
  keystore.updateRepo(vault.vault_id, { pending_writer_admission: null });
2299
2301
  // reconcile principal envelope — the bearer envelope is superseded
2300
- // within minutes of use; run the same reconcile `push()` runs,
2302
+ // within minutes of use; run the same reconcile `capture()` runs,
2301
2303
  // best-effort (never a `resume()` throw), NOW that this checkout is an
2302
2304
  // admitted writer and the reconcile's own wrap step is meaningful.
2303
2305
  const reconcile = await this.#tryReconcileEnvelopeRecipients(handle.vault);
@@ -2346,7 +2348,7 @@ export class Gitvault {
2346
2348
  /**
2347
2349
  * Join an Invite Key: parse (refusing a `kgh1_` handoff key by name,
2348
2350
  * pointing at `resume` — design D9) → ensure this machine has a wallet
2349
- * (design D5, mirroring {@link Gitvault.resume}'s own bare-wallet
2351
+ * (design D5, mirroring {@link Repos.resume}'s own bare-wallet
2350
2352
  * backstop; the CALLER folds the fuller cold-start chain — wallet,
2351
2353
  * faucet, one x402 prototype payment — before invoking this, never
2352
2354
  * blocking the redemption itself) → redeem → open the sealed envelope → write
@@ -2360,14 +2362,14 @@ export class Gitvault {
2360
2362
  * the most recent messages for the arrival view.
2361
2363
  */
2362
2364
  async join(options) {
2363
- const [ho, { GitvaultKeystore }, { createGitvaultHttpTransport }] = await Promise.all([
2364
- nodeOnly(() => import("../node/gitvault-handoff.js"), "join"),
2365
+ const [ho, { VaultKeystore }, { createVaultHttpTransport }] = await Promise.all([
2366
+ nodeOnly(() => import("../node/vault-handoff.js"), "join"),
2365
2367
  this.#keystore(),
2366
2368
  this.#publication(),
2367
2369
  ]);
2368
- const restore = await nodeOnly(() => import("../node/gitvault-restore.js"), "join");
2370
+ const restore = await nodeOnly(() => import("../node/vault-restore.js"), "join");
2369
2371
  const { parseInviteKey, deriveInviteSecrets, deriveInviteWriterAdmissionSeed, buildWriterAcceptance, openInviteEnvelope } = ho;
2370
- const { cloneGitvaultRemote, applyHandoffCheckpoint, resolveResumeTargetDir, readGitCommitMessage, excludeMessagingCacheFromGit } = restore;
2372
+ const { cloneVaultRemote, applyHandoffCheckpoint, resolveResumeTargetDir, readGitCommitMessage, excludeMessagingCacheFromGit } = restore;
2371
2373
  const parsed = parseInviteKey(options.key);
2372
2374
  const secrets = deriveInviteSecrets(parsed.invite_id_bytes, parsed.master_secret);
2373
2375
  // Bare-wallet backstop, exactly like `resume` (design D5) — the claim
@@ -2379,7 +2381,7 @@ export class Gitvault {
2379
2381
  // below needs THIS checkout's own signing key, and the redeem REQUEST
2380
2382
  // body carries it. Nothing about the joiner's key is copied from the
2381
2383
  // inviter — the joiner generates it and pushes under it.
2382
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
2384
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
2383
2385
  const identity = keystore.ensureIdentity();
2384
2386
  const signingKeypair = keystore.signingKeypair(identity);
2385
2387
  if (!signingKeypair) {
@@ -2399,7 +2401,7 @@ export class Gitvault {
2399
2401
  redeemer_signing_seed: signingKeypair.seed,
2400
2402
  redeemer_encryption_pubkey_raw: redeemerEncryptionPubkeyRaw,
2401
2403
  });
2402
- const redeem = await this.#client.request(`/gitvault/v1/invites/${encodeURIComponent(parsed.invite_id)}/redeem`, {
2404
+ const redeem = await this.#client.request(`/vaults/v1/invites/${encodeURIComponent(parsed.invite_id)}/redeem`, {
2403
2405
  method: "POST",
2404
2406
  // Base64url, per the documented wire contract — the gateway decodes
2405
2407
  // base64/base64url and substitutes 32 zero bytes for anything else,
@@ -2452,14 +2454,14 @@ export class Gitvault {
2452
2454
  // Genesis must be pinned before ANY materialize call can succeed — the
2453
2455
  // one read that happens BEFORE a keystore repo file exists, via the
2454
2456
  // transport directly (mirrors `resume`'s own signature check).
2455
- const transport = createGitvaultHttpTransport(this.#client);
2457
+ const transport = createVaultHttpTransport(this.#client);
2456
2458
  const genesisBytes = await transport.getGenesis({ repo_id: vault.vault_id });
2457
2459
  if (!genesisBytes) {
2458
2460
  throw new LocalError("the vault has no admitted genesis", "joining an invite", { code: "CHAIN_BROKEN", details: { repo_id: vault.vault_id } });
2459
2461
  }
2460
- const genesis = parseGitvaultStrict(new TextDecoder().decode(genesisBytes));
2461
- if (!verifyGitvaultObject(genesis, genesis.creator_signing_pubkey)) {
2462
- throw new LocalError("vault_genesis signature does not verify", "joining an invite", { code: "GITVAULT_SIGNATURE_INVALID", details: { repo_id: vault.vault_id } });
2462
+ const genesis = parseVaultStrict(new TextDecoder().decode(genesisBytes));
2463
+ if (!verifyVaultObject(genesis, genesis.creator_signing_pubkey)) {
2464
+ throw new LocalError("vault_genesis signature does not verify", "joining an invite", { code: "VAULT_SIGNATURE_INVALID", details: { repo_id: vault.vault_id } });
2463
2465
  }
2464
2466
  const genesisSha = sha256Hex(genesisBytes);
2465
2467
  // Write the repo file to the keystore BEFORE touching disk (design D5),
@@ -2484,18 +2486,18 @@ export class Gitvault {
2484
2486
  });
2485
2487
  const targetDir = await resolveResumeTargetDir(options.to, vault.address, vault.vault_id);
2486
2488
  options.onLine?.(`joining into ${targetDir}`);
2487
- const remoteUrl = gitvaultRemoteUrl(vault.organization_id, vault.project_id);
2488
- await cloneGitvaultRemote(remoteUrl, targetDir);
2489
+ const remoteUrl = vaultRemoteUrl(vault.organization_id, vault.project_id);
2490
+ await cloneVaultRemote(remoteUrl, targetDir);
2489
2491
  // The ROW's room key — a named room, or the project id when the mint
2490
2492
  // omitted one — is what makes `messages wait` in the joined checkout
2491
2493
  // address the right room with zero flags (design D5).
2492
2494
  const roomKey = redeem.room?.room_key ?? vault.project_id ?? "";
2493
2495
  // Local-only pins (design D5) — never a worktree file, never the global
2494
- // active project. Reuses the SAME pin-writer every other gitvault
2496
+ // active project. Reuses the SAME pin-writer every other vault
2495
2497
  // resolution path uses, this time with the invite's OWN room key.
2496
- const { pinGitvaultRepo } = await this.#address();
2498
+ const { pinVaultRepo } = await this.#address();
2497
2499
  const addressParts = vault.address ? vault.address.split("/") : null;
2498
- await pinGitvaultRepo(targetDir, vault.vault_id, addressParts && addressParts.length === 2 ? { org_slug: addressParts[0], repo_name: addressParts[1] } : undefined, { project_id: vault.project_id, org_id: vault.organization_id, room_key: roomKey });
2500
+ await pinVaultRepo(targetDir, vault.vault_id, addressParts && addressParts.length === 2 ? { org_slug: addressParts[0], repo_name: addressParts[1] } : undefined, { project_id: vault.project_id, org_id: vault.organization_id, room_key: roomKey });
2499
2501
  // design D5/D9 risk list: `.git/info/exclude` rather than `.gitignore`
2500
2502
  // — the ignore file is part of the captured tree and touching it would
2501
2503
  // break exact-state on the first `git status`. Best-effort.
@@ -2505,7 +2507,7 @@ export class Gitvault {
2505
2507
  catch {
2506
2508
  // Best-effort: an unwritable checkout still completes the join.
2507
2509
  }
2508
- // verify chain — `open()` here mainly constructs the `GitvaultVault`
2510
+ // verify chain — `open()` here mainly constructs the `Vault`
2509
2511
  // instance (its cold-open restore path no-ops the instant it sees the
2510
2512
  // repo file `saveRepo` just wrote). The chain walk this method needs
2511
2513
  // happens the FIRST time `submitWriterActivationHead` calls
@@ -2517,7 +2519,7 @@ export class Gitvault {
2517
2519
  // design D5: activate as a writer BEFORE `join()` returns, through the
2518
2520
  // SAME `add_writer_key` door `resume` drives — so the joiner's first
2519
2521
  // `git push` is an ordinary push under its OWN key, not a
2520
- // `GITVAULT_WRITER_NOT_ADMITTED` refusal. `added_writer.principal_id`
2522
+ // `VAULT_WRITER_NOT_ADMITTED` refusal. `added_writer.principal_id`
2521
2523
  // names the redeemer's own control-plane principal, which the claim
2522
2524
  // response never carries (its `membership` block names the ORG), so
2523
2525
  // resolve it fresh here.
@@ -2552,7 +2554,7 @@ export class Gitvault {
2552
2554
  writerActivation = { outcome: "pending", writer_key_id: myWriterKeyId, reason: e instanceof Error ? e.message : String(e) };
2553
2555
  }
2554
2556
  // The bearer envelope is superseded within minutes of use — run the
2555
- // same reconcile `push()` runs, best-effort (never a `join()` throw),
2557
+ // same reconcile `capture()` runs, best-effort (never a `join()` throw),
2556
2558
  // NOW that this checkout is an admitted writer and the reconcile's own
2557
2559
  // wrap step is meaningful.
2558
2560
  const reconcile = await this.#tryReconcileEnvelopeRecipients(handle.vault);
@@ -2675,7 +2677,7 @@ export class Gitvault {
2675
2677
  next_actions: nextActions,
2676
2678
  };
2677
2679
  }
2678
- /** Best-effort dual-push: catches EVERYTHING, including the lazy module import itself, so a mirror problem can never surface as a `push()` throw. */
2680
+ /** Best-effort dual-push: catches EVERYTHING, including the lazy module import itself, so a mirror problem can never surface as a `capture()` throw. */
2679
2681
  /**
2680
2682
  * `EPOCH_ROTATION_REQUIRED` (D193) is left THROWN — never swallowed into a
2681
2683
  * silent auto-rotation — because this call site cannot legally decide the
@@ -2683,7 +2685,7 @@ export class Gitvault {
2683
2685
  * a rotation attempt must be fenced against: no shipped gateway route
2684
2686
  * exposes them for `reason:"member_removed"`/`"elective_rekey"`/
2685
2687
  * `"epoch_secret_exposed"` (verified against the live gateway route
2686
- * source — see `GitvaultVault.rotateEpoch`'s own doc comment). Submitting
2688
+ * source — see `Vault.rotateEpoch`'s own doc comment). Submitting
2687
2689
  * a GUESSED pair would either fail loudly (`RECIPIENT_SET_MISMATCH`, the
2688
2690
  * honest outcome) or — worse — never be reachable at all for a fresh
2689
2691
  * counter row. Rather than let a caller decode `details.migration_required`/
@@ -2698,7 +2700,7 @@ export class Gitvault {
2698
2700
  if (!isRun402Error(e) || e.code !== "EPOCH_ROTATION_REQUIRED")
2699
2701
  return e;
2700
2702
  // Mirrors `epochRotationRequiredNextActions` in
2701
- // `../node/gitvault-deploy.ts` byte-for-byte (same three causes, same
2703
+ // `../node/vault-deploy.ts` byte-for-byte (same three causes, same
2702
2704
  // three commands) — kept as a small standalone copy rather than a
2703
2705
  // shared import so this namespace-level module (isomorphic — Deno/Bun/V8
2704
2706
  // isolates, no Node-only imports) never has to pull in the Node-only
@@ -2711,14 +2713,14 @@ export class Gitvault {
2711
2713
  nextActions.push({ action: "run402 repos access revoke-key <principal_id>", why: "an org membership removal or key revocation is outstanding for this vault; a surviving writer's push completes a membership removal automatically (reason member_removed), so this push was refused because that rotation could not run here — an owner can rotate explicitly with this command (owner + step-up)" });
2712
2714
  if (details.exposure_outstanding)
2713
2715
  nextActions.push({ action: "run402 repos access declare-exposure", why: "this vault's own epoch secret has been declared exposed (owner + step-up)" });
2714
- return new LocalError(`this vault requires a rotate_epoch admission before an ordinary push is admissible (repo_id ${repoId})`, "pushing to gitvault", { code: "EPOCH_ROTATION_REQUIRED", details, next_actions: nextActions.length > 0 ? nextActions : undefined, cause: e });
2716
+ return new LocalError(`this vault requires a rotate_epoch admission before an ordinary push is admissible (repo_id ${repoId})`, "pushing to vault", { code: "EPOCH_ROTATION_REQUIRED", details, next_actions: nextActions.length > 0 ? nextActions : undefined, cause: e });
2715
2717
  }
2716
2718
  /**
2717
2719
  * The capture-time copies a plain `git push` through the remote helper
2718
- * owes exactly as {@link push} and {@link deploy} do: the opt-in mirror
2720
+ * owes exactly as {@link capture} and {@link deploy} do: the opt-in mirror
2719
2721
  * dual-push and, on a BYO vault, the signed-chain copy into the customer
2720
- * bucket (gitvault-byo-primary-bucket task 3.3). The helper publishes
2721
- * through `GitvaultVault.push` directly, so it calls this right after a
2722
+ * bucket (vault-byo-primary-bucket task 3.3). The helper publishes
2723
+ * through `Vault.push` directly, so it calls this right after a
2722
2724
  * generation lands. Same contract as the private hooks it composes:
2723
2725
  * best-effort, NEVER throws, never alters the push already committed —
2724
2726
  * each outcome is reported on its own field (`skipped_no_mirror` costs no
@@ -2739,12 +2741,12 @@ export class Gitvault {
2739
2741
  }
2740
2742
  }
2741
2743
  /**
2742
- * gitvault-byo-primary-bucket task 3.3 — the chain's every-push dual-write
2744
+ * vault-byo-primary-bucket task 3.3 — the chain's every-push dual-write
2743
2745
  * into a BYO vault's own destination, mirroring {@link #tryMirrorPush}'s
2744
2746
  * exact contract byte-for-byte (best-effort, catches EVERYTHING, never
2745
2747
  * throws, never alters the vault outcome already committed above — a
2746
2748
  * chain-copy failure is a named pending finding reported BESIDE the vault
2747
- * result on its own field, never a `push()`/`deploy()` throw).
2749
+ * result on its own field, never a `capture()`/`deploy()` throw).
2748
2750
  */
2749
2751
  async #tryByoChainCopyPush(repoId, keystore) {
2750
2752
  try {
@@ -2755,7 +2757,7 @@ export class Gitvault {
2755
2757
  return { attempted: false, outcome: "skipped_no_mirror", error: e instanceof Error ? e.message : String(e) };
2756
2758
  }
2757
2759
  }
2758
- /** Best-effort envelope-recipient reconcile: availability and local-policy failures never surface as a `push()` throw (mirroring {@link #tryMirrorPush}), but INTEGRITY verdicts do — `RECONCILE_FATAL_CODES` propagates tampering evidence instead of demoting it to `skipped_error` (round 3 blocker 2). */
2760
+ /** Best-effort envelope-recipient reconcile: availability and local-policy failures never surface as a `capture()` throw (mirroring {@link #tryMirrorPush}), but INTEGRITY verdicts do — `RECONCILE_FATAL_CODES` propagates tampering evidence instead of demoting it to `skipped_error` (round 3 blocker 2). */
2759
2761
  async #tryReconcileEnvelopeRecipients(vault) {
2760
2762
  try {
2761
2763
  const result = await vault.reconcileEnvelopeRecipients();
@@ -2767,12 +2769,12 @@ export class Gitvault {
2767
2769
  }
2768
2770
  }
2769
2771
  /**
2770
- * gitvault-multi-writer (task 5.7) — best-effort writer-admission
2772
+ * vault-multi-writer (task 5.7) — best-effort writer-admission
2771
2773
  * reconcile, the SAME non-blocking contract as {@link
2772
2774
  * #tryReconcileEnvelopeRecipients} beside it: availability failures
2773
2775
  * (network, an older gateway missing `pending_writers`/`signing_pubkey`,
2774
- * a CAS-conflict-exhausted admission) never surface as a `push()`/
2775
- * `deploy()`/`open()` throw — `GitvaultVault.reconcileWriterAdmissions()`
2776
+ * a CAS-conflict-exhausted admission) never surface as a `capture()`/
2777
+ * `deploy()`/`open()` throw — `Vault.reconcileWriterAdmissions()`
2776
2778
  * ALREADY returns an empty result rather than throwing for the ordinary
2777
2779
  * "I am not a writer yet" case, so `skipped_error` here is reserved for
2778
2780
  * genuinely unexpected failures (a transport fault mid-loop, a thrown
@@ -2794,14 +2796,14 @@ export class Gitvault {
2794
2796
  }
2795
2797
  }
2796
2798
  /**
2797
- * A REAL preview of what {@link push} would publish
2798
- * — never publishes anything, and never allocates. `run402 gitvault
2799
- * snapshot --dry-run` and `git-remote-run402`'s `option dry-run true` are
2799
+ * A REAL preview of what {@link capture} would publish
2800
+ * — never publishes anything, and never allocates. `run402 repos
2801
+ * capture --dry-run` and `git-remote-run402`'s `option dry-run true` are
2800
2802
  * both thin adapters over this method.
2801
2803
  *
2802
2804
  * "Refusing beats fake success" (this file's own architectural law) governs
2803
2805
  * the shape of what happens when the vault does not exist yet: unlike
2804
- * {@link push}, this NEVER allocates one (push-to-create must not allocate
2806
+ * {@link capture}, this NEVER allocates one (push-to-create must not allocate
2805
2807
  * on a dry run) — it resolves READ-ONLY (`open`/`resolveOrCreateAddress`
2806
2808
  * with `allow_create: false`), and when that resolution misses, returns
2807
2809
  * `allocation_needed: true` with every sizing field `null` rather than a
@@ -2812,15 +2814,15 @@ export class Gitvault {
2812
2814
  *
2813
2815
  * Everything else is the SAME real local pipeline `push` runs — capture,
2814
2816
  * pack building, sealing/encryption — computed by
2815
- * {@link import("../node/gitvault-publication.js").GitvaultVault.planPush},
2817
+ * {@link import("../node/vault-publication.js").Vault.planPush},
2816
2818
  * which is what actually stops short of the two network mutations
2817
2819
  * (`uploadObjects`, `admitHead`). See its doc comment for what
2818
2820
  * `would_admit_generation` does and does not promise.
2819
2821
  */
2820
- async planPush(options) {
2821
- const { captureSnapshot, gitvaultCommitLine } = await this.#snapshot();
2822
+ async planCapture(options) {
2823
+ const { captureSnapshot, vaultCommitLine } = await this.#snapshot();
2822
2824
  const repoDir = options.repo_dir ?? process.cwd();
2823
- // READ-ONLY resolution — mirrors `push()`'s own dispatch on `address`,
2825
+ // READ-ONLY resolution — mirrors `capture()`'s own dispatch on `address`,
2824
2826
  // but with `allow_create: false` and no `openOrCreate` fallback: a dry
2825
2827
  // run must never mutate the control plane, and allocation is the one
2826
2828
  // push-time mutation that happens before a single byte is built.
@@ -2836,14 +2838,14 @@ export class Gitvault {
2836
2838
  handle = null; // no vault to preview a push against yet
2837
2839
  }
2838
2840
  const snapshot = await captureSnapshot({ dir: repoDir, ...(options.snapshot ?? {}) });
2839
- const line = gitvaultCommitLine(snapshot);
2841
+ const line = vaultCommitLine(snapshot);
2840
2842
  options.onCommitLine?.(line);
2841
2843
  if (!handle) {
2842
2844
  return {
2843
2845
  base_generation: null, would_admit_generation: null, would_admit_generation_decimal: null,
2844
2846
  form: null, refs: {}, head_target: null, objects: [], object_count: null,
2845
2847
  encrypted_bytes: null, raw_bytes: null,
2846
- allocation_needed: true, snapshot, gitvault_commit: snapshot.oid, gitvault_commit_line: line,
2848
+ allocation_needed: true, snapshot, vault_commit: snapshot.oid, vault_commit_line: line,
2847
2849
  };
2848
2850
  }
2849
2851
  const { deployRefTransaction } = await this.#publication();
@@ -2851,15 +2853,15 @@ export class Gitvault {
2851
2853
  const push = {
2852
2854
  transaction: deployRefTransaction(materialized.refs, snapshot.oid),
2853
2855
  head_target: snapshot.head,
2854
- protocol_refs: "allow", // same opt-in `push()` makes for the SAME move — see its doc comment.
2856
+ protocol_refs: "allow", // same opt-in `capture()` makes for the SAME move — see its doc comment.
2855
2857
  ...(options.checkpoint ? { checkpoint: true } : {}),
2856
2858
  };
2857
2859
  const plan = await handle.vault.planPush(push);
2858
- return { ...plan, allocation_needed: false, snapshot, gitvault_commit: snapshot.oid, gitvault_commit_line: line };
2860
+ return { ...plan, allocation_needed: false, snapshot, vault_commit: snapshot.oid, vault_commit_line: line };
2859
2861
  }
2860
2862
  /**
2861
2863
  * Compaction's transient-storage preflight
2862
- * (gitvault-compaction-headroom-preflight, design D1/D2).
2864
+ * (vault-compaction-headroom-preflight, design D1/D2).
2863
2865
  *
2864
2866
  * Three postures, in order of information quality:
2865
2867
  * 1. the check answers "won't fit" → typed refusal, before any upload;
@@ -2890,11 +2892,11 @@ export class Gitvault {
2890
2892
  return this.#readCompactHeadroom(await this.#resolveRepoId(options));
2891
2893
  }
2892
2894
  /**
2893
- * Open this vault's compaction headroom grant directly (gitvault-checkpoint-cadence
2895
+ * Open this vault's compaction headroom grant directly (vault-checkpoint-cadence
2894
2896
  * design D3) — `compact()` already does this internally; this standalone
2895
2897
  * entry point exists for callers that need to inspect or drive the grant
2896
2898
  * without also running a full compaction cycle (tests; a future
2897
- * operator/diagnostic surface). Throws `GITVAULT_COMPACTION_GRANT_ACTIVE`
2899
+ * operator/diagnostic surface). Throws `VAULT_COMPACTION_GRANT_ACTIVE`
2898
2900
  * (409) verbatim when another compaction already holds this project's
2899
2901
  * grant.
2900
2902
  */
@@ -2910,7 +2912,7 @@ export class Gitvault {
2910
2912
  /**
2911
2913
  * The arithmetic, with no policy: the block, or `null` when unanswerable.
2912
2914
  *
2913
- * `effectiveLimitOverride` (gitvault-checkpoint-cadence design D3): when a
2915
+ * `effectiveLimitOverride` (vault-checkpoint-cadence design D3): when a
2914
2916
  * compaction grant is active for this cycle, `compact()` passes the
2915
2917
  * grant's `effective_pool_limit_bytes` here so `ok`/`projected_transient_bytes`
2916
2918
  * reflect the RAISED limit — `pool_limit_bytes` itself always stays the
@@ -2973,8 +2975,8 @@ export class Gitvault {
2973
2975
  throw new LocalError(`compaction needs about ${mib(sourceBytes)} of transient headroom and the org's pooled storage has ${mib(Math.max(limitForMessage - poolUsed, 0))} free ` +
2974
2976
  `(${mib(poolUsed)} used of ${mib(limitForMessage)}${effectiveLimit !== undefined ? ` — includes an active compaction grant raising the ${mib(poolLimit)} tier limit` : ""}; projected ${mib(projected)}). Compaction transiently holds BOTH the new checkpoint and the ` +
2975
2977
  `not-yet-pruned history — roughly 2x source_bytes — until a prune completes. Free storage, raise the tier, or re-run with --force-headroom ` +
2976
- `(the platform's own quota enforcement stays authoritative either way).`, "preflighting gitvault compaction storage headroom", {
2977
- code: "GITVAULT_COMPACT_INSUFFICIENT_HEADROOM",
2978
+ `(the platform's own quota enforcement stays authoritative either way).`, "preflighting vault compaction storage headroom", {
2979
+ code: "VAULT_COMPACT_INSUFFICIENT_HEADROOM",
2978
2980
  details: {
2979
2981
  pool_used_bytes: poolUsed,
2980
2982
  pool_limit_bytes: poolLimit,
@@ -2987,10 +2989,10 @@ export class Gitvault {
2987
2989
  }
2988
2990
  return { ...headroom, overridden: !ok && ignore };
2989
2991
  }
2990
- /** A 409 `GITVAULT_COMPACTION_GRANT_ACTIVE` refusal — another compaction already holds this project's grant. */
2992
+ /** A 409 `VAULT_COMPACTION_GRANT_ACTIVE` refusal — another compaction already holds this project's grant. */
2991
2993
  #isCompactionGrantActive(e) {
2992
2994
  const err = e;
2993
- return Boolean(err && err.code === "GITVAULT_COMPACTION_GRANT_ACTIVE");
2995
+ return Boolean(err && err.code === "VAULT_COMPACTION_GRANT_ACTIVE");
2994
2996
  }
2995
2997
  /**
2996
2998
  * Open this vault's compaction headroom grant, shared by `compact()` and
@@ -2998,7 +3000,7 @@ export class Gitvault {
2998
3000
  * objects into the vault and both need the same single-flight-per-vault
2999
3001
  * headroom slot. Four outcomes:
3000
3002
  * - opened: the grant is returned, carrying `effective_pool_limit_bytes`.
3001
- * - 409 `GITVAULT_COMPACTION_GRANT_ACTIVE`: another maintenance op (this
3003
+ * - 409 `VAULT_COMPACTION_GRANT_ACTIVE`: another maintenance op (this
3002
3004
  * process, another process, auto-gc, or a manual `repos gc`) already
3003
3005
  * holds this project's one-at-a-time grant — refuse rather than race
3004
3006
  * it, surfaced as the identical single-flight-conflict `LocalError`
@@ -3017,7 +3019,7 @@ export class Gitvault {
3017
3019
  }
3018
3020
  catch (e) {
3019
3021
  if (this.#isCompactionGrantActive(e)) {
3020
- throw new LocalError(`another compaction is already in progress for this vault (its headroom grant expires ${e.details?.expires_at ?? "soon"}) — refusing to race it.`, context, { code: "GITVAULT_COMPACTION_IN_PROGRESS", details: { expires_at: e.details?.expires_at ?? null } });
3022
+ throw new LocalError(`another compaction is already in progress for this vault (its headroom grant expires ${e.details?.expires_at ?? "soon"}) — refusing to race it.`, context, { code: "VAULT_COMPACTION_IN_PROGRESS", details: { expires_at: e.details?.expires_at ?? null } });
3021
3023
  }
3022
3024
  // 404/absent-route or any other failure: proceed ungranted.
3023
3025
  return null;
@@ -3035,14 +3037,14 @@ export class Gitvault {
3035
3037
  */
3036
3038
  async compact(options = {}) {
3037
3039
  const handle = await this.open(options);
3038
- // gitvault-checkpoint-cadence design D3: open the compaction headroom
3040
+ // vault-checkpoint-cadence design D3: open the compaction headroom
3039
3041
  // grant BEFORE the preflight (which needs its raised limit) and before
3040
3042
  // any checkpoint is built or uploaded — same ordering rule as the
3041
3043
  // preflight itself. Outcomes are documented on
3042
- // {@link GitvaultNamespace.#openMaintenanceGrantOrConflict}.
3043
- const grant = await this.#openMaintenanceGrantOrConflict(handle, "opening the gitvault compaction headroom grant");
3044
+ // {@link VaultNamespace.#openMaintenanceGrantOrConflict}.
3045
+ const grant = await this.#openMaintenanceGrantOrConflict(handle, "opening the vault compaction headroom grant");
3044
3046
  // Everything from here on is bracketed by the grant's own lifetime —
3045
- // including the preflight's OWN possible throw (`GITVAULT_COMPACT_
3047
+ // including the preflight's OWN possible throw (`VAULT_COMPACT_
3046
3048
  // INSUFFICIENT_HEADROOM`) — so a refusal still closes a grant this call
3047
3049
  // opened rather than leaking it until the gateway's hourly sweep.
3048
3050
  try {
@@ -3056,7 +3058,7 @@ export class Gitvault {
3056
3058
  /** The rest of `compact()`, run under an already-opened-or-skipped grant — split out so the grant's `finally` above covers every exit path, including the preflight's own throw. */
3057
3059
  async #compactAfterGrant(handle, options, grant) {
3058
3060
  // BEFORE any checkpoint is built or uploaded (that ordering is the whole
3059
- // point — see GitvaultCompactHeadroom).
3061
+ // point — see VaultCompactHeadroom).
3060
3062
  const headroom = await this.#compactHeadroomPreflight(handle.repo_id, options.ignoreHeadroom === true, grant?.effective_pool_limit_bytes);
3061
3063
  const base = await handle.vault.materialize();
3062
3064
  let lease = null;
@@ -3098,7 +3100,7 @@ export class Gitvault {
3098
3100
  finally {
3099
3101
  if (lease) {
3100
3102
  await this.#client
3101
- .request(`/gitvault/v1/vaults/${encodeURIComponent(handle.repo_id)}/maintenance-leases/${encodeURIComponent(lease.maintenance_lease_id)}`, { method: "DELETE", body: { holder_token: lease.holder_token }, context: "releasing the gitvault maintenance lease" })
3103
+ .request(`/vaults/v1/${encodeURIComponent(handle.repo_id)}/maintenance-leases/${encodeURIComponent(lease.maintenance_lease_id)}`, { method: "DELETE", body: { holder_token: lease.holder_token }, context: "releasing the vault maintenance lease" })
3102
3104
  .catch(() => undefined);
3103
3105
  }
3104
3106
  // The compaction headroom grant (if one was opened) is closed by the
@@ -3132,13 +3134,13 @@ export class Gitvault {
3132
3134
  async prune(options = {}) {
3133
3135
  const pub = await this.#publication();
3134
3136
  const prune = await this.#prune();
3135
- const { isRootEligibleForRemoval, GITVAULT_RETENTION_MIN_DAYS } = pub;
3137
+ const { isRootEligibleForRemoval, VAULT_RETENTION_MIN_DAYS } = pub;
3136
3138
  const handle = await this.open(options);
3137
- // gitvault-byo-primary-bucket: prune deletion on a BYO vault is not
3139
+ // vault-byo-primary-bucket: prune deletion on a BYO vault is not
3138
3140
  // shipped (the gateway's worker deletes from run402's own storage, which
3139
3141
  // holds none of this vault's payload; client-executed deletion is the
3140
3142
  // open design item), and the gateway refuses an intent by name
3141
- // (GITVAULT_BYO_PRUNE_NOT_SUPPORTED). Say so before any planning or
3143
+ // (VAULT_BYO_PRUNE_NOT_SUPPORTED). Say so before any planning or
3142
3144
  // ceremony — a plan here would only invite a refused submit.
3143
3145
  const record = await handle.vault.transport.getVaultRecord({ repo_id: handle.repo_id });
3144
3146
  if (record.storage_profile === "byo") {
@@ -3148,7 +3150,7 @@ export class Gitvault {
3148
3150
  retained_count: 0,
3149
3151
  object_candidates: [],
3150
3152
  deferred_object_count: 0,
3151
- blocked_reason: "this vault keeps its payload in your own bucket (storage_profile byo); run402 cannot delete from a bucket it holds no credential to, and client-executed prune deletion has not shipped — the gateway refuses a prune intent on a BYO vault by name (GITVAULT_BYO_PRUNE_NOT_SUPPORTED); compaction still works and superseded history stays in your bucket",
3153
+ blocked_reason: "this vault keeps its payload in your own bucket (storage_profile byo); run402 cannot delete from a bucket it holds no credential to, and client-executed prune deletion has not shipped — the gateway refuses a prune intent on a BYO vault by name (VAULT_BYO_PRUNE_NOT_SUPPORTED); compaction still works and superseded history stays in your bucket",
3152
3154
  intent_core: null,
3153
3155
  intent_core_sha256: null,
3154
3156
  attestation: null,
@@ -3173,8 +3175,8 @@ export class Gitvault {
3173
3175
  reason: admittedAt === null
3174
3176
  ? "this client cannot resolve the drop's effective_admitted_at, which RETAINS the root — expiry is permissive by design"
3175
3177
  : eligible
3176
- ? `dropped more than ${GITVAULT_RETENTION_MIN_DAYS} days before the cutoff; removable at the next checkpoint-bearing generation, then at the next successful prune`
3177
- : `still inside the ${GITVAULT_RETENTION_MIN_DAYS}-day retention window`,
3178
+ ? `dropped more than ${VAULT_RETENTION_MIN_DAYS} days before the cutoff; removable at the next checkpoint-bearing generation, then at the next successful prune`
3179
+ : `still inside the ${VAULT_RETENTION_MIN_DAYS}-day retention window`,
3178
3180
  };
3179
3181
  });
3180
3182
  const rootView = {
@@ -3275,8 +3277,8 @@ export class Gitvault {
3275
3277
  // the SDK never signs an attestation it did not earn.
3276
3278
  retention_evolution_ok: rootsEvolution.ok && attestation.object_set_matches && attestation.ref_state_matches && attestation.retention_roots_matches,
3277
3279
  candidates_outside_roots_ok: outsideRoots,
3278
- implementation_id: prune.GITVAULT_SDK_VERIFIER_IMPLEMENTATION,
3279
- implementation_version: prune.GITVAULT_SDK_VERIFIER_VERSION,
3280
+ implementation_id: prune.VAULT_SDK_VERIFIER_IMPLEMENTATION,
3281
+ implementation_version: prune.VAULT_SDK_VERIFIER_VERSION,
3280
3282
  }, handle.vault.signer());
3281
3283
  const intent = prune.buildPruneIntent(core, [ours, options.submit.verifier_receipt], handle.vault.signer());
3282
3284
  // The submission writes ~8 KB of ceremony
@@ -3287,7 +3289,7 @@ export class Gitvault {
3287
3289
  // the SAME compaction headroom grant `compact()` uses (design D3, via
3288
3290
  // the shared `#openMaintenanceGrantOrConflict`) — opened before the
3289
3291
  // upload, closed in a `finally` regardless of outcome.
3290
- const grant = await this.#openMaintenanceGrantOrConflict(handle, "opening the gitvault compaction headroom grant for prune submission");
3292
+ const grant = await this.#openMaintenanceGrantOrConflict(handle, "opening the vault compaction headroom grant for prune submission");
3291
3293
  let stored;
3292
3294
  try {
3293
3295
  await this.#uploadVerifierReceipts(handle, pub, [ours, options.submit.verifier_receipt]);
@@ -3320,11 +3322,11 @@ export class Gitvault {
3320
3322
  }
3321
3323
  /** Upload both receipts so the gateway can claim them at the intent's fence. */
3322
3324
  async #uploadVerifierReceipts(handle, pub, receipts) {
3323
- const { storedBytes, sha256Hex } = await import("./gitvault.crypto.js");
3325
+ const { storedBytes, sha256Hex } = await import("./vault.crypto.js");
3324
3326
  const objects = receipts.map((r) => {
3325
3327
  const bytes = storedBytes(r);
3326
3328
  return {
3327
- path: pub.gitvaultPaths.verifierReceipt(r.object_id),
3329
+ path: pub.vaultPaths.verifierReceipt(r.object_id),
3328
3330
  object_kind: "verifier_receipt",
3329
3331
  object_id: r.object_id,
3330
3332
  bytes,
@@ -3363,7 +3365,7 @@ export class Gitvault {
3363
3365
  continue; // identical bytes already landed — nothing to do
3364
3366
  throw new LocalError(existing
3365
3367
  ? `verifier receipt ${o.object_id} already exists in the vault with DIFFERENT bytes than this attempt's (stored sha256 ${existingSha256}, this attempt's sha256 ${o.sha256}) — the object id is burned and cannot be reused; re-plan the prune (new core, new nonce, new r402s-verify run).`
3366
- : `verifier receipt ${o.object_id} was refused as an already-used id, but its stored bytes could not be read back to confirm they match — re-plan the prune.`, "uploading gitvault verifier receipts", { code: "GITVAULT_RECEIPT_ID_REUSED_DIFFERENT", details: { object_id: o.object_id, existing_sha256: existingSha256, this_attempt_sha256: o.sha256 } });
3368
+ : `verifier receipt ${o.object_id} was refused as an already-used id, but its stored bytes could not be read back to confirm they match — re-plan the prune.`, "uploading vault verifier receipts", { code: "VAULT_RECEIPT_ID_REUSED_DIFFERENT", details: { object_id: o.object_id, existing_sha256: existingSha256, this_attempt_sha256: o.sha256 } });
3367
3369
  }
3368
3370
  // Every reused id was confirmed identical to ours; anything NOT
3369
3371
  // reused (a genuinely new upload, or the other side of a partial
@@ -3374,7 +3376,7 @@ export class Gitvault {
3374
3376
  }
3375
3377
  /**
3376
3378
  * `VALIDATION_FAILED` with `details.reused_object_ids`
3377
- * (`services/gitvault/upload-sessions.ts`: "an object id in the manifest is
3379
+ * (`services/vault/upload-sessions.ts`: "an object id in the manifest is
3378
3380
  * already used") — object ids a prior attempt already landed. `null` for
3379
3381
  * any other failure, so the caller rethrows it untouched.
3380
3382
  */
@@ -3439,16 +3441,16 @@ export class Gitvault {
3439
3441
  * bare "verified": `chain_verified_to_generation` and
3440
3442
  * `decryptable_to_generation` are reported separately and can genuinely
3441
3443
  * differ — the incident-shape truth ("chain verified to 10, decryptable
3442
- * to 7, `GITVAULT_EPOCH_NOT_OPENABLE` at epoch 2/rotation …") is exactly
3444
+ * to 7, `VAULT_EPOCH_NOT_OPENABLE` at epoch 2/rotation …") is exactly
3443
3445
  * what this split makes representable. `refs`/`head_target`/
3444
3446
  * `pin_after.highest_materialized` all reflect `decryptable_to_generation`.
3445
3447
  *
3446
- * **gitvault-byo-primary-bucket task 3.3 (design D6).** For a
3448
+ * **vault-byo-primary-bucket task 3.3 (design D6).** For a
3447
3449
  * `storage_profile: "byo"` vault, `fsck` ALSO adjudicates the customer's
3448
3450
  * own bucket against run402's signed chain — see {@link
3449
3451
  * #checkByoPresence} for the full contract (automatic, never a flag;
3450
3452
  * fails soft with no local credentials; throws
3451
- * `GITVAULT_BYO_OBJECT_MISSING` on a confirmed absence). A managed vault
3453
+ * `VAULT_BYO_OBJECT_MISSING` on a confirmed absence). A managed vault
3452
3454
  * is byte-identical to before this task.
3453
3455
  */
3454
3456
  async fsck(options = {}) {
@@ -3457,10 +3459,10 @@ export class Gitvault {
3457
3459
  if (!repoId) {
3458
3460
  throw new LocalError(options.repo_id || options.project_id
3459
3461
  ? "no vault is allocated for this project yet — nothing to fsck"
3460
- : "pass repo_id, or project_id to resolve it from the control plane", "running gitvault fsck", { code: "GITVAULT_VAULT_UNRESOLVED", details: { project_id: options.project_id ?? null } });
3462
+ : "pass repo_id, or project_id to resolve it from the control plane", "running vault fsck", { code: "VAULT_UNRESOLVED", details: { project_id: options.project_id ?? null } });
3461
3463
  }
3462
3464
  const write = options.write ?? true;
3463
- // gitvault-agent-envelopes D5: fsck is observational — it never wraps an
3465
+ // vault-agent-envelopes D5: fsck is observational — it never wraps an
3464
3466
  // envelope, in write mode or not. Investigating a suspicious pending
3465
3467
  // recipient must not complete the disclosure being investigated.
3466
3468
  const handle = await this.open({ ...options, repo_id: repoId, reconcile: "forbidden" });
@@ -3497,7 +3499,7 @@ export class Gitvault {
3497
3499
  chain_verified_to_generation: state.generation,
3498
3500
  decryptable_to_generation: decryptableToGeneration,
3499
3501
  });
3500
- // gitvault-byo-primary-bucket task 3.3 (design D6) — LAST, deliberately:
3502
+ // vault-byo-primary-bucket task 3.3 (design D6) — LAST, deliberately:
3501
3503
  // everything above (chain verify + its pin persist, retained-refs
3502
3504
  // reconcile, open-proof submission) is real, valid work regardless of
3503
3505
  // what the customer's own bucket holds — the signed chain is run402-
@@ -3538,13 +3540,13 @@ export class Gitvault {
3538
3540
  evidence,
3539
3541
  resolvePrincipalId: async () => {
3540
3542
  const who = await this.#client.request("/agent/v1/whoami", {
3541
- context: "resolving this principal's identity for a gitvault proof-of-open submission",
3543
+ context: "resolving this principal's identity for a vault proof-of-open submission",
3542
3544
  });
3543
3545
  return who.principal?.id ?? null;
3544
3546
  },
3545
3547
  readerEntrypoint: async () => {
3546
- const { gitvaultReaderEntrypoint } = await this.#publication();
3547
- return gitvaultReaderEntrypoint("fsck");
3548
+ const { vaultReaderEntrypoint } = await this.#publication();
3549
+ return vaultReaderEntrypoint("fsck");
3548
3550
  },
3549
3551
  submit: (principalId, ekFingerprint, ev) => this.submitProofOfOpen(repoId, principalId, {
3550
3552
  ek_fingerprint: ekFingerprint,
@@ -3555,9 +3557,9 @@ export class Gitvault {
3555
3557
  });
3556
3558
  }
3557
3559
  /**
3558
- * gitvault-byo-primary-bucket task 3.3 (design D6) — `repos fsck`'s
3560
+ * vault-byo-primary-bucket task 3.3 (design D6) — `repos fsck`'s
3559
3561
  * wiring of the shipped read-half primitive
3560
- * {@link import("../node/gitvault-mirror.js").verifyByoObjectsPresent}.
3562
+ * {@link import("../node/vault-mirror.js").verifyByoObjectsPresent}.
3561
3563
  * Thin wrapper over {@link computeByoPresenceOutcome} (the testable
3562
3564
  * decision function, factored out the same way {@link
3563
3565
  * computeOpenProofOutcome} is factored out of `#submitFsckOpenProof`)
@@ -3579,23 +3581,21 @@ export class Gitvault {
3579
3581
  /**
3580
3582
  * Wrap this vault's current epoch key to every org member who has
3581
3583
  * published an encryption key but has no `key_envelope` on this vault yet
3582
- * — gitvault-human-envelopes task 4.1's ADD-path workaround. See {@link
3583
- * import("../node/gitvault-publication.js").GitvaultVault.
3584
+ * — vault-human-envelopes task 4.1's ADD-path workaround. See {@link
3585
+ * import("../node/vault-publication.js").Vault.
3584
3586
  * reconcileEnvelopeRecipients} for the full design (TOFU pinning, the
3585
3587
  * gateway `public_key` gap, and why this is a workaround rather than the
3586
3588
  * eventual epoch-rotation design).
3587
3589
  *
3588
- * `run402 gitvault reconcile` has no `repos` equivalent — `reconcile` is
3589
- * a workaround, not a permanent verb — and answers `COMMAND_REMOVED`
3590
- * pointing at `repos access` for inspection. This method itself stays:
3591
- * `deploy()` runs it, best-effort,
3590
+ * No CLI verb runs this directly — `repos access` is the inspection
3591
+ * read. `deploy()` runs it, best-effort,
3592
3592
  * whenever a deploy lands a new generation in the vault — design D5's
3593
3593
  * "deploy time" hook, "the same 'one command every agent runs' argument
3594
- * that decided deploy-implies-capture." `push()` (capture-and-publish
3594
+ * that decided deploy-implies-capture." `capture()` (capture-and-publish
3595
3595
  * outside a deploy) runs the identical hook after every successful
3596
3596
  * publish, for the vault-only-project cadence. See
3597
3597
  * `#tryReconcileEnvelopeRecipients` below for both call sites, and
3598
- * {@link Gitvault.access} for the READ half repo-surface-consolidation
3598
+ * {@link Repos.access} for the READ half repo-surface-consolidation
3599
3599
  * ships in its place.
3600
3600
  */
3601
3601
  async reconcileEnvelopeRecipients(options = {}) {
@@ -3603,12 +3603,12 @@ export class Gitvault {
3603
3603
  return handle.vault.reconcileEnvelopeRecipients();
3604
3604
  }
3605
3605
  /**
3606
- * gitvault-multi-writer (task 5.7) — admit every eligible `pending_writers[]`
3606
+ * vault-multi-writer (task 5.7) — admit every eligible `pending_writers[]`
3607
3607
  * candidate (active org membership at role developer+, a published,
3608
3608
  * possession-verified signing key, not yet in the writer set) via a fresh
3609
3609
  * `add_writer_key{"writer"}` head per candidate. This session's OWN key
3610
3610
  * must already be an active writer — see {@link
3611
- * import("../node/gitvault-publication.js").GitvaultVault.
3611
+ * import("../node/vault-publication.js").Vault.
3612
3612
  * reconcileWriterAdmissions}'s doc comment for why that is checked
3613
3613
  * locally, once, rather than surfaced as N identical gateway refusals.
3614
3614
  *
@@ -3631,7 +3631,7 @@ export class Gitvault {
3631
3631
  * `rotation_attempt_descriptor`, submit the `rotate_epoch` head, verify
3632
3632
  * this principal's own envelope opens to the committed key (when it is
3633
3633
  * itself a recipient), and advance the local keystore's epoch pointer.
3634
- * See {@link import("../node/gitvault-publication.js").GitvaultVault.
3634
+ * See {@link import("../node/vault-publication.js").Vault.
3635
3635
  * rotateEpoch}'s own doc comment for the full obligations and — load-
3636
3636
  * bearing — the confirmed gap in what the gateway exposes for
3637
3637
  * `recipient_state_version`/`recipient_revocation_version` outside the
@@ -3654,9 +3654,9 @@ export class Gitvault {
3654
3654
  */
3655
3655
  /**
3656
3656
  * The writer-capable rotation that completes an org membership removal
3657
- * (`reason:"member_removed"`, gitvault-multi-writer D6): counters come off
3657
+ * (`reason:"member_removed"`, vault-multi-writer D6): counters come off
3658
3658
  * the envelope-recipients read, no declaration, no owner step-up — any
3659
- * surviving writer can run it. `push()` runs it automatically when the
3659
+ * surviving writer can run it. `capture()` runs it automatically when the
3660
3660
  * gate names an outstanding removal; this is the explicit entry point
3661
3661
  * (`run402 orgs members rm` drives it on every vault the caller can).
3662
3662
  */
@@ -3693,19 +3693,19 @@ export class Gitvault {
3693
3693
  /**
3694
3694
  * `EPOCH_ROTATION_REQUIRED` from a `publishPinManifestUpdate` call names
3695
3695
  * the SAME three causes {@link #enrichEpochRotationRequired} decodes for
3696
- * `push()`, but the remedy is different: a manifest-only publish should
3696
+ * `capture()`, but the remedy is different: a manifest-only publish should
3697
3697
  * fold into the NEXT `rotateEpoch` call via `pending_confirmations`
3698
3698
  * rather than run a separate migration/revocation/exposure rotation
3699
3699
  * first and publish again afterward — one admission instead of two, and
3700
3700
  * the only path that works at all while EVERY predecessor-confirmed
3701
- * principal is already exhausted (see `GitvaultVault.rotateEpoch`'s own
3701
+ * principal is already exhausted (see `Vault.rotateEpoch`'s own
3702
3702
  * doc comment for the honest residual: this does not rescue a vault with
3703
3703
  * zero ever-confirmed principals, which needs an operator-side fix).
3704
3704
  */
3705
3705
  #enrichEpochRotationRequiredForPinManifest(e, repoId) {
3706
3706
  if (!isRun402Error(e) || e.code !== "EPOCH_ROTATION_REQUIRED")
3707
3707
  return e;
3708
- return new LocalError(`this vault requires a rotate_epoch admission before an ordinary pin-manifest publish is admissible (repo_id ${repoId}) — fold this SAME receipt into rotateEpoch({..., pending_confirmations: [{principal_id, ek_fingerprint, receipt}]}) instead of retrying this call`, "publishing a recipient_pin_manifest update", { code: "EPOCH_ROTATION_REQUIRED", details: e.details, next_actions: [{ action: "r.gitvault.rotateEpoch({..., pending_confirmations: [{principal_id, ek_fingerprint, receipt}]})", why: "the manifest publish rides the SAME head as the required rotation, which is EPOCH_ROTATION_REQUIRED's own escape valve — a standalone publish never is" }], cause: e });
3708
+ return new LocalError(`this vault requires a rotate_epoch admission before an ordinary pin-manifest publish is admissible (repo_id ${repoId}) — fold this SAME receipt into rotateEpoch({..., pending_confirmations: [{principal_id, ek_fingerprint, receipt}]}) instead of retrying this call`, "publishing a recipient_pin_manifest update", { code: "EPOCH_ROTATION_REQUIRED", details: e.details, next_actions: [{ action: "r.repos.rotateEpoch({..., pending_confirmations: [{principal_id, ek_fingerprint, receipt}]})", why: "the manifest publish rides the SAME head as the required rotation, which is EPOCH_ROTATION_REQUIRED's own escape valve — a standalone publish never is" }], cause: e });
3709
3709
  }
3710
3710
  /**
3711
3711
  * `repos access` (repo-surface-consolidation D5/D10) — a READ-ONLY report
@@ -3713,15 +3713,15 @@ export class Gitvault {
3713
3713
  * surface exposes today. Never wraps, never mutates a `key_envelope` —
3714
3714
  * that mutating half stays {@link reconcileEnvelopeRecipients}, reachable
3715
3715
  * only through the deploy/push best-effort hooks until `access repair`
3716
- * ships (gated on `gitvault-human-envelopes`' epoch-rotation work). See
3717
- * {@link GitvaultAccessResult}'s doc comment for the honest gap this
3716
+ * ships (gated on `vault-human-envelopes`' epoch-rotation work). See
3717
+ * {@link VaultAccessResult}'s doc comment for the honest gap this
3718
3718
  * reports rather than invents.
3719
3719
  */
3720
3720
  async access(options = {}) {
3721
3721
  const repoId = await this.#resolveRepoId(options);
3722
3722
  const record = await this.get(repoId).catch(() => null);
3723
3723
  const orgId = record?.org_id ?? null;
3724
- // gitvault-agent-envelopes D3/D5: `access` is one of the ordinary reads a
3724
+ // vault-agent-envelopes D3/D5: `access` is one of the ordinary reads a
3725
3725
  // KEY-HOLDER's session starts with — enroll this keystore's key if absent
3726
3726
  // and fulfil every pending desired recipient once per process, BEFORE the
3727
3727
  // roster below is read, so the roster reflects the fulfilment. Reported,
@@ -3731,8 +3731,8 @@ export class Gitvault {
3731
3731
  let enrollment = null;
3732
3732
  if (options.reconcile !== "forbidden") {
3733
3733
  try {
3734
- const { GitvaultKeystore } = await this.#keystore();
3735
- const probe = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
3734
+ const { VaultKeystore } = await this.#keystore();
3735
+ const probe = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
3736
3736
  if (probe.readRepo(repoId)) {
3737
3737
  const handle = await this.open({ ...options, repo_id: repoId });
3738
3738
  reconcileRecipients = handle.reconcile_recipients;
@@ -3747,10 +3747,10 @@ export class Gitvault {
3747
3747
  orgId
3748
3748
  ? this.#client.request(`/orgs/v1/${encodeURIComponent(orgId)}/encryption-keys`, { context: "reading the org encryption-key directory" })
3749
3749
  : Promise.resolve({ org_id: "", keys: [] }),
3750
- this.#client.request(`/gitvault/v1/vaults/${encodeURIComponent(repoId)}/envelope-recipients`, { context: "reading the gitvault envelope recipients" }),
3750
+ this.#client.request(`/vaults/v1/${encodeURIComponent(repoId)}/envelope-recipients`, { context: "reading the vault envelope recipients" }),
3751
3751
  ]);
3752
3752
  const covered = new Set(coverage.recipient_fingerprints);
3753
- // `desired` is OPTIONAL on the wire (see GitvaultEnvelopeRecipientsResponse):
3753
+ // `desired` is OPTIONAL on the wire (see VaultEnvelopeRecipientsResponse):
3754
3754
  // absent means an older gateway that predates this field — genuinely
3755
3755
  // unknown, not "no desired recipients." Distinguish "absent" from
3756
3756
  // "present and empty" via the array itself, not a boolean flag, so a
@@ -3770,8 +3770,8 @@ export class Gitvault {
3770
3770
  let pins = {};
3771
3771
  let ownFingerprint = null;
3772
3772
  try {
3773
- const { GitvaultKeystore } = await this.#keystore();
3774
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
3773
+ const { VaultKeystore } = await this.#keystore();
3774
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
3775
3775
  pins = keystore.readRepo(repoId)?.envelope_recipient_pins ?? {};
3776
3776
  ownFingerprint = keystore.readIdentity()?.encryption_fingerprint ?? null;
3777
3777
  }
@@ -3794,8 +3794,8 @@ export class Gitvault {
3794
3794
  const directoryFingerprints = new Set(directory.keys.map((k) => k.ek_fingerprint));
3795
3795
  // Removed members (desired status pending_removal) whose fingerprint is
3796
3796
  // STILL covered: real, continuing access that membership removal did not
3797
- // revoke, because gitvault v0 has no epoch-rotation mechanism yet. See
3798
- // GitvaultAccessResult's doc comment.
3797
+ // revoke, because vault v0 has no epoch-rotation mechanism yet. See
3798
+ // VaultAccessResult's doc comment.
3799
3799
  const staleAccess = (desiredList ?? [])
3800
3800
  .filter((d) => d.status === "pending_removal" && d.ek_fingerprint != null && covered.has(d.ek_fingerprint))
3801
3801
  .map((d) => ({ principal_id: d.principal_id, display_name: d.display_name, fingerprint: d.ek_fingerprint }));
@@ -3810,7 +3810,7 @@ export class Gitvault {
3810
3810
  // not orphaned/external, it is provably this machine, so it is broken
3811
3811
  // out into `this_keystore` instead of left to read as a misconfiguration.
3812
3812
  const unmatchedRaw = coverage.recipient_fingerprints.filter((fp) => !directoryFingerprints.has(fp) && !staleAccessFingerprints.has(fp));
3813
- // gitvault-agent-envelopes: THIS machine's keystore is reported for every
3813
+ // vault-agent-envelopes: THIS machine's keystore is reported for every
3814
3814
  // principal type — enrolled or not, covered or not — never `null` for a
3815
3815
  // real keystore (only when there is no local identity at all). The
3816
3816
  // directory now lists agent keys too, so "own fingerprint in the
@@ -3837,7 +3837,7 @@ export class Gitvault {
3837
3837
  ...(!covered.has(ownFingerprint) && publishState === "active"
3838
3838
  ? { next_actions: [
3839
3839
  { action: "run402 repos access", why: "poll — covered_on_this_vault flips true once a key-holder has wrapped this vault to your key" },
3840
- { action: "ask a key-holder to run any gitvault operation (run402 repos view / git push)", why: "a key-holding client wraps every pending desired recipient on its next operation" },
3840
+ { action: "ask a key-holder to run any vault operation (run402 repos view / git push)", why: "a key-holding client wraps every pending desired recipient on its next operation" },
3841
3841
  ] }
3842
3842
  : {}),
3843
3843
  ...(publishState === "rotation_required"
@@ -3856,7 +3856,7 @@ export class Gitvault {
3856
3856
  "covered:true they still decrypt this vault until an owner runs `repos access repair` (or, for a targeted key, `repos access " +
3857
3857
  "revoke-key`); see stale_access for exactly who, and next_actions for the exact command."
3858
3858
  : "the gateway did not report desired-recipient state (desired[]) for this vault_id — likely an older gateway than this SDK " +
3859
- "expects, so per-recipient envelope_state and stale_access are unavailable. history_scope is unavailable regardless: gitvault " +
3859
+ "expects, so per-recipient envelope_state and stale_access are unavailable. history_scope is unavailable regardless: vault " +
3860
3860
  "protocol v0 pins a single fixed epoch, so there is no per-epoch scope to report. This reports what the read surface has today: " +
3861
3861
  "the org's directory of encryption-key-holding members, which of the vault's current envelope-recipient fingerprints match a " +
3862
3862
  "directory entry (covered), and this machine's own local TOFU pin per principal when it has ever wrapped one (tofu_pin) — never a server-side fact.";
@@ -3895,31 +3895,31 @@ export class Gitvault {
3895
3895
  * `run402 deploy` is design D5's PRIMARY envelope-recipient reconcile hook
3896
3896
  * ("the same 'one command every agent runs' argument that decided
3897
3897
  * deploy-implies-capture") and design D6's primary dual-push mirror trigger
3898
- * — both fire HERE, not inside {@link runGitvaultDeploy} itself, mirroring
3899
- * {@link push}'s exact non-blocking contract: best-effort, NEVER throw,
3898
+ * — both fire HERE, not inside {@link runVaultDeploy} itself, mirroring
3899
+ * {@link capture}'s exact non-blocking contract: best-effort, NEVER throw,
3900
3900
  * NEVER alter the deploy outcome already resolved above, reported BESIDE it
3901
3901
  * on `mirror_push` / `reconcile_recipients`. They fire only when this
3902
3902
  * deploy actually landed a new generation in the vault
3903
3903
  * (`DEPLOYED_AND_VAULTED` / `DEPLOY_FAILED_VAULTED` — the outcomes carrying
3904
3904
  * a `generation`); the other three outcomes published nothing new, so
3905
3905
  * there is nothing to mirror or reconcile against ({@link
3906
- * import("../node/gitvault-mirror.js").mirrorPushForGeneration}'s own
3906
+ * import("../node/vault-mirror.js").mirrorPushForGeneration}'s own
3907
3907
  * contract: "fires after an ordinary vault push/deploy produces a new
3908
3908
  * generation"). Both fields are therefore OMITTED — never a faked
3909
3909
  * `skipped_*` outcome — when no generation landed.
3910
3910
  */
3911
3911
  async deploy(options) {
3912
- const { runGitvaultDeploy } = await this.#deploy();
3912
+ const { runVaultDeploy } = await this.#deploy();
3913
3913
  const handle = await this.open(options);
3914
- const result = await runGitvaultDeploy({ ...options, vault: handle.vault, repo_dir: options.repo_dir ?? process.cwd() });
3915
- // Same ordering push() uses (mirror, then reconcile) — sequential, not
3914
+ const result = await runVaultDeploy({ ...options, vault: handle.vault, repo_dir: options.repo_dir ?? process.cwd() });
3915
+ // Same ordering capture() uses (mirror, then reconcile) — sequential, not
3916
3916
  // Promise.all, so a reconcile failure can never be misread as a mirror
3917
3917
  // failure in a log line that assumed ordering. Extracted to a standalone
3918
3918
  // function so the outcome-gating is unit-testable with fake thunks,
3919
- // without standing up a live vault — see gitvault-deploy-hooks.test.ts.
3920
- const hooked = await attachGitvaultDeployHooks(result, () => this.#tryMirrorPush(handle.repo_id, handle.keystore), () => this.#tryReconcileEnvelopeRecipients(handle.vault));
3921
- // gitvault-byo-primary-bucket task 3.3 / gitvault-multi-writer task 5.7
3922
- // — composed AFTER, not inside, `attachGitvaultDeployHooks` (kept
3919
+ // without standing up a live vault — see repos-deploy-hooks.test.ts.
3920
+ const hooked = await attachVaultDeployHooks(result, () => this.#tryMirrorPush(handle.repo_id, handle.keystore), () => this.#tryReconcileEnvelopeRecipients(handle.vault));
3921
+ // vault-byo-primary-bucket task 3.3 / vault-multi-writer task 5.7
3922
+ // — composed AFTER, not inside, `attachVaultDeployHooks` (kept
3923
3923
  // untouched so its own unit-tested outcome-gating contract stays
3924
3924
  // byte-for-byte): the SAME "did this deploy actually land a generation"
3925
3925
  // gate `mirror_push`'s presence already encodes, so no new
@@ -3948,14 +3948,14 @@ export class Gitvault {
3948
3948
  const out = await handle.vault.restoreObjectsInto(options.target_dir);
3949
3949
  return { refs: out.refs, generation: out.generation, retained_refs: out.retained_refs };
3950
3950
  }
3951
- // ── degraded read (gitvault-byo-primary-bucket, design D4, task 3.4 — mirror half) ──
3951
+ // ── degraded read (vault-byo-primary-bucket, design D4, task 3.4 — mirror half) ──
3952
3952
  /**
3953
3953
  * Wrap an ALREADY-RESOLVED vault read with degraded-read fallback: run
3954
3954
  * `options.attemptLive` (the caller's own live call — its
3955
3955
  * `vault.materialize()` for a `list`-shaped read, or
3956
3956
  * `vault.restoreObjectsInto(dir)` for a `fetch`-shaped one), and on a
3957
3957
  * network-class failure (never on an authorization refusal or any other
3958
- * 4xx — see `isNetworkClassGitvaultReadError`), fall back to the vault's
3958
+ * 4xx — see `isNetworkClassVaultReadError`), fall back to the vault's
3959
3959
  * configured mirror via the SAME `r402s-recover` engine `recover()` uses.
3960
3960
  *
3961
3961
  * Deliberately takes an already-open `vault`/`keystore`/`repo_id` rather
@@ -3974,17 +3974,17 @@ export class Gitvault {
3974
3974
  * entirely: the original gateway error surfaces exactly as it always did.
3975
3975
  */
3976
3976
  async withDegradedRead(options) {
3977
- const { tryGitvaultDegradedRead } = await this.#degradedRead();
3978
- return tryGitvaultDegradedRead(options);
3977
+ const { tryVaultDegradedRead } = await this.#degradedRead();
3978
+ return tryVaultDegradedRead(options);
3979
3979
  }
3980
3980
  /**
3981
- * gitvault-byo-primary-bucket (design D4): the degraded read for the OPEN
3981
+ * vault-byo-primary-bucket (design D4): the degraded read for the OPEN
3982
3982
  * itself. {@link withDegradedRead} wraps a handle's live read, but a plain
3983
3983
  * `git fetch`/`clone` needs the gateway once BEFORE any read — to open the
3984
3984
  * handle (enrollment, the vault record). When that open fails
3985
3985
  * network-class and this checkout already knows the vault — a pinned
3986
3986
  * `repo_id`, or the keystore's own project→repo file for an id-form
3987
- * address (gitvault-offline-clone-resolve) — the whole read is served from
3987
+ * address (vault-offline-clone-resolve) — the whole read is served from
3988
3988
  * the vault's BYO destination or configured mirror, exactly as
3989
3989
  * `withDegradedRead` would have after a failed live read. `null` when this
3990
3990
  * cannot help (a non-network failure, no local identity for the vault, no
@@ -3992,13 +3992,13 @@ export class Gitvault {
3992
3992
  * Writes are never rerouted.
3993
3993
  */
3994
3994
  async degradedOpenFallback(input) {
3995
- const [{ isNetworkClassGitvaultReadError, tryGitvaultDegradedRead }, { GitvaultKeystore }, { readPinnedGitvaultRepo, resolveGitvaultAddress }, { createGitvaultHttpTransport }] = await Promise.all([this.#degradedRead(), this.#keystore(), this.#address(), this.#publication()]);
3996
- if (!isNetworkClassGitvaultReadError(input.error))
3995
+ const [{ isNetworkClassVaultReadError, tryVaultDegradedRead }, { VaultKeystore }, { readPinnedVaultRepo, resolveVaultAddress }, { createVaultHttpTransport }] = await Promise.all([this.#degradedRead(), this.#keystore(), this.#address(), this.#publication()]);
3996
+ if (!isNetworkClassVaultReadError(input.error))
3997
3997
  return null;
3998
- const keystore = new GitvaultKeystore({});
3998
+ const keystore = new VaultKeystore({});
3999
3999
  let repoId = input.repo_id ?? null;
4000
4000
  if (!repoId) {
4001
- const pinned = await readPinnedGitvaultRepo(input.repo_dir).catch(() => null);
4001
+ const pinned = await readPinnedVaultRepo(input.repo_dir).catch(() => null);
4002
4002
  repoId = pinned?.repo_id ?? null;
4003
4003
  }
4004
4004
  if (!repoId && input.address) {
@@ -4007,7 +4007,7 @@ export class Gitvault {
4007
4007
  // here for the same reason the open did, and that is the answer: no
4008
4008
  // local identity, nothing to serve from.
4009
4009
  try {
4010
- const resolution = await resolveGitvaultAddress({ keystore, transport: createGitvaultHttpTransport(this.#client), address: input.address, repo_dir: input.repo_dir, allow_create: false });
4010
+ const resolution = await resolveVaultAddress({ keystore, transport: createVaultHttpTransport(this.#client), address: input.address, repo_dir: input.repo_dir, allow_create: false });
4011
4011
  if (resolution.offline)
4012
4012
  repoId = resolution.repo_id;
4013
4013
  }
@@ -4018,13 +4018,13 @@ export class Gitvault {
4018
4018
  if (!repoId)
4019
4019
  return null;
4020
4020
  try {
4021
- return await tryGitvaultDegradedRead({ attemptLive: () => Promise.reject(input.error), keystore, repo_id: repoId, out_dir: input.repo_dir });
4021
+ return await tryVaultDegradedRead({ attemptLive: () => Promise.reject(input.error), keystore, repo_id: repoId, out_dir: input.repo_dir });
4022
4022
  }
4023
4023
  catch {
4024
4024
  return null;
4025
4025
  }
4026
4026
  }
4027
- // ── mirror (gitvault-mirror-and-recover, design D1/D2/D7) ─────────────────
4027
+ // ── mirror (vault-mirror-and-recover, design D1/D2/D7) ─────────────────
4028
4028
  /**
4029
4029
  * Configure (or replace) the customer-owned mirror destination for one
4030
4030
  * vault. Client-side ONLY — the destination + credential NAME are written
@@ -4033,17 +4033,17 @@ export class Gitvault {
4033
4033
  * filesystem path needs none.
4034
4034
  */
4035
4035
  async mirrorSet(options) {
4036
- const [{ GitvaultKeystore }, { parseMirrorDestinationUrl, saveMirrorConfig }] = await Promise.all([this.#keystore(), this.#mirrorConfig()]);
4036
+ const [{ VaultKeystore }, { parseMirrorDestinationUrl, saveMirrorConfig }] = await Promise.all([this.#keystore(), this.#mirrorConfig()]);
4037
4037
  const repoId = await this.#resolveRepoId(options);
4038
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4038
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4039
4039
  const destination = parseMirrorDestinationUrl(options.destination_url, { region: options.region, endpoint: options.endpoint });
4040
4040
  return saveMirrorConfig(keystore, { repo_id: repoId, destination, ...(options.credential ? { credential: options.credential } : {}) });
4041
4041
  }
4042
4042
  /** Remove the mirror config for one vault. Never touches the mirror's own bytes (design: config removal ≠ data deletion). */
4043
4043
  async mirrorRemove(options = {}) {
4044
- const [{ GitvaultKeystore }, { removeMirrorConfig }] = await Promise.all([this.#keystore(), this.#mirrorConfig()]);
4044
+ const [{ VaultKeystore }, { removeMirrorConfig }] = await Promise.all([this.#keystore(), this.#mirrorConfig()]);
4045
4045
  const repoId = await this.#resolveRepoId(options);
4046
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4046
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4047
4047
  return { repo_id: repoId, ...removeMirrorConfig(keystore, repoId) };
4048
4048
  }
4049
4049
  /**
@@ -4054,31 +4054,31 @@ export class Gitvault {
4054
4054
  * command. Both honesty statements (design D8) ride every response.
4055
4055
  */
4056
4056
  async mirrorStatus(options = {}) {
4057
- const [{ GitvaultKeystore }, { readMirrorConfig, formatMirrorDestination }, { openGitvaultMirrorBackend }, { verifyGitvaultMirror }] = await Promise.all([
4057
+ const [{ VaultKeystore }, { readMirrorConfig, formatMirrorDestination }, { openVaultMirrorBackend }, { verifyVaultMirror }] = await Promise.all([
4058
4058
  this.#keystore(), this.#mirrorConfig(), this.#mirrorBackend(), this.#recovery(),
4059
4059
  ]);
4060
4060
  const repoId = await this.#resolveRepoId(options);
4061
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4061
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4062
4062
  const config = readMirrorConfig(keystore, repoId);
4063
- const base = { repo_id: repoId, validity_not_freshness: GITVAULT_MIRROR_VALIDITY_NOT_FRESHNESS_STATEMENT, keystore_still_required: GITVAULT_MIRROR_KEYSTORE_STILL_REQUIRED_STATEMENT };
4063
+ const base = { repo_id: repoId, validity_not_freshness: VAULT_MIRROR_VALIDITY_NOT_FRESHNESS_STATEMENT, keystore_still_required: VAULT_MIRROR_KEYSTORE_STILL_REQUIRED_STATEMENT };
4064
4064
  const lastSuccessAt = config?.last_success_at ?? null;
4065
4065
  if (!config) {
4066
- // gitvault-mirror-default: the unconfigured branch stays gateway-blind
4066
+ // vault-mirror-default: the unconfigured branch stays gateway-blind
4067
4067
  // by construction — it returns before ANY network call, finding included.
4068
- // `options.is_byo` is a caller-supplied hint (gitvault-byo-primary-bucket
4068
+ // `options.is_byo` is a caller-supplied hint (vault-byo-primary-bucket
4069
4069
  // task 3.5) — NEVER derived here, which is what keeps this branch
4070
4070
  // network-call-free; `repos view` already has `storage_profile` from
4071
4071
  // its own `status()` read and passes it in.
4072
4072
  return {
4073
4073
  ...base, configured: false, destination: null, credential_kind: null, mirrored_generation: null, newest_generation: null, is_current: null, closing_command: null,
4074
4074
  last_success_at: lastSuccessAt,
4075
- finding: gitvaultUnmirroredFinding({ configured: false, last_success_at: lastSuccessAt, mirrored_generation: null, is_byo: options.is_byo }),
4075
+ finding: vaultUnmirroredFinding({ configured: false, last_success_at: lastSuccessAt, mirrored_generation: null, is_byo: options.is_byo }),
4076
4076
  };
4077
4077
  }
4078
4078
  let mirroredGeneration = null;
4079
4079
  try {
4080
- const backend = openGitvaultMirrorBackend(config.destination, repoId, config.credential);
4081
- const report = await verifyGitvaultMirror(backend, { keystore });
4080
+ const backend = openVaultMirrorBackend(config.destination, repoId, config.credential);
4081
+ const report = await verifyVaultMirror(backend, { keystore });
4082
4082
  mirroredGeneration = report.recovered_generation;
4083
4083
  }
4084
4084
  catch {
@@ -4097,28 +4097,28 @@ export class Gitvault {
4097
4097
  mirrored_generation: mirroredGeneration, newest_generation: newestGeneration, is_current: isCurrent,
4098
4098
  closing_command: isCurrent === false ? "run402 repos mirror --backfill" : null,
4099
4099
  last_success_at: lastSuccessAt,
4100
- finding: gitvaultUnmirroredFinding({ configured: true, last_success_at: lastSuccessAt, mirrored_generation: mirroredGeneration, is_byo: options.is_byo }),
4100
+ finding: vaultUnmirroredFinding({ configured: true, last_success_at: lastSuccessAt, mirrored_generation: mirroredGeneration, is_byo: options.is_byo }),
4101
4101
  };
4102
4102
  }
4103
4103
  /** List the vault's stored objects, diff against the mirror, fetch + hash-verify + write what's missing, in admission order. Resumable and idempotent. */
4104
4104
  async mirrorSync(options = {}) {
4105
- const [{ GitvaultKeystore }, { mirrorSync }] = await Promise.all([this.#keystore(), this.#mirror()]);
4105
+ const [{ VaultKeystore }, { mirrorSync }] = await Promise.all([this.#keystore(), this.#mirror()]);
4106
4106
  const repoId = await this.#resolveRepoId(options);
4107
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4107
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4108
4108
  return mirrorSync(this.#client, repoId, { keystore });
4109
4109
  }
4110
4110
  /** Keyless integrity probe against the CONFIGURED mirror: discovery + chain verification + closure/absence adjudication, never decryption (`run402 repos fsck --mirror`). */
4111
4111
  async mirrorVerify(options = {}) {
4112
- const [{ GitvaultKeystore }, { readMirrorConfig }, { openGitvaultMirrorBackend }, { verifyGitvaultMirror }] = await Promise.all([
4112
+ const [{ VaultKeystore }, { readMirrorConfig }, { openVaultMirrorBackend }, { verifyVaultMirror }] = await Promise.all([
4113
4113
  this.#keystore(), this.#mirrorConfig(), this.#mirrorBackend(), this.#recovery(),
4114
4114
  ]);
4115
4115
  const repoId = await this.#resolveRepoId(options);
4116
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4116
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4117
4117
  const config = readMirrorConfig(keystore, repoId);
4118
4118
  if (!config)
4119
- throw new LocalError(`no mirror is configured for ${repoId}`, "verifying gitvault mirror", { code: "GITVAULT_MIRROR_NOT_CONFIGURED", details: { repo_id: repoId }, next_actions: [{ action: "run402 repos mirror <destination>" }] });
4120
- const backend = openGitvaultMirrorBackend(config.destination, repoId, config.credential);
4121
- return verifyGitvaultMirror(backend, { keystore });
4119
+ throw new LocalError(`no mirror is configured for ${repoId}`, "verifying vault mirror", { code: "VAULT_MIRROR_NOT_CONFIGURED", details: { repo_id: repoId }, next_actions: [{ action: "run402 repos mirror <destination>" }] });
4120
+ const backend = openVaultMirrorBackend(config.destination, repoId, config.credential);
4121
+ return verifyVaultMirror(backend, { keystore });
4122
4122
  }
4123
4123
  /**
4124
4124
  * `r402s-recover` (design D4): rebuild a working git repository straight
@@ -4127,7 +4127,7 @@ export class Gitvault {
4127
4127
  * than one mirrored vault, pass `repo_id` explicitly. Recovery proves
4128
4128
  * validity, never freshness (both honesty statements ride every result).
4129
4129
  *
4130
- * gitvault-recovery-custody: a human member with no keystore recovers with
4130
+ * vault-recovery-custody: a human member with no keystore recovers with
4131
4131
  * `member_bundle` (the exported `r402s-member-recovery-bundle/v1`, or the
4132
4132
  * mirror's own `member-recovery-bundles/` sidecar when omitted) +
4133
4133
  * `source_recovery_code`; a raw WebAuthn PRF output is NOT a supported
@@ -4135,22 +4135,22 @@ export class Gitvault {
4135
4135
  * pass `recovery_receipt` when there is no keystore holding one.
4136
4136
  */
4137
4137
  async recover(options) {
4138
- const [{ GitvaultKeystore }, { parseMirrorDestinationUrl }, { openGitvaultMirrorBackend, discoverMirroredRepoIds }, { recoverGitvaultMirror }] = await Promise.all([
4138
+ const [{ VaultKeystore }, { parseMirrorDestinationUrl }, { openVaultMirrorBackend, discoverMirroredRepoIds }, { recoverVaultMirror }] = await Promise.all([
4139
4139
  this.#keystore(), this.#mirrorConfig(), this.#mirrorBackend(), this.#recovery(),
4140
4140
  ]);
4141
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4141
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4142
4142
  const destination = parseMirrorDestinationUrl(options.source, { region: options.region, endpoint: options.endpoint });
4143
4143
  let repoId = options.repo_id;
4144
4144
  if (!repoId) {
4145
4145
  const found = await discoverMirroredRepoIds(destination, options.credential);
4146
4146
  if (found.length === 0)
4147
- throw new LocalError(`${options.source} holds no mirrored vault (no source/<repo_id>/ prefix found)`, "recovering gitvault vault", { code: "GITVAULT_MIRROR_EMPTY", details: { source: options.source } });
4147
+ throw new LocalError(`${options.source} holds no mirrored vault (no source/<repo_id>/ prefix found)`, "recovering vault", { code: "VAULT_MIRROR_EMPTY", details: { source: options.source } });
4148
4148
  if (found.length > 1)
4149
- throw new LocalError(`${options.source} holds ${found.length} mirrored vaults; pass repo_id to pick one`, "recovering gitvault vault", { code: "GITVAULT_MIRROR_AMBIGUOUS", details: { source: options.source, repo_ids: found }, next_actions: found.map((id) => ({ action: `recover --repo ${id}` })) });
4149
+ throw new LocalError(`${options.source} holds ${found.length} mirrored vaults; pass repo_id to pick one`, "recovering vault", { code: "VAULT_MIRROR_AMBIGUOUS", details: { source: options.source, repo_ids: found }, next_actions: found.map((id) => ({ action: `recover --repo ${id}` })) });
4150
4150
  repoId = found[0];
4151
4151
  }
4152
- const backend = openGitvaultMirrorBackend(destination, repoId, options.credential);
4153
- return recoverGitvaultMirror({
4152
+ const backend = openVaultMirrorBackend(destination, repoId, options.credential);
4153
+ return recoverVaultMirror({
4154
4154
  backend, out_dir: options.out_dir, keystore,
4155
4155
  ...(options.recovery_receipt ? { recovery_receipt: options.recovery_receipt } : {}),
4156
4156
  ...(options.member_bundle ? { member_bundle: options.member_bundle } : {}),
@@ -4167,9 +4167,9 @@ export class Gitvault {
4167
4167
  * with no cache directory at all (a no-op).
4168
4168
  */
4169
4169
  async sweepObjectCache(options) {
4170
- const [{ GitvaultKeystore }] = await Promise.all([this.#keystore()]);
4170
+ const [{ VaultKeystore }] = await Promise.all([this.#keystore()]);
4171
4171
  const repoId = await this.#resolveRepoId(options);
4172
- const keystore = new GitvaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4172
+ const keystore = new VaultKeystore(options.keystore_root !== undefined ? { rootDir: options.keystore_root } : {});
4173
4173
  keystore.sweepObjectCache(repoId);
4174
4174
  }
4175
4175
  // ── internals ─────────────────────────────────────────────────────────────
@@ -4178,90 +4178,90 @@ export class Gitvault {
4178
4178
  return options.repo_id;
4179
4179
  if (options.project_id)
4180
4180
  return (await this.forProject(options.project_id)).repo_id;
4181
- throw new LocalError("pass repo_id, or project_id to resolve it from the control plane", "opening the gitvault", { code: "GITVAULT_VAULT_UNRESOLVED" });
4181
+ throw new LocalError("pass repo_id, or project_id to resolve it from the control plane", "opening the vault", { code: "VAULT_UNRESOLVED" });
4182
4182
  }
4183
4183
  #publication() {
4184
- return nodeOnly(() => import("../node/gitvault-publication.js"), "open");
4184
+ return nodeOnly(() => import("../node/vault-publication.js"), "open");
4185
4185
  }
4186
4186
  #deploy() {
4187
- return nodeOnly(() => import("../node/gitvault-deploy.js"), "deploy");
4187
+ return nodeOnly(() => import("../node/vault-deploy.js"), "deploy");
4188
4188
  }
4189
4189
  #keystore() {
4190
- return nodeOnly(() => import("../node/gitvault-keystore.js"), "open");
4190
+ return nodeOnly(() => import("../node/vault-keystore.js"), "open");
4191
4191
  }
4192
4192
  #creation() {
4193
- return nodeOnly(() => import("../node/gitvault-creation-journal.js"), "init");
4193
+ return nodeOnly(() => import("../node/vault-creation-journal.js"), "init");
4194
4194
  }
4195
4195
  #snapshot() {
4196
- return nodeOnly(() => import("../node/gitvault-snapshot.js"), "push");
4196
+ return nodeOnly(() => import("../node/vault-snapshot.js"), "push");
4197
4197
  }
4198
4198
  #prune() {
4199
- return nodeOnly(() => import("../node/gitvault-prune.js"), "prune");
4199
+ return nodeOnly(() => import("../node/vault-prune.js"), "prune");
4200
4200
  }
4201
4201
  #openOrCreate() {
4202
- return nodeOnly(() => import("../node/gitvault-open-or-create.js"), "openOrCreate");
4202
+ return nodeOnly(() => import("../node/vault-open-or-create.js"), "openOrCreate");
4203
4203
  }
4204
4204
  #address() {
4205
- return nodeOnly(() => import("../node/gitvault-address.js"), "resolveOrCreateAddress");
4205
+ return nodeOnly(() => import("../node/vault-address.js"), "resolveOrCreateAddress");
4206
4206
  }
4207
4207
  #mirror() {
4208
- return nodeOnly(() => import("../node/gitvault-mirror.js"), "mirrorSync");
4208
+ return nodeOnly(() => import("../node/vault-mirror.js"), "mirrorSync");
4209
4209
  }
4210
4210
  #mirrorConfig() {
4211
- return nodeOnly(() => import("../node/gitvault-mirror-config.js"), "mirrorSet");
4211
+ return nodeOnly(() => import("../node/vault-mirror-config.js"), "mirrorSet");
4212
4212
  }
4213
4213
  #mirrorBackend() {
4214
- return nodeOnly(() => import("../node/gitvault-mirror-backend.js"), "mirrorSet");
4214
+ return nodeOnly(() => import("../node/vault-mirror-backend.js"), "mirrorSet");
4215
4215
  }
4216
4216
  #recovery() {
4217
- return nodeOnly(() => import("../node/gitvault-recover.js"), "recover");
4217
+ return nodeOnly(() => import("../node/vault-recover.js"), "recover");
4218
4218
  }
4219
4219
  #handoff() {
4220
- return nodeOnly(() => import("../node/gitvault-handoff.js"), "handoff");
4220
+ return nodeOnly(() => import("../node/vault-handoff.js"), "handoff");
4221
4221
  }
4222
4222
  #writerState() {
4223
- return nodeOnly(() => import("../node/gitvault-writer-state.js"), "handoff");
4223
+ return nodeOnly(() => import("../node/vault-writer-state.js"), "handoff");
4224
4224
  }
4225
4225
  #restore() {
4226
- return nodeOnly(() => import("../node/gitvault-restore.js"), "resume");
4226
+ return nodeOnly(() => import("../node/vault-restore.js"), "resume");
4227
4227
  }
4228
4228
  #degradedRead() {
4229
- return nodeOnly(() => import("../node/gitvault-degraded-read.js"), "list");
4229
+ return nodeOnly(() => import("../node/vault-degraded-read.js"), "list");
4230
4230
  }
4231
4231
  #byoConfig() {
4232
- return nodeOnly(() => import("../node/gitvault-byo-config.js"), "init");
4232
+ return nodeOnly(() => import("../node/vault-byo-config.js"), "init");
4233
4233
  }
4234
4234
  /**
4235
- * gitvault-byo-primary-bucket: the transport's `byoBackend` option — where
4235
+ * vault-byo-primary-bucket: the transport's `byoBackend` option — where
4236
4236
  * THIS machine reads a BYO vault's payload from (its `byo/<repo_id>.json`
4237
4237
  * config; destination + credential NAME). One backend per vault per
4238
4238
  * transport; `null` for a vault this machine has no config for, so the
4239
- * transport refuses `GITVAULT_BYO_NOT_CONFIGURED` by name rather than
4239
+ * transport refuses `VAULT_BYO_NOT_CONFIGURED` by name rather than
4240
4240
  * reporting a false absence. Managed vaults never reach it.
4241
4241
  */
4242
4242
  async #byoBackendResolver(keystore) {
4243
- const [{ readByoConfig }, { openGitvaultDestinationBackend }] = await Promise.all([this.#byoConfig(), this.#mirrorBackend()]);
4243
+ const [{ readByoConfig }, { openVaultDestinationBackend }] = await Promise.all([this.#byoConfig(), this.#mirrorBackend()]);
4244
4244
  const cache = new Map();
4245
4245
  return (repoId) => {
4246
4246
  if (!cache.has(repoId)) {
4247
4247
  // The RAW destination backend, keyed by the gateway's full
4248
4248
  // `source/<repo_id>/…` key — the same pairing the write path uses
4249
- // (`openGitvaultDestinationBackend` + the session's `key`). The
4249
+ // (`openVaultDestinationBackend` + the session's `key`). The
4250
4250
  // repo-scoped backend the mirror engine opens would prefix
4251
4251
  // `source/<repo_id>/` a second time.
4252
4252
  const config = readByoConfig(keystore, repoId);
4253
- cache.set(repoId, config ? openGitvaultDestinationBackend(config.destination, config.credential) : null);
4253
+ cache.set(repoId, config ? openVaultDestinationBackend(config.destination, config.credential) : null);
4254
4254
  }
4255
4255
  return cache.get(repoId);
4256
4256
  };
4257
4257
  }
4258
4258
  #byoProbe() {
4259
- return nodeOnly(() => import("../node/gitvault-byo-probe.js"), "init");
4259
+ return nodeOnly(() => import("../node/vault-byo-probe.js"), "init");
4260
4260
  }
4261
4261
  }
4262
4262
  // ─── D7 — progressive terminal-loss warning (repo-first-onramp task 2.7) ────
4263
4263
  //
4264
- // The §0 terminal-loss statement (`GITVAULT_TERMINAL_LOSS_STATEMENT`) never
4264
+ // The §0 terminal-loss statement (`VAULT_TERMINAL_LOSS_STATEMENT`) never
4265
4265
  // changes — this governs only PROMINENCE and CADENCE. A quiet stderr line
4266
4266
  // already runs at genesis (the one-shot receipt path in `push`/`openOrCreate`
4267
4267
  // callers). This is the OTHER half: once the vault has accrued enough value
@@ -4274,17 +4274,17 @@ export class Gitvault {
4274
4274
  * (an agent that pads one dimension to stay under a lone threshold). Shipped
4275
4275
  * as defaults; tunable in this ONE place, not a protocol contract.
4276
4276
  */
4277
- export const GITVAULT_LOSS_WARNING_THRESHOLDS = {
4277
+ export const VAULT_LOSS_WARNING_THRESHOLDS = {
4278
4278
  generations: 10,
4279
4279
  source_bytes: 10 * 1024 * 1024,
4280
4280
  days_since_genesis: 14,
4281
4281
  };
4282
4282
  /**
4283
- * gitvault-clone-scaling (bench P3): generations-since-checkpoint at or
4283
+ * vault-clone-scaling (bench P3): generations-since-checkpoint at or
4284
4284
  * above this advises `run402 repos gc`. Same one-place-to-tune convention
4285
- * as {@link GITVAULT_LOSS_WARNING_THRESHOLDS}; an advisory, never a gate.
4285
+ * as {@link VAULT_LOSS_WARNING_THRESHOLDS}; an advisory, never a gate.
4286
4286
  */
4287
- export const GITVAULT_CHECKPOINT_ADVISORY_GENERATIONS = 25;
4287
+ export const VAULT_CHECKPOINT_ADVISORY_GENERATIONS = 25;
4288
4288
  /**
4289
4289
  * Pure staleness computation over two 16-hex generations. TOTAL: garbage
4290
4290
  * or unknown coverage (`null`) yields `{0, advised: false}` — advisory
@@ -4294,7 +4294,7 @@ export const GITVAULT_CHECKPOINT_ADVISORY_GENERATIONS = 25;
4294
4294
  * `checkpoint_covers_through` doc), which is deliberately indistinguishable
4295
4295
  * from fresh here.
4296
4296
  */
4297
- export function gitvaultCheckpointStaleness(input) {
4297
+ export function vaultCheckpointStaleness(input) {
4298
4298
  try {
4299
4299
  if (input.covers_through_generation === null)
4300
4300
  return { generations_since_checkpoint: 0, advised: false };
@@ -4304,7 +4304,7 @@ export function gitvaultCheckpointStaleness(input) {
4304
4304
  const newest = BigInt(`0x${input.newest_generation}`);
4305
4305
  const covered = BigInt(`0x${input.covers_through_generation}`);
4306
4306
  const since = newest > covered ? Number(newest - covered) : 0;
4307
- return { generations_since_checkpoint: since, advised: since >= GITVAULT_CHECKPOINT_ADVISORY_GENERATIONS };
4307
+ return { generations_since_checkpoint: since, advised: since >= VAULT_CHECKPOINT_ADVISORY_GENERATIONS };
4308
4308
  }
4309
4309
  catch {
4310
4310
  return { generations_since_checkpoint: 0, advised: false };
@@ -4324,34 +4324,34 @@ export function gitvaultCheckpointStaleness(input) {
4324
4324
  * it, ever, in V0. What DOES now exist, one call site up in `status()`, is a
4325
4325
  * way to downgrade the COPY once tripped: a locally-provable read of the
4326
4326
  * vault's covering-recipient count (the same envelope-recipients read
4327
- * `Gitvault.access` uses) can show this is no longer the single-principal
4327
+ * `Repos.access` uses) can show this is no longer the single-principal
4328
4328
  * case the message below describes. See
4329
- * {@link gitvaultKeystoreBackupReminderMessage} for that downgraded form.
4329
+ * {@link vaultKeystoreBackupReminderMessage} for that downgraded form.
4330
4330
  */
4331
- export function gitvaultLossWarningTrip(record, now = new Date()) {
4331
+ export function vaultLossWarningTrip(record, now = new Date()) {
4332
4332
  const generations = Number(record.admitted_generations ?? "0");
4333
4333
  const sourceBytes = Number(record.storage?.source_bytes ?? "0");
4334
4334
  const genesisAt = record.genesis_admitted_at ? new Date(record.genesis_admitted_at) : null;
4335
4335
  const daysSinceGenesis = genesisAt && !Number.isNaN(genesisAt.getTime()) ? (now.getTime() - genesisAt.getTime()) / 86_400_000 : null;
4336
4336
  return {
4337
- generations: Number.isFinite(generations) && generations >= GITVAULT_LOSS_WARNING_THRESHOLDS.generations,
4338
- source_bytes: Number.isFinite(sourceBytes) && sourceBytes >= GITVAULT_LOSS_WARNING_THRESHOLDS.source_bytes,
4339
- days_since_genesis: daysSinceGenesis !== null && daysSinceGenesis >= GITVAULT_LOSS_WARNING_THRESHOLDS.days_since_genesis,
4337
+ generations: Number.isFinite(generations) && generations >= VAULT_LOSS_WARNING_THRESHOLDS.generations,
4338
+ source_bytes: Number.isFinite(sourceBytes) && sourceBytes >= VAULT_LOSS_WARNING_THRESHOLDS.source_bytes,
4339
+ days_since_genesis: daysSinceGenesis !== null && daysSinceGenesis >= VAULT_LOSS_WARNING_THRESHOLDS.days_since_genesis,
4340
4340
  };
4341
4341
  }
4342
4342
  /** Any composite metric tripped — the standing warning threshold itself. */
4343
- export function gitvaultLossWarningTripped(trip) {
4343
+ export function vaultLossWarningTripped(trip) {
4344
4344
  return trip.generations || trip.source_bytes || trip.days_since_genesis;
4345
4345
  }
4346
4346
  /** Shared by both D7 message forms below — which threshold(s) tripped, in prose. */
4347
- function gitvaultLossWarningReasons(trip) {
4347
+ function vaultLossWarningReasons(trip) {
4348
4348
  const reasons = [];
4349
4349
  if (trip.generations)
4350
- reasons.push(`≥${GITVAULT_LOSS_WARNING_THRESHOLDS.generations} generations`);
4350
+ reasons.push(`≥${VAULT_LOSS_WARNING_THRESHOLDS.generations} generations`);
4351
4351
  if (trip.source_bytes)
4352
- reasons.push(`≥${Math.round(GITVAULT_LOSS_WARNING_THRESHOLDS.source_bytes / (1024 * 1024))} MB of source`);
4352
+ reasons.push(`≥${Math.round(VAULT_LOSS_WARNING_THRESHOLDS.source_bytes / (1024 * 1024))} MB of source`);
4353
4353
  if (trip.days_since_genesis)
4354
- reasons.push(`≥${GITVAULT_LOSS_WARNING_THRESHOLDS.days_since_genesis} days since genesis`);
4354
+ reasons.push(`≥${VAULT_LOSS_WARNING_THRESHOLDS.days_since_genesis} days since genesis`);
4355
4355
  return reasons;
4356
4356
  }
4357
4357
  /**
@@ -4362,10 +4362,10 @@ function gitvaultLossWarningReasons(trip) {
4362
4362
  * This is the SINGLE-PRINCIPAL form — use it only when the vault's
4363
4363
  * covering-recipient count is unknown or <= 1. Once a caller has locally
4364
4364
  * proven >= 2 covering recipients, its premise ("only one principal can open
4365
- * it") is false; use {@link gitvaultKeystoreBackupReminderMessage} instead.
4365
+ * it") is false; use {@link vaultKeystoreBackupReminderMessage} instead.
4366
4366
  */
4367
- export function gitvaultLossWarningMessage(trip) {
4368
- const reasons = gitvaultLossWarningReasons(trip);
4367
+ export function vaultLossWarningMessage(trip) {
4368
+ const reasons = vaultLossWarningReasons(trip);
4369
4369
  return (`this vault has accrued real value at risk (${reasons.join(", ")}) while only one principal can open it. ` +
4370
4370
  "Only a second principal — another keystore, or later a human envelope — demonstrably able to open the vault clears this warning; " +
4371
4371
  "this client cannot verify that yet, so it stands until you add one. No attestation or flag clears it.");
@@ -4373,22 +4373,22 @@ export function gitvaultLossWarningMessage(trip) {
4373
4373
  /**
4374
4374
  * D7's downgraded form (dogfood item 2): once `status()` has locally proven
4375
4375
  * this vault carries >= 2 covering recipients (via the same envelope-recipients
4376
- * read `Gitvault.access` uses), the single-principal premise behind
4377
- * {@link gitvaultLossWarningMessage} is false for THIS vault — printing it
4376
+ * read `Repos.access` uses), the single-principal premise behind
4377
+ * {@link vaultLossWarningMessage} is false for THIS vault — printing it
4378
4378
  * anyway would be a false terminal-loss claim. The composite threshold still
4379
- * fires the SAME way (this function does not touch `gitvaultLossWarningTrip`/
4380
- * `gitvaultLossWarningTripped` at all — a real value-at-risk signal is still
4379
+ * fires the SAME way (this function does not touch `vaultLossWarningTrip`/
4380
+ * `vaultLossWarningTripped` at all — a real value-at-risk signal is still
4381
4381
  * worth a reminder), but the copy switches to the protocol's own
4382
4382
  * keystore-qualified durability sentence instead of asserting single-principal
4383
4383
  * risk, and never claims terminal loss.
4384
4384
  */
4385
- export function gitvaultKeystoreBackupReminderMessage(trip, coveringRecipients) {
4386
- const reasons = gitvaultLossWarningReasons(trip);
4385
+ export function vaultKeystoreBackupReminderMessage(trip, coveringRecipients) {
4386
+ const reasons = vaultLossWarningReasons(trip);
4387
4387
  return (`this vault has accrued real value at risk (${reasons.join(", ")}), but it is covered by ${coveringRecipients} recipients today — not the single-principal case. ` +
4388
- `${GITVAULT_DURABILITY_STATEMENT} Back up this machine's keystore anyway: losing it does not lose the vault, but it does lose YOUR access to it.`);
4388
+ `${VAULT_DURABILITY_STATEMENT} Back up this machine's keystore anyway: losing it does not lose the vault, but it does lose YOUR access to it.`);
4389
4389
  }
4390
4390
  /**
4391
- * gitvault-mirror-default — the pure `vault_unmirrored` computation, in ONE
4391
+ * vault-mirror-default — the pure `vault_unmirrored` computation, in ONE
4392
4392
  * place so doctor and `repos view` echo the same finding instead of each
4393
4393
  * deriving their own (the loss-warning pattern above). Present when no mirror
4394
4394
  * is configured, OR when one is configured but has no success evidence yet —
@@ -4398,68 +4398,60 @@ export function gitvaultKeystoreBackupReminderMessage(trip, coveringRecipients)
4398
4398
  * never blocking; every input is client-local or read from the CUSTOMER'S
4399
4399
  * mirror — nothing here touches the gateway.
4400
4400
  */
4401
- export function gitvaultUnmirroredFinding(state) {
4401
+ export function vaultUnmirroredFinding(state) {
4402
4402
  if (state.configured && (state.last_success_at !== null || state.mirrored_generation !== null))
4403
4403
  return null;
4404
4404
  return {
4405
4405
  kind: "vault_unmirrored",
4406
- message: state.is_byo ? GITVAULT_BYO_UNMIRRORED_REMEDY_STATEMENT : GITVAULT_UNMIRRORED_FINDING_STATEMENT,
4406
+ message: state.is_byo ? VAULT_BYO_UNMIRRORED_REMEDY_STATEMENT : VAULT_UNMIRRORED_FINDING_STATEMENT,
4407
4407
  setup_command: state.configured ? "run402 repos mirror --backfill" : "run402 repos mirror <destination>",
4408
4408
  };
4409
4409
  }
4410
4410
  /**
4411
- * gitvault-byo-primary-bucket (design D4) — the ONE stderr line a degraded
4411
+ * vault-byo-primary-bucket (design D4) — the ONE stderr line a degraded
4412
4412
  * chain/payload read prints: the fallback's own destination (never a
4413
4413
  * credential) plus the canonical, mechanism-only statement. `list`/`fetch`
4414
4414
  * degrading in the SAME `git-remote-run402` session each print their own
4415
4415
  * line (one per degraded READ, not one per session) — see
4416
- * `Gitvault.withDegradedRead`'s own doc comment.
4416
+ * `Repos.withDegradedRead`'s own doc comment.
4417
4417
  */
4418
- export function gitvaultDegradedReadNote(source) {
4419
- return `degraded read from ${source.destination}: ${GITVAULT_DEGRADED_READ_STATEMENT}`;
4418
+ export function vaultDegradedReadNote(source) {
4419
+ return `degraded read from ${source.destination}: ${VAULT_DEGRADED_READ_STATEMENT}`;
4420
4420
  }
4421
- /**
4422
- * The remote door (kygit-handoff design D8): `"run402"` (the canonical,
4423
- * plumbing spelling — accepted forever) or `"kygit"` (what the
4424
- * `@kychee/kygit` shim renders once it sets `RUN402_REMOTE_SCHEME=kygit`
4425
- * before exec). The gateway never sees this — `address` and every registry
4426
- * `next_actions` command stay `run402::`; only client-side RENDERING reads
4427
- * it. Any other value falls back to `"run402"` rather than emitting an
4428
- * unparseable scheme.
4429
- */
4430
- export function gitvaultRemoteScheme() {
4431
- return typeof process !== "undefined" && process.env?.RUN402_REMOTE_SCHEME === "kygit" ? "kygit" : "run402";
4432
- }
4433
- /** `<door>::<org_id>/<project_id>` — what `git-remote-run402`/`git-remote-kygit` resolves. */
4434
- export function gitvaultRemoteUrl(orgId, projectId) {
4435
- return `${gitvaultRemoteScheme()}::${orgId}/${projectId}`;
4421
+ /** `run402::<org_id>/<project_id>` — what `git-remote-run402` resolves. */
4422
+ export function vaultRemoteUrl(orgId, projectId) {
4423
+ return `run402::${orgId}/${projectId}`;
4436
4424
  }
4437
4425
  /**
4438
- * `<door>::<org-slug>/<repo-name>` — the address-form remote builder
4426
+ * `run402::<org-slug>/<repo-name>` — the address-form remote builder
4439
4427
  * (repo-first-onramp task 4, design D6). Same string shape as
4440
- * {@link gitvaultRemoteUrl} (the wire slot admits both forms undiscriminated
4441
- * — see {@link gitvaultRemoteAddressForm}); kept as its own named function so
4428
+ * {@link vaultRemoteUrl} (the wire slot admits both forms undiscriminated
4429
+ * — see {@link vaultRemoteAddressForm}); kept as its own named function so
4442
4430
  * a call site states which form it means rather than reusing the id-form
4443
- * builder for a semantically different pair of arguments. Rendered by
4444
- * {@link gitvaultRemoteScheme} (kygit-handoff design D8) — `run402 repos
4445
- * create` renders `run402::`, `kygit create` renders `kygit::`.
4431
+ * builder for a semantically different pair of arguments.
4446
4432
  */
4447
- export function gitvaultRemoteUrlForRepo(orgSlug, repoName) {
4448
- return `${gitvaultRemoteScheme()}::${orgSlug}/${repoName}`;
4433
+ export function vaultRemoteUrlForRepo(orgSlug, repoName) {
4434
+ return `run402::${orgSlug}/${repoName}`;
4449
4435
  }
4450
4436
  /**
4451
- * Parse a `run402::<org>/<project>` OR `kygit::<org>/<project>` remote URL
4452
- * (kygit-handoff design D8) into ONE canonical, scheme-less address — the
4453
- * door never changes resolution, only rendering. `null` when it is neither.
4437
+ * Parse a `run402::<org>/<project>` remote URL into its two address halves.
4438
+ * `run402::` is the one remote scheme: `null` for anything that is not a
4439
+ * `<scheme>::` address at all, and a typed `REMOTE_SCHEME_UNSUPPORTED`
4440
+ * refusal naming the scheme for any other `<scheme>::` spelling.
4454
4441
  */
4455
- export function parseGitvaultRemoteUrl(url) {
4456
- const m = /^(?:run402|kygit)::([^/]+)\/(.+)$/.exec(url.trim());
4457
- if (!m)
4458
- return null;
4459
- return { org_id: m[1], project_id: m[2] };
4442
+ export function parseVaultRemoteUrl(url) {
4443
+ const trimmed = url.trim();
4444
+ const m = /^run402::([^/]+)\/(.+)$/.exec(trimmed);
4445
+ if (m)
4446
+ return { org_id: m[1], project_id: m[2] };
4447
+ const other = /^([A-Za-z][A-Za-z0-9+.-]*)::/.exec(trimmed);
4448
+ if (other && other[1] !== "run402") {
4449
+ throw new LocalError(`remote scheme '${other[1]}::' is not supported; the one vault remote scheme is run402::<org>/<name>`, "parsing a vault remote address", { code: "REMOTE_SCHEME_UNSUPPORTED", details: { scheme: other[1] } });
4450
+ }
4451
+ return null;
4460
4452
  }
4461
- const GITVAULT_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
4462
- const GITVAULT_PROJECT_ID_RE = /^prj_/;
4453
+ const VAULT_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
4454
+ const VAULT_PROJECT_ID_RE = /^prj_/;
4463
4455
  /**
4464
4456
  * Discriminate a parsed address's form (design D6, "resolved"): "org UUIDs
4465
4457
  * and `prj_` prefixes make slug-vs-id in the same slot unambiguous." Both
@@ -4469,8 +4461,8 @@ const GITVAULT_PROJECT_ID_RE = /^prj_/;
4469
4461
  * `prj_`-prefixed; anything else (an org slug half, or a bare repo-name half)
4470
4462
  * is slug-form. Resolution accepts either (task 4.3).
4471
4463
  */
4472
- export function gitvaultRemoteAddressForm(address) {
4473
- return GITVAULT_UUID_RE.test(address.org_id) && GITVAULT_PROJECT_ID_RE.test(address.project_id) ? "id" : "slug";
4464
+ export function vaultRemoteAddressForm(address) {
4465
+ return VAULT_UUID_RE.test(address.org_id) && VAULT_PROJECT_ID_RE.test(address.project_id) ? "id" : "slug";
4474
4466
  }
4475
4467
  /**
4476
4468
  * `SLUG_RELEASED` (a renamed/deleted org slug, still inside its ~90-day
@@ -4478,7 +4470,7 @@ export function gitvaultRemoteAddressForm(address) {
4478
4470
  * (design D6: "no redirects, deliberately"). `null` when `err` is not a
4479
4471
  * `SLUG_RELEASED` refusal.
4480
4472
  */
4481
- export function gitvaultSlugReleasedInfo(err) {
4473
+ export function vaultSlugReleasedInfo(err) {
4482
4474
  const e = err;
4483
4475
  if (!e || e.code !== "SLUG_RELEASED")
4484
4476
  return null;
@@ -4495,11 +4487,11 @@ function isMissingCutoffRoute(e) {
4495
4487
  * "No vault exists for this address/project yet" — the same 404 shape as
4496
4488
  * {@link isMissingCutoffRoute}, named separately because the two mean
4497
4489
  * different things to their callers (an absent OPTIONAL route vs. an absent
4498
- * RESOURCE). Used by {@link Gitvault.planPush} to distinguish "nothing to
4490
+ * RESOURCE). Used by {@link Repos.planCapture} to distinguish "nothing to
4499
4491
  * preview a push against" from a genuine failure worth rethrowing.
4500
4492
  */
4501
4493
  function isVaultResolutionMiss(e) {
4502
4494
  const err = e;
4503
4495
  return Boolean(err && (err.status === 404 || err.code === "RESOURCE_NOT_FOUND" || err.code === "ROUTE_NOT_FOUND"));
4504
4496
  }
4505
- //# sourceMappingURL=gitvault.js.map
4497
+ //# sourceMappingURL=repos.js.map