@homeflare/alchemy 0.37.1 → 0.37.3

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 (195) hide show
  1. package/dist/proxmox/backup-job-config.d.ts +95 -0
  2. package/dist/proxmox/backup-job-config.d.ts.map +1 -0
  3. package/dist/proxmox/backup-job-distilled.d.ts +46 -0
  4. package/dist/proxmox/backup-job-distilled.d.ts.map +1 -0
  5. package/dist/proxmox/backup-job.d.ts +9 -26
  6. package/dist/proxmox/backup-job.d.ts.map +1 -1
  7. package/dist/proxmox/ceph-fs-distilled.d.ts +17 -10
  8. package/dist/proxmox/ceph-fs-distilled.d.ts.map +1 -1
  9. package/dist/proxmox/ceph-fs-wire.d.ts +5 -22
  10. package/dist/proxmox/ceph-fs-wire.d.ts.map +1 -1
  11. package/dist/proxmox/ceph-fs.d.ts +3 -3
  12. package/dist/proxmox/distilled-pbs.d.ts +12 -0
  13. package/dist/proxmox/distilled-pbs.d.ts.map +1 -0
  14. package/dist/proxmox/fake-pbs-jobs.d.ts +23 -0
  15. package/dist/proxmox/fake-pbs-jobs.d.ts.map +1 -0
  16. package/dist/proxmox/fake-pbs-notify.d.ts.map +1 -1
  17. package/dist/proxmox/fake-pve.d.ts +1 -1
  18. package/dist/proxmox/fake-pve.d.ts.map +1 -1
  19. package/dist/proxmox/group-wire.d.ts +2 -2
  20. package/dist/proxmox/group-wire.d.ts.map +1 -1
  21. package/dist/proxmox/index.js +1382 -506
  22. package/dist/proxmox/index.js.map +51 -27
  23. package/dist/proxmox/live-core-fixtures.d.ts +40 -0
  24. package/dist/proxmox/live-core-fixtures.d.ts.map +1 -0
  25. package/dist/proxmox/metric-server-config.d.ts +49 -0
  26. package/dist/proxmox/metric-server-config.d.ts.map +1 -0
  27. package/dist/proxmox/metric-server-distilled.d.ts +43 -0
  28. package/dist/proxmox/metric-server-distilled.d.ts.map +1 -0
  29. package/dist/proxmox/metric-server.d.ts +2 -10
  30. package/dist/proxmox/metric-server.d.ts.map +1 -1
  31. package/dist/proxmox/node-network-wire.d.ts +1 -1
  32. package/dist/proxmox/node-network-wire.d.ts.map +1 -1
  33. package/dist/proxmox/notification-matcher-distilled.d.ts +9 -0
  34. package/dist/proxmox/notification-matcher-distilled.d.ts.map +1 -0
  35. package/dist/proxmox/notification-matcher-lifecycle.d.ts +27 -0
  36. package/dist/proxmox/notification-matcher-lifecycle.d.ts.map +1 -0
  37. package/dist/proxmox/notification-matcher.d.ts +5 -5
  38. package/dist/proxmox/notification-matcher.d.ts.map +1 -1
  39. package/dist/proxmox/notification-sdk-input.d.ts +22 -0
  40. package/dist/proxmox/notification-sdk-input.d.ts.map +1 -0
  41. package/dist/proxmox/notification-target-distilled.d.ts +12 -0
  42. package/dist/proxmox/notification-target-distilled.d.ts.map +1 -0
  43. package/dist/proxmox/notification-target-form.d.ts +2 -0
  44. package/dist/proxmox/notification-target-form.d.ts.map +1 -1
  45. package/dist/proxmox/notification-target-lifecycle.d.ts +29 -0
  46. package/dist/proxmox/notification-target-lifecycle.d.ts.map +1 -0
  47. package/dist/proxmox/notification-target-spec.d.ts +5 -0
  48. package/dist/proxmox/notification-target-spec.d.ts.map +1 -0
  49. package/dist/proxmox/notification-target.d.ts +4 -5
  50. package/dist/proxmox/notification-target.d.ts.map +1 -1
  51. package/dist/proxmox/pbs-datastore-endpoint.d.ts +1 -1
  52. package/dist/proxmox/pbs-datastore-form.d.ts +18 -42
  53. package/dist/proxmox/pbs-datastore-form.d.ts.map +1 -1
  54. package/dist/proxmox/pbs-datastore-guard.d.ts +7 -4
  55. package/dist/proxmox/pbs-datastore-guard.d.ts.map +1 -1
  56. package/dist/proxmox/pbs-datastore-lifecycle.d.ts +56 -0
  57. package/dist/proxmox/pbs-datastore-lifecycle.d.ts.map +1 -0
  58. package/dist/proxmox/pbs-datastore-wire.d.ts +21 -0
  59. package/dist/proxmox/pbs-datastore-wire.d.ts.map +1 -0
  60. package/dist/proxmox/pbs-datastore.d.ts +5 -6
  61. package/dist/proxmox/pbs-datastore.d.ts.map +1 -1
  62. package/dist/proxmox/pbs-notification-input.d.ts +18 -0
  63. package/dist/proxmox/pbs-notification-input.d.ts.map +1 -0
  64. package/dist/proxmox/pbs-notification-matcher-distilled.d.ts +11 -0
  65. package/dist/proxmox/pbs-notification-matcher-distilled.d.ts.map +1 -0
  66. package/dist/proxmox/pbs-notification-matcher.d.ts +4 -3
  67. package/dist/proxmox/pbs-notification-matcher.d.ts.map +1 -1
  68. package/dist/proxmox/pbs-notification-target-distilled.d.ts +20 -0
  69. package/dist/proxmox/pbs-notification-target-distilled.d.ts.map +1 -0
  70. package/dist/proxmox/pbs-notification-target-lifecycle.d.ts +4 -4
  71. package/dist/proxmox/pbs-notification-target-lifecycle.d.ts.map +1 -1
  72. package/dist/proxmox/pbs-notification-target.d.ts +1 -1
  73. package/dist/proxmox/pbs-prune-job-lifecycle.d.ts +22 -0
  74. package/dist/proxmox/pbs-prune-job-lifecycle.d.ts.map +1 -0
  75. package/dist/proxmox/pbs-prune-job-spec.d.ts +5 -0
  76. package/dist/proxmox/pbs-prune-job-spec.d.ts.map +1 -0
  77. package/dist/proxmox/pbs-prune-job-wire.d.ts +11 -0
  78. package/dist/proxmox/pbs-prune-job-wire.d.ts.map +1 -0
  79. package/dist/proxmox/pbs-prune-job.d.ts +9 -8
  80. package/dist/proxmox/pbs-prune-job.d.ts.map +1 -1
  81. package/dist/proxmox/pbs-sync-job-attributes.d.ts +34 -0
  82. package/dist/proxmox/pbs-sync-job-attributes.d.ts.map +1 -0
  83. package/dist/proxmox/pbs-sync-job-form.d.ts +21 -22
  84. package/dist/proxmox/pbs-sync-job-form.d.ts.map +1 -1
  85. package/dist/proxmox/pbs-sync-job-lifecycle.d.ts +22 -0
  86. package/dist/proxmox/pbs-sync-job-lifecycle.d.ts.map +1 -0
  87. package/dist/proxmox/pbs-sync-job-wire.d.ts +11 -0
  88. package/dist/proxmox/pbs-sync-job-wire.d.ts.map +1 -0
  89. package/dist/proxmox/pbs-sync-job.d.ts +9 -39
  90. package/dist/proxmox/pbs-sync-job.d.ts.map +1 -1
  91. package/dist/proxmox/pbs-verify-job-lifecycle.d.ts +22 -0
  92. package/dist/proxmox/pbs-verify-job-lifecycle.d.ts.map +1 -0
  93. package/dist/proxmox/pbs-verify-job-spec.d.ts +16 -0
  94. package/dist/proxmox/pbs-verify-job-spec.d.ts.map +1 -0
  95. package/dist/proxmox/pbs-verify-job-wire.d.ts +11 -0
  96. package/dist/proxmox/pbs-verify-job-wire.d.ts.map +1 -0
  97. package/dist/proxmox/pbs-verify-job.d.ts +12 -12
  98. package/dist/proxmox/pbs-verify-job.d.ts.map +1 -1
  99. package/dist/proxmox/pool.d.ts +10 -1
  100. package/dist/proxmox/pool.d.ts.map +1 -1
  101. package/dist/proxmox/storage-wire.d.ts +2 -2
  102. package/dist/proxmox/storage-wire.d.ts.map +1 -1
  103. package/dist/proxmox/user-wire.d.ts +2 -2
  104. package/dist/proxmox/user-wire.d.ts.map +1 -1
  105. package/dist/proxmox/zfs-pool-wire.d.ts +1 -1
  106. package/dist/proxmox/zfs-pool-wire.d.ts.map +1 -1
  107. package/docs/changelog/README.md +22 -0
  108. package/docs/changelog/archive-01.md +176 -0
  109. package/docs/changelog/archive-02.md +180 -0
  110. package/docs/changelog/archive-03.md +179 -0
  111. package/docs/changelog/archive-04.md +178 -0
  112. package/docs/changelog/archive-05.md +177 -0
  113. package/docs/changelog/archive-06.md +180 -0
  114. package/docs/changelog/archive-07.md +180 -0
  115. package/docs/changelog/archive-08.md +178 -0
  116. package/docs/changelog/archive-09.md +181 -0
  117. package/docs/changelog/archive-10.md +182 -0
  118. package/docs/changelog/archive-11.md +182 -0
  119. package/docs/changelog/archive-12.md +183 -0
  120. package/docs/changelog/archive-13.md +180 -0
  121. package/docs/changelog/archive-14.md +178 -0
  122. package/docs/changelog/archive-15.md +181 -0
  123. package/docs/changelog/archive-16.md +182 -0
  124. package/docs/changelog/archive-17.md +183 -0
  125. package/docs/changelog/archive-18.md +55 -0
  126. package/docs/pbs-distilled-jobs.md +31 -0
  127. package/docs/pbs-notifications.md +8 -2
  128. package/docs/proxmox-notification-sdk.md +28 -0
  129. package/docs/proxmox-sdk-migration.md +60 -0
  130. package/docs/proxmox.md +9 -3
  131. package/docs/upstream-conformance-families.md +6 -2
  132. package/package.json +3 -3
  133. package/src/proxmox/adopt-noop.test.ts +4 -5
  134. package/src/proxmox/backup-job-config.ts +95 -0
  135. package/src/proxmox/backup-job-distilled.ts +86 -0
  136. package/src/proxmox/backup-job.ts +78 -116
  137. package/src/proxmox/ceph-fs-delete.test.ts +5 -8
  138. package/src/proxmox/ceph-fs-destroy-sdk.test.ts +98 -0
  139. package/src/proxmox/ceph-fs-distilled.ts +41 -13
  140. package/src/proxmox/ceph-fs-wire.ts +5 -93
  141. package/src/proxmox/ceph-fs.ts +7 -7
  142. package/src/proxmox/constraints.test.ts +9 -8
  143. package/src/proxmox/distilled-pbs.test.ts +87 -0
  144. package/src/proxmox/distilled-pbs.ts +50 -0
  145. package/src/proxmox/fake-pbs-jobs.ts +99 -0
  146. package/src/proxmox/fake-pbs-notify.ts +4 -1
  147. package/src/proxmox/fake-pve.ts +3 -2
  148. package/src/proxmox/live-core-fixtures.ts +126 -0
  149. package/src/proxmox/live-core-lifecycle.test.ts +115 -0
  150. package/src/proxmox/live-core-wire.test.ts +190 -0
  151. package/src/proxmox/metric-server-config.ts +87 -0
  152. package/src/proxmox/metric-server-distilled.ts +81 -0
  153. package/src/proxmox/metric-server.ts +77 -88
  154. package/src/proxmox/notification-distilled.test.ts +162 -0
  155. package/src/proxmox/notification-matcher-distilled.ts +60 -0
  156. package/src/proxmox/notification-matcher-lifecycle.ts +71 -0
  157. package/src/proxmox/notification-matcher.ts +9 -26
  158. package/src/proxmox/notification-replacement.test.ts +190 -0
  159. package/src/proxmox/notification-sdk-input.ts +39 -0
  160. package/src/proxmox/notification-target-distilled.ts +160 -0
  161. package/src/proxmox/notification-target-form.ts +2 -0
  162. package/src/proxmox/notification-target-lifecycle.ts +75 -0
  163. package/src/proxmox/notification-target-spec.ts +68 -0
  164. package/src/proxmox/notification-target.ts +6 -68
  165. package/src/proxmox/pbs-datastore-endpoint.ts +1 -1
  166. package/src/proxmox/pbs-datastore-form.ts +18 -49
  167. package/src/proxmox/pbs-datastore-guard.ts +7 -4
  168. package/src/proxmox/pbs-datastore-lifecycle.ts +114 -0
  169. package/src/proxmox/pbs-datastore-wire.ts +94 -0
  170. package/src/proxmox/pbs-datastore.ts +7 -133
  171. package/src/proxmox/pbs-jobs-delete.test.ts +40 -0
  172. package/src/proxmox/pbs-jobs-sdk.test.ts +215 -0
  173. package/src/proxmox/pbs-notification-errors.test.ts +93 -0
  174. package/src/proxmox/pbs-notification-input.ts +25 -0
  175. package/src/proxmox/pbs-notification-mail.test.ts +64 -0
  176. package/src/proxmox/pbs-notification-matcher-distilled.ts +65 -0
  177. package/src/proxmox/pbs-notification-matcher.ts +70 -17
  178. package/src/proxmox/pbs-notification-target-distilled.ts +124 -0
  179. package/src/proxmox/pbs-notification-target-lifecycle.ts +26 -17
  180. package/src/proxmox/pbs-notification-target.ts +1 -1
  181. package/src/proxmox/pbs-notifications-stack.test.ts +25 -0
  182. package/src/proxmox/pbs-prune-job-lifecycle.ts +52 -0
  183. package/src/proxmox/pbs-prune-job-spec.ts +53 -0
  184. package/src/proxmox/pbs-prune-job-wire.ts +68 -0
  185. package/src/proxmox/pbs-prune-job.ts +10 -58
  186. package/src/proxmox/pbs-sync-job-attributes.ts +33 -0
  187. package/src/proxmox/pbs-sync-job-form.ts +7 -6
  188. package/src/proxmox/pbs-sync-job-lifecycle.ts +46 -0
  189. package/src/proxmox/pbs-sync-job-wire.ts +71 -0
  190. package/src/proxmox/pbs-sync-job.ts +10 -41
  191. package/src/proxmox/pbs-verify-job-lifecycle.ts +52 -0
  192. package/src/proxmox/pbs-verify-job-spec.ts +76 -0
  193. package/src/proxmox/pbs-verify-job-wire.ts +58 -0
  194. package/src/proxmox/pbs-verify-job.ts +13 -85
  195. package/src/proxmox/pool.ts +92 -10
@@ -33,13 +33,15 @@ export declare const guardBackend: (live: PbsDatastoreAttributes, props: PbsData
33
33
  /**
34
34
  * Wait for PBS to finish, then answer the last thing it said.
35
35
  *
36
- * ⛔ IT EXISTS BECAUSE A PBS CREATE IS A FORKED WORKER AND THE CONFIG SECTION IS WRITTEN LAST.
36
+ * ⛔ THE ORIGINAL CREATE-WORKER ASSUMPTION BELOW WAS REASONED, NOT MEASURED.
37
37
  * `POST /config/datastore` answers with a UPID while a `create-datastore` task builds the chunk
38
38
  * store's 65536 directories; only when that finishes does the section reach `datastore.cfg`. An
39
39
  * immediate read-back therefore sees a datastore that is not there yet, and the factory's "the
40
40
  * write returned no error but the object is still absent" would fire on a create going perfectly.
41
41
  * The DELETE forks a worker too. ⚠️ DOCUMENTED FROM THE PUBLISHED SCHEMA, NOT MEASURED — I hold
42
- * no PBS token. If a create turns out to be synchronous, the first poll simply succeeds.
42
+ * no PBS token. The pinned PBS 4.2.6-1 schema actually declares a NULL create response,
43
+ * while DELETE declares a UPID. We preserve bounded readback for both; a synchronous create
44
+ * succeeds at the first poll rather than depending on the old UPID assumption.
43
45
  * ★ IT TAKES THE READ AS AN EFFECT RATHER THAN A FUNCTION — the one simplification over
44
46
  * ceph-pool-settle.ts: an Effect is a description, so re-running it re-reads and no dependency
45
47
  * has to be threaded back in to avoid a cycle.
@@ -48,8 +50,9 @@ export declare const guardBackend: (live: PbsDatastoreAttributes, props: PbsData
48
50
  * Anything still unsettled after two minutes is a fault to surface, not a wait to lengthen, and
49
51
  * the caller's message points at the task log, which is where the real answer is. `Effect.sleep`
50
52
  * yields between polls; nothing here parks a call on one long wait.
51
- * ⚠️ POLLING THE TASK STATUS INSTEAD WOULD BE WORSE, for ceph-pool-settle.ts's reason: every call
52
- * mints a FRESH token, so the token asking about the task is not the one that started it.
53
+ * ⚠️ THE ORIGINAL TRANSPORT MINTED A TOKEN PER CALL, making task-owner polling unreliable.
54
+ * The SDK runner now reuses leases, but create has no task id in its measured response schema.
55
+ * This migration therefore preserves bounded readback rather than inventing a task handle.
53
56
  */
54
57
  export declare const settle: <A, E, R>(read: Effect.Effect<A, E, R>, done: (live: A) => boolean) => Effect.Effect<A, E, R>;
55
58
  //# sourceMappingURL=pbs-datastore-guard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pbs-datastore-guard.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-datastore-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,sBAAsB,EAAU,MAAM,yBAAyB,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAmB5D;;;;GAIG;AACH,eAAO,MAAM,SAAS,SAAU,sBAAsB,SAAS,iBAAiB,sCAWzE,CAAC;AAER;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,SAAU,sBAAsB,SAAS,iBAAiB,sCAY5E,CAAC;AAER;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,2BAQpF,CAAC"}
1
+ {"version":3,"file":"pbs-datastore-guard.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-datastore-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,sBAAsB,EAAU,MAAM,yBAAyB,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAmB5D;;;;GAIG;AACH,eAAO,MAAM,SAAS,SAAU,sBAAsB,SAAS,iBAAiB,sCAWzE,CAAC;AAER;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,SAAU,sBAAsB,SAAS,iBAAiB,sCAY5E,CAAC;AAER;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,2BAQpF,CAAC"}
@@ -0,0 +1,56 @@
1
+ import type { Input } from 'alchemy/Input';
2
+ import * as Effect from 'effect/Effect';
3
+ import type { PbsDatastoreProps } from './pbs-datastore.ts';
4
+ import { type PbsDatastoreAttributes } from './pbs-datastore-form.ts';
5
+ export declare const handlers: {
6
+ /**
7
+ * ⛔ EMPTY, AND HERE IT GUARDS THE ESTATE'S BACKUPS. `GET /config/datastore` returns every
8
+ * datastore on the host, the one PVE's `type: pbs` storage writes into included. See
9
+ * `pveHandlers` in resource.ts for why adoption stays an explicit act.
10
+ */
11
+ list: () => Effect.Effect<never[], never, never>;
12
+ read: ({ olds }: {
13
+ olds: PbsDatastoreProps;
14
+ }) => Effect.Effect<PbsDatastoreAttributes | undefined, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | import("@distilled.cloud/proxmox-backup/Protocol").ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
15
+ /**
16
+ * ⚠️ `isResolved` IS THE NARROWING, resource.ts's reason: at plan time a prop can still be an
17
+ * unresolved Output, and comparing a placeholder to a live value reports a phantom update.
18
+ * ⛔ `guardPath` IS A DELIBERATE DEPARTURE FROM storage.ts, which lets its create-only field
19
+ * plan as noop. Dying fails `alchemy plan` with both paths named — see the ⛔ on the prop.
20
+ */
21
+ diff: ({ news, output, }: {
22
+ news: Input<PbsDatastoreProps>;
23
+ output: PbsDatastoreAttributes | undefined;
24
+ }) => Effect.Effect<{
25
+ readonly action: 'update';
26
+ } | {
27
+ readonly action: 'noop';
28
+ } | undefined, Error | import("effect/unstable/http/HttpClientError").HttpClientError | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
29
+ /**
30
+ * ⚠️ NOT THE FACTORY'S reconcile: it reads back ONCE, immediately — see the ⛔ on `settle`.
31
+ * ⛔ `guardPath` RUNS HERE TOO, AND THAT IS NOT BELT-AND-BRACES — see the ⛔ on it.
32
+ * ⛔ THE `matches` GUARD BEFORE THE PUT IS resource.ts's, AND IT IS WHY ADOPTION IS FREE.
33
+ */
34
+ reconcile: (args_0: {
35
+ news: PbsDatastoreProps;
36
+ }) => Effect.Effect<PbsDatastoreAttributes, Error | import("effect/unstable/http/HttpClientError").HttpClientError | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
37
+ /**
38
+ * ⛔ FULLY IMPLEMENTED, NEVER A STUB, and it only ever runs on an explicit
39
+ * `.pipe(RemovalPolicy.destroy())` because this family defaults to `retain`.
40
+ * ⛔ NO `destroy-data`. PBS's DELETE drops the section from `datastore.cfg` and leaves every
41
+ * chunk and snapshot on disk; `destroy-data=1` erases the contents. It is not a prop and
42
+ * not a flag here, so this provider can un-declare a datastore and can never erase one.
43
+ * ⚠️ IT IS STILL A ONE-WAY DOOR FOR A DECLARATION: re-adding a datastore over an existing
44
+ * chunk store needs `reuse-datastore`, which is deliberately not declarable — see the
45
+ * ⚠️ on `createForm`. Re-adopt with `proxmox-backup-manager datastore create …`.
46
+ * ⚠️ NO `keep-job-configs` EITHER, SO THE JOBS GO TOO: PBS defaults it false and removes the
47
+ * verify, sync and prune jobs referencing this datastore — objects nothing here declares.
48
+ * PBS's default stands, so the blast radius is what a human clicking Remove would get.
49
+ * ⚠️ AND THE REFUSAL CAN ARRIVE AFTER THE RESPONSE: the delete forks a worker too, so a store
50
+ * held open by a running backup can fail once the call has already returned 200.
51
+ */
52
+ delete: (args_0: {
53
+ olds: PbsDatastoreProps;
54
+ }) => Effect.Effect<undefined, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | import("@distilled.cloud/proxmox-backup/Protocol").ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
55
+ };
56
+ //# sourceMappingURL=pbs-datastore-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-datastore-lifecycle.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-datastore-lifecycle.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,KAAK,sBAAsB,EAA+B,MAAM,yBAAyB,CAAC;AAMnG,eAAO,MAAM,QAAQ;IACnB;;;;OAIG;IACH,IAAI;IACJ,IAAI,aAAa;QAAE,IAAI,EAAE,iBAAiB,CAAA;KAAE;IAC5C;;;;;OAKG;IACH,IAAI,sBAGD;QACD,IAAI,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,EAAE,sBAAsB,GAAG,SAAS,CAAC;KAC5C;yBAU4C,QAAQ;;yBAGT,MAAM;;IAElD;;;;OAIG;IACH,SAAS;cAAyC,iBAAiB;;IAiCnE;;;;;;;;;;;;;;OAcG;IACH,MAAM;cAAyC,iBAAiB;;CAcjE,CAAC"}
@@ -0,0 +1,21 @@
1
+ /** PBS 4.2.6-1 datastore SDK operations; no raw route-string transport. */
2
+ import * as config from '@distilled.cloud/proxmox-backup/config';
3
+ import * as Effect from 'effect/Effect';
4
+ import type { PbsDatastoreProps } from './pbs-datastore.ts';
5
+ /**
6
+ * ⛔ THE RAW READ FOLDED EVERY ERROR TO ABSENCE. Its `name` presence check could not distinguish
7
+ * a missing section from a denied read: both suggested CREATE for a datastore holding backups.
8
+ * The resulting "already exists" failure was loud, but the same fold on DELETE was worse:
9
+ * the first denied read confirmed removal while the datastore still stood.
10
+ * ★ MEASURED 2026-09-24 against PBS 4.2.6-1: a missing section is plain-text HTTP400,
11
+ * `no such datastore '<name>'`. The distilled patch types that GET response as
12
+ * DatastoreNotFound. Only that tag means absent; no permission, transport or malformed-response
13
+ * error can settle deletion. This replaces the old recommendation to disambiguate by listing.
14
+ * ⚠️ The read role still requires Datastore.Audit, and a missing grant now fails visibly.
15
+ */
16
+ export declare const readOne: (props: PbsDatastoreProps) => Effect.Effect<import("./pbs-datastore-form.ts").PbsDatastoreAttributes | undefined, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | config.ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
17
+ export declare const createOne: (props: PbsDatastoreProps) => Effect.Effect<config.CreateConfigDatastoreResponse, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | config.ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
18
+ export declare const updateOne: (props: PbsDatastoreProps) => Effect.Effect<config.PutConfigDatastoreResponse, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | config.ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
19
+ /** ⛔ No destroy-data or keep-job-configs flag: retain the original removal contract. */
20
+ export declare const deleteOne: (props: PbsDatastoreProps) => Effect.Effect<string | undefined, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | config.ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
21
+ //# sourceMappingURL=pbs-datastore-wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-datastore-wire.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-datastore-wire.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,OAAO,KAAK,MAAM,MAAM,wCAAwC,CAAC;AACjE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAuD5D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,UAAW,iBAAiB,gRAI7C,CAAC;AAEJ,eAAO,MAAM,SAAS,UAAW,iBAAiB,gPACqC,CAAC;AAExF,eAAO,MAAM,SAAS,UAAW,iBAAiB,6OACkC,CAAC;AAErF,wFAAwF;AACxF,eAAO,MAAM,SAAS,UAAW,iBAAiB,8NAS9C,CAAC"}
@@ -13,12 +13,11 @@
13
13
  * `/access/domains` lists the realms `pbs`, `pam` and an openid realm. So the
14
14
  * prefix, the `{"data": …}` envelope and the strict-TLS story are PVE's exactly — and only the
15
15
  * credential differs. There is no `pve` realm here; a PVE token cannot authenticate at all.
16
- * The header differs too, which is why `pve()` exists rather than `pve()` being reused — see the
17
- * ⛔ on `pbsAuthorization` in pbs-datastore-form.ts.
16
+ * The distilled PBS SDK owns that distinct header; `distilled-pbs.ts` supplies its credentials.
18
17
  *
19
- * ⛔ THERE IS NO OPENBAO MOUNT FOR PBS TODAY, SO NOTHING HERE CAN DEPLOY YET. `PbsTarget.mount` is
18
+ * ⚠️ HISTORICAL BOOTSTRAP BLOCKER, 2026-09-13: THERE WAS NO PBS MOUNT. `PbsTarget.mount` is
20
19
  * a parameter for the reason `PveTarget.mount` is — the provider must be able to leave this
21
- * estate — but the estate has nothing to put in it. MEASURED: under the agent's approle,
20
+ * estate. A later PBS credential lane resolved the following incident. MEASURED: under the agent's approle,
22
21
  * `bao token capabilities` answers `deny` for `proxmox-c1/creds/{read,provision}`,
23
22
  * `proxmox-c2/creds/read` and every `…pbs…` path tried, and `sys/mounts` is 403 — so I could
24
23
  * not enumerate the mounts to PROVE a PBS one is absent. That it is absent is the brief's
@@ -27,7 +26,7 @@
27
26
  * <mount>/creds/<role>` answering `{"data":{"token_id":…,"secret":…}}`, where `token_id` is a
28
27
  * PBS token id `user@realm!tokenname` — `hf-read@pbs!…` and `hf-provision@pbs!…`. Same short,
29
28
  * non-renewable lease contract as `proxmox-c1`.
30
- * ⚠️ PBS HAS NO DYNAMIC-SECRETS PLUGIN OF ITS OWN — OpenBao's Proxmox support is a PVE thing — so
29
+ * ⚠️ PBS HAD NO DYNAMIC-SECRETS PLUGIN OF ITS OWN — OpenBao's Proxmox support is a PVE thing — so
31
30
  * the mount is a small custom vendor against `POST /access/users/{id}/token/{name}`. Say which
32
31
  * mount and role you needed rather than reaching for the read-only `metrics@pbs` token on
33
32
  * the kv shelf: widening that would delete the outer lock for every reader of the shelf.
@@ -51,7 +50,7 @@
51
50
  */
52
51
  import { Resource } from 'alchemy';
53
52
  import * as Provider from 'alchemy/Provider';
54
- import { type PbsDatastoreAttributes, type PbsTarget } from './pbs-datastore-form.ts';
53
+ import type { PbsDatastoreAttributes, PbsTarget } from './pbs-datastore-form.ts';
55
54
  import type { PveRequirements } from './resource.ts';
56
55
  export type { PbsDatastoreAttributes, PbsTarget };
57
56
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"pbs-datastore.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-datastore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAG7C,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,SAAS,EAMf,MAAM,yBAAyB,CAAC;AAGjC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,YAAY,EAAE,sBAAsB,EAAE,SAAS,EAAE,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,SAAS,CAAC;IAClB,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;OASG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gGAAgG;IAChG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kGAAkG;IAClG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+FAA+F;IAC/F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iGAAiG;IACjG,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,YAAa,SAAQ,QAAQ,CAC5C,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ,uFAAuF;AACvF,eAAO,MAAM,YAAY,+CAEvB,CAAC;AAEH,eAAO,MAAM,oBAAoB,kIAkH9B,CAAC"}
1
+ {"version":3,"file":"pbs-datastore.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-datastore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,YAAY,EAAE,sBAAsB,EAAE,SAAS,EAAE,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,SAAS,CAAC;IAClB,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;OASG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gGAAgG;IAChG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kGAAkG;IAClG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+FAA+F;IAC/F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iGAAiG;IACjG,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,YAAa,SAAQ,QAAQ,CAC5C,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ,uFAAuF;AACvF,eAAO,MAAM,YAAY,+CAEvB,CAAC;AAEH,eAAO,MAAM,oBAAoB,kIACkD,CAAC"}
@@ -0,0 +1,18 @@
1
+ import * as Effect from 'effect/Effect';
2
+ import * as Schema from 'effect/Schema';
3
+ declare const PbsNotificationInputRefusal_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
4
+ readonly _tag: "PbsNotificationInputRefusal";
5
+ } & Readonly<A>;
6
+ export declare class PbsNotificationInputRefusal extends PbsNotificationInputRefusal_base<{
7
+ readonly message: string;
8
+ }> {
9
+ }
10
+ /**
11
+ * Fields already use SDK Type-side names; toType validates without any wire transforms.
12
+ * A schema diagnostic can reproduce the whole submitted form, including a webhook secret or
13
+ * SMTP password. Sanitize only our pre-request validation failure. SDK operation errors below
14
+ * this boundary retain their original typed tags and are never remapped.
15
+ */
16
+ export declare const notificationInput: <S extends Schema.Top>(schema: S, fields: unknown) => Effect.Effect<S["Type"], PbsNotificationInputRefusal, never>;
17
+ export {};
18
+ //# sourceMappingURL=pbs-notification-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-notification-input.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-input.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;;;;AAExC,qBAAa,2BAA4B,SAAQ,iCAAgD;IAC/F,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;CAAG;AAEL;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,MAAM,CAAC,GAAG,UAAU,CAAC,UAAU,OAAO,iEAS/E,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** PBS 4.2.6-1 matcher operations through SDK 0.3.0; failed reads never become absence. */
2
+ import * as config from '@distilled.cloud/proxmox-backup/config';
3
+ import * as Effect from 'effect/Effect';
4
+ import { type MatcherCreateForm, type MatcherUpdateForm } from './notification-matcher-form.ts';
5
+ import type { PbsNotificationMatcherProps as Props } from './pbs-notification-matcher.ts';
6
+ export declare const readMatcher: (props: Props) => Effect.Effect<import("./notification-matcher-form.ts").NotificationMatcherAttributes | undefined, import("@distilled.cloud/caddy").BadGateway | import("@distilled.cloud/caddy").BadRequest | import("@distilled.cloud/caddy").ConfigError | import("@distilled.cloud/caddy").Conflict | Error | import("@distilled.cloud/caddy").Forbidden | import("@distilled.cloud/caddy").GatewayTimeout | import("effect/unstable/http/HttpClientError").HttpClientError | import("@distilled.cloud/caddy").InternalServerError | import("@distilled.cloud/caddy").Locked | import("@distilled.cloud/proxmox-backup/Errors").ParameterVerificationFailed | import("./credential-errors.ts").PveCredentialDenied | import("@distilled.cloud/caddy").ServiceUnavailable | import("effect/Cause").TimeoutError | import("@distilled.cloud/caddy").TooManyRequests | import("@distilled.cloud/caddy").Unauthorized | import("@distilled.cloud/caddy").UnprocessableEntity | import("@distilled.cloud/proxmox-backup/Errors").ClientErrors, import("effect/unstable/http/HttpClient").HttpClient>;
7
+ export declare const createMatcher: (props: Props, form: MatcherCreateForm) => Effect.Effect<config.CreateConfigNotificationMatcherResponse, Error | import("./pbs-notification-input.ts").PbsNotificationInputRefusal | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | config.ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
8
+ export declare const updateMatcher: (props: Props, form: MatcherUpdateForm) => Effect.Effect<config.PutConfigNotificationMatcherResponse, Error | import("./pbs-notification-input.ts").PbsNotificationInputRefusal | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | config.ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
9
+ /** PBS reverts built-ins on deletion; it reports NotFound only for an absent user-created row. */
10
+ export declare const deleteMatcher: (props: Props) => Effect.Effect<void | config.DeleteConfigNotificationMatcherResponse, import("@distilled.cloud/caddy").BadGateway | import("@distilled.cloud/caddy").BadRequest | import("@distilled.cloud/caddy").ConfigError | import("@distilled.cloud/caddy").Conflict | Error | import("@distilled.cloud/caddy").Forbidden | import("@distilled.cloud/caddy").GatewayTimeout | import("effect/unstable/http/HttpClientError").HttpClientError | import("@distilled.cloud/caddy").InternalServerError | import("@distilled.cloud/caddy").Locked | import("@distilled.cloud/proxmox-backup/Errors").ParameterVerificationFailed | import("./credential-errors.ts").PveCredentialDenied | import("@distilled.cloud/caddy").ServiceUnavailable | import("effect/Cause").TimeoutError | import("@distilled.cloud/caddy").TooManyRequests | import("@distilled.cloud/caddy").Unauthorized | import("@distilled.cloud/caddy").UnprocessableEntity | import("@distilled.cloud/proxmox-backup/Errors").ClientErrors, import("effect/unstable/http/HttpClient").HttpClient>;
11
+ //# sourceMappingURL=pbs-notification-matcher-distilled.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-notification-matcher-distilled.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-matcher-distilled.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,OAAO,KAAK,MAAM,MAAM,wCAAwC,CAAC;AACjE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAEvB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,2BAA2B,IAAI,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAE1F,eAAO,MAAM,WAAW,UAAW,KAAK,uhCAerC,CAAC;AAYJ,eAAO,MAAM,aAAa,UAAW,KAAK,QAAQ,iBAAiB,8TAQhE,CAAC;AAEJ,eAAO,MAAM,aAAa,UAAW,KAAK,QAAQ,iBAAiB,2TAOhE,CAAC;AAEJ,kGAAkG;AAClG,eAAO,MAAM,aAAa,UAAW,KAAK,0/BAKc,CAAC"}
@@ -36,13 +36,14 @@
36
36
  * ★ WHAT THIS NEEDS, READ OFF THE SERVER'S SCHEMA (generated/pbs.ts source):
37
37
  * read GET Sys.Audit on /system/notifications
38
38
  * write POST, PUT, DELETE Sys.Modify on /system/notifications
39
- * ⚠️ NOT A DATASTORE PRIVILEGE. A PBS credential scoped to `/datastore/...` reads every matcher
40
- * as absent — the "absent, then already exists" signature notification-target.ts describes.
39
+ * ⚠️ NOT A DATASTORE PRIVILEGE. A credential scoped to `/datastore/...` cannot read matchers;
40
+ * the old client treated that refusal as absent — notification-target.ts describes the
41
+ * resulting "absent, then already exists" signature.
41
42
  */
42
43
  import { Resource } from 'alchemy';
43
44
  import * as Provider from 'alchemy/Provider';
44
45
  import { type NotificationMatcherAttributes, type NotificationMatcherFields } from './notification-matcher-form.ts';
45
- import { type PveRequirements, type WithPbsTarget } from './resource.ts';
46
+ import type { PveRequirements, WithPbsTarget } from './resource.ts';
46
47
  export interface PbsNotificationMatcherProps extends NotificationMatcherFields, WithPbsTarget {
47
48
  }
48
49
  export interface PbsNotificationMatcher extends Resource<'Pbs.NotificationMatcher', PbsNotificationMatcherProps, NotificationMatcherAttributes, never, PveRequirements> {
@@ -1 +1 @@
1
- {"version":3,"file":"pbs-notification-matcher.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,yBAAyB,EAK/B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAe,MAAM,eAAe,CAAC;AAEtF,MAAM,WAAW,2BAA4B,SAAQ,yBAAyB,EAAE,aAAa;CAAG;AAEhG,MAAM,WAAW,sBAAuB,SAAQ,QAAQ,CACtD,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ,0FAA0F;AAC1F,eAAO,MAAM,sBAAsB,yDAA8D,CAAC;AAgBlG,eAAO,MAAM,8BAA8B,4IAIxC,CAAC"}
1
+ {"version":3,"file":"pbs-notification-matcher.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAI7C,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,yBAAyB,EAI/B,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AASpE,MAAM,WAAW,2BAA4B,SAAQ,yBAAyB,EAAE,aAAa;CAAG;AAEhG,MAAM,WAAW,sBAAuB,SAAQ,QAAQ,CACtD,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ,0FAA0F;AAC1F,eAAO,MAAM,sBAAsB,yDAA8D,CAAC;AA4DlG,eAAO,MAAM,8BAA8B,4IAIxC,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * PBS 4.2.6-1 notification operations, generated from its vendor schema in SDK 0.3.0.
3
+ *
4
+ * ★ Keep targetForm's selective secret groups and deletion semantics. The SDK schemas validate
5
+ * the spelling adapter before their typed operations encode it; no request shape is cast.
6
+ * Only the SDK's NotFound is absence. An unreadable target must stop adoption, not create it.
7
+ */
8
+ import * as config from '@distilled.cloud/proxmox-backup/config';
9
+ import type { ProxmoxBackupOpError } from '@distilled.cloud/proxmox-backup/Protocol';
10
+ import * as Effect from 'effect/Effect';
11
+ import type { PveForm } from './client.ts';
12
+ import type { PbsNotificationTargetProps as Props } from './pbs-notification-target.ts';
13
+ export declare const readTarget: (props: Props) => Effect.Effect<import("./pbs-notification-target.ts").PbsNotificationTargetAttributes | undefined, import("@distilled.cloud/caddy").BadGateway | import("@distilled.cloud/caddy").BadRequest | import("@distilled.cloud/caddy").ConfigError | import("@distilled.cloud/caddy").Conflict | Error | import("@distilled.cloud/caddy").Forbidden | import("@distilled.cloud/caddy").GatewayTimeout | import("effect/unstable/http/HttpClientError").HttpClientError | import("@distilled.cloud/caddy").InternalServerError | import("@distilled.cloud/caddy").Locked | import("@distilled.cloud/proxmox-backup/Errors").ParameterVerificationFailed | import("./credential-errors.ts").PveCredentialDenied | import("@distilled.cloud/caddy").ServiceUnavailable | import("effect/Cause").TimeoutError | import("@distilled.cloud/caddy").TooManyRequests | import("@distilled.cloud/caddy").Unauthorized | import("@distilled.cloud/caddy").UnprocessableEntity | import("@distilled.cloud/proxmox-backup/Errors").ClientErrors, import("effect/unstable/http/HttpClient").HttpClient>;
14
+ /** No request: run the same translated-input validation before replacement can delete anything. */
15
+ export declare const validateTargetWrite: (props: Props, form: PveForm, mode: 'create' | 'update') => Effect.Effect<void, import("./pbs-notification-input.ts").PbsNotificationInputRefusal, never>;
16
+ export declare const createTarget: (props: Props, form: PveForm) => Effect.Effect<config.CreateConfigNotificationEndpointSendmailResponse, Error | import("./pbs-notification-input.ts").PbsNotificationInputRefusal | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
17
+ export declare const updateTarget: (props: Props, form: PveForm) => Effect.Effect<config.PutConfigNotificationEndpointSendmailResponse, Error | import("./pbs-notification-input.ts").PbsNotificationInputRefusal | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
18
+ /** Built-ins still follow PBS's revert-on-delete semantics; missing objects are already deleted. */
19
+ export declare const deleteTarget: (props: Props) => Effect.Effect<void | config.DeleteConfigNotificationEndpointSendmailResponse, import("@distilled.cloud/caddy").BadGateway | import("@distilled.cloud/caddy").BadRequest | import("@distilled.cloud/caddy").ConfigError | import("@distilled.cloud/caddy").Conflict | Error | import("@distilled.cloud/caddy").Forbidden | import("@distilled.cloud/caddy").GatewayTimeout | import("effect/unstable/http/HttpClientError").HttpClientError | import("@distilled.cloud/caddy").InternalServerError | import("@distilled.cloud/caddy").Locked | import("@distilled.cloud/proxmox-backup/Errors").ParameterVerificationFailed | import("./credential-errors.ts").PveCredentialDenied | import("@distilled.cloud/caddy").ServiceUnavailable | import("effect/Cause").TimeoutError | import("@distilled.cloud/caddy").TooManyRequests | import("@distilled.cloud/caddy").Unauthorized | import("@distilled.cloud/caddy").UnprocessableEntity | import("@distilled.cloud/proxmox-backup/Errors").ClientErrors, import("effect/unstable/http/HttpClient").HttpClient>;
20
+ //# sourceMappingURL=pbs-notification-target-distilled.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-notification-target-distilled.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-target-distilled.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,MAAM,MAAM,wCAAwC,CAAC;AACjE,OAAO,KAAK,EAEV,oBAAoB,EACrB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,0BAA0B,IAAI,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAsCxF,eAAO,MAAM,UAAU,UAAW,KAAK,uhCAIpC,CAAC;AAEJ,mGAAmG;AACnG,eAAO,MAAM,mBAAmB,UAAW,KAAK,QAAQ,OAAO,QAAQ,QAAQ,GAAG,QAAQ,kGAczF,CAAC;AAEF,eAAO,MAAM,YAAY,UAAW,KAAK,QAAQ,OAAO,gUAevD,CAAC;AAEF,eAAO,MAAM,YAAY,UAAW,KAAK,QAAQ,OAAO,6TAevD,CAAC;AAEF,oGAAoG;AACpG,eAAO,MAAM,YAAY,UAAW,KAAK,mgCAWxC,CAAC"}
@@ -46,7 +46,7 @@ export declare const handlers: {
46
46
  header: string;
47
47
  headerDigest: string;
48
48
  secret: string;
49
- } | undefined, never, import("effect/unstable/http/HttpClient").HttpClient>;
49
+ } | undefined, import("@distilled.cloud/caddy").BadGateway | import("@distilled.cloud/caddy").BadRequest | import("@distilled.cloud/caddy").ConfigError | import("@distilled.cloud/caddy").Conflict | Error | import("@distilled.cloud/caddy").Forbidden | import("@distilled.cloud/caddy").GatewayTimeout | import("effect/unstable/http/HttpClientError").HttpClientError | import("@distilled.cloud/caddy").InternalServerError | import("@distilled.cloud/caddy").Locked | import("@distilled.cloud/proxmox-backup/Errors").ParameterVerificationFailed | import("./credential-errors.ts").PveCredentialDenied | import("@distilled.cloud/caddy").ServiceUnavailable | import("effect/Cause").TimeoutError | import("@distilled.cloud/caddy").TooManyRequests | import("@distilled.cloud/caddy").Unauthorized | import("@distilled.cloud/caddy").UnprocessableEntity | import("@distilled.cloud/proxmox-backup/Errors").ClientErrors, import("effect/unstable/http/HttpClient").HttpClient>;
50
50
  /**
51
51
  * ⚠️ `Input<Props>` and `isResolved`, resource.ts's reason: at plan time a prop can still be an
52
52
  * unresolved Output, and comparing a placeholder to a live value reports a phantom update.
@@ -66,7 +66,7 @@ export declare const handlers: {
66
66
  } | {
67
67
  readonly deleteFirst?: never;
68
68
  readonly action: 'noop';
69
- } | undefined, never, import("effect/unstable/http/HttpClient").HttpClient>;
69
+ } | undefined, Error | import("effect/unstable/http/HttpClientError").HttpClientError | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
70
70
  reconcile: ({ news, output }: {
71
71
  news: Props;
72
72
  output: Attributes | undefined;
@@ -91,10 +91,10 @@ export declare const handlers: {
91
91
  header: string;
92
92
  headerDigest: string;
93
93
  secret: string;
94
- }, Error | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
94
+ }, Error | import("effect/unstable/http/HttpClientError").HttpClientError | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
95
95
  delete: ({ olds }: {
96
96
  olds: Props;
97
- }) => Effect.Effect<unknown, Error | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
97
+ }) => Effect.Effect<void | import("@distilled.cloud/proxmox-backup/config").DeleteConfigNotificationEndpointSendmailResponse, import("@distilled.cloud/caddy").BadGateway | import("@distilled.cloud/caddy").BadRequest | import("@distilled.cloud/caddy").ConfigError | import("@distilled.cloud/caddy").Conflict | Error | import("@distilled.cloud/caddy").Forbidden | import("@distilled.cloud/caddy").GatewayTimeout | import("effect/unstable/http/HttpClientError").HttpClientError | import("@distilled.cloud/caddy").InternalServerError | import("@distilled.cloud/caddy").Locked | import("@distilled.cloud/proxmox-backup/Errors").ParameterVerificationFailed | import("./credential-errors.ts").PveCredentialDenied | import("@distilled.cloud/caddy").ServiceUnavailable | import("effect/Cause").TimeoutError | import("@distilled.cloud/caddy").TooManyRequests | import("@distilled.cloud/caddy").Unauthorized | import("@distilled.cloud/caddy").UnprocessableEntity | import("@distilled.cloud/proxmox-backup/Errors").ClientErrors, import("effect/unstable/http/HttpClient").HttpClient>;
98
98
  };
99
99
  export {};
100
100
  //# sourceMappingURL=pbs-notification-target-lifecycle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pbs-notification-target-lifecycle.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-target-lifecycle.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAIxC,OAAO,KAAK,EACV,+BAA+B,EAC/B,0BAA0B,EAC3B,MAAM,8BAA8B,CAAC;AActC,KAAK,KAAK,GAAG,0BAA0B,CAAC;AACxC,KAAK,UAAU,GAAG,+BAA+B,CAAC;AA8ClD,eAAO,MAAM,QAAQ;IACnB,kGAAkG;IAClG,IAAI;IACJ;;;;;;;;;;;;;;;OAeG;IACH,IAAI,qBAAqB;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;IAOxE;;;;;OAKG;IACH,IAAI,4BAID;QACD,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,EAAE,KAAK,CAAC;QACZ,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;KAChC;yBAIsB,SAAS;;;;yBAIa,QAAQ;;;yBAElC,MAAM;;IAGzB,SAAS,qBAAqB;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;IAyC7E,MAAM,aAAa;QAAE,IAAI,EAAE,KAAK,CAAA;KAAE;CACnC,CAAC"}
1
+ {"version":3,"file":"pbs-notification-target-lifecycle.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-target-lifecycle.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAUxC,OAAO,KAAK,EACV,+BAA+B,EAC/B,0BAA0B,EAC3B,MAAM,8BAA8B,CAAC;AAatC,KAAK,KAAK,GAAG,0BAA0B,CAAC;AACxC,KAAK,UAAU,GAAG,+BAA+B,CAAC;AAoClD,eAAO,MAAM,QAAQ;IACnB,kGAAkG;IAClG,IAAI;IACJ;;;;;;;;;;;;;;;OAeG;IACH,IAAI,qBAAqB;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;IAOxE;;;;;OAKG;IACH,IAAI,4BAID;QACD,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,EAAE,KAAK,CAAC;QACZ,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;KAChC;yBAoBsB,SAAS;;;;yBAGa,QAAQ;;;yBAElC,MAAM;;IAGzB,SAAS,qBAAqB;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;IAwC7E,MAAM,aAAa;QAAE,IAAI,EAAE,KAAK,CAAA;KAAE;CACnC,CAAC"}
@@ -24,7 +24,7 @@
24
24
  * the consequence. Read `origin` before declaring a name you did not create.
25
25
  *
26
26
  * ★ WHAT THIS NEEDS (generated/pbs.ts source): Sys.Audit on /system/notifications to read,
27
- * Sys.Modify there to write. A datastore-scoped credential reads every target as absent.
27
+ * Sys.Modify there to write. A datastore-scoped credential cannot read targets; its typed refusal now fails the plan.
28
28
  */
29
29
  import { Resource } from 'alchemy';
30
30
  import * as Provider from 'alchemy/Provider';
@@ -0,0 +1,22 @@
1
+ import type { Input } from 'alchemy/Input';
2
+ import * as Effect from 'effect/Effect';
3
+ import type { PruneJobAttributes, PruneJobProps } from './pbs-prune-job.ts';
4
+ export declare const handlers: {
5
+ list: () => Effect.Effect<never[], never, never>;
6
+ read: ({ olds }: {
7
+ olds: PruneJobProps;
8
+ }) => Effect.Effect<PruneJobAttributes | undefined, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | import("@distilled.cloud/proxmox-backup/Protocol").ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
9
+ diff: ({ news, output, }: {
10
+ news: Input<PruneJobProps>;
11
+ output: PruneJobAttributes | undefined;
12
+ }) => Effect.Effect<{
13
+ readonly action: "noop" | "update";
14
+ } | undefined, Error | import("effect/unstable/http/HttpClientError").HttpClientError | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
15
+ reconcile: ({ news }: {
16
+ news: PruneJobProps;
17
+ }) => Effect.Effect<PruneJobAttributes, Error | import("effect/unstable/http/HttpClientError").HttpClientError | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
18
+ delete: ({ olds }: {
19
+ olds: PruneJobProps;
20
+ }) => Effect.Effect<import("@distilled.cloud/proxmox-backup/config").DeleteConfigPruneResponse | undefined, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | import("@distilled.cloud/proxmox-backup/Protocol").ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
21
+ };
22
+ //# sourceMappingURL=pbs-prune-job-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-prune-job-lifecycle.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-prune-job-lifecycle.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAM5E,eAAO,MAAM,QAAQ;IAEnB,IAAI;IACJ,IAAI,aAAa;QAAE,IAAI,EAAE,aAAa,CAAA;KAAE;IACxC,IAAI,sBAGD;QACD,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;QAC3B,MAAM,EAAE,kBAAkB,GAAG,SAAS,CAAC;KACxC;;;IAaD,SAAS,aAAa;QAAE,IAAI,EAAE,aAAa,CAAA;KAAE;IAgB7C,MAAM,aAAa;QAAE,IAAI,EAAE,aAAa,CAAA;KAAE;CAC3C,CAAC"}
@@ -0,0 +1,5 @@
1
+ /** PBS 4.2.6-1 values and vendor form guards; SDK transport is in pbs-prune-job-wire.ts. */
2
+ import type { PruneJobAttributes, PruneJobProps } from './pbs-prune-job.ts';
3
+ import type { PveSpec } from './resource-spec.ts';
4
+ export declare const spec: PveSpec<PruneJobProps, PruneJobAttributes>;
5
+ //# sourceMappingURL=pbs-prune-job-spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-prune-job-spec.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-prune-job-spec.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAOlD,eAAO,MAAM,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,kBAAkB,CA2C3D,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** PBS 4.2.6-1 operations through @distilled.cloud/proxmox-backup. */
2
+ import * as config from '@distilled.cloud/proxmox-backup/config';
3
+ import * as Effect from 'effect/Effect';
4
+ import type { PruneJobProps } from './pbs-prune-job.ts';
5
+ /** ⛔ Only the SDK PruneJobNotFound is absence; permission, transport and malformed replies propagate. */
6
+ export declare const readOne: (props: PruneJobProps) => Effect.Effect<import("./pbs-prune-job.ts").PruneJobAttributes | undefined, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | config.ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
7
+ export declare const createOne: (props: PruneJobProps) => Effect.Effect<config.CreateConfigPruneResponse, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | config.ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
8
+ export declare const updateOne: (props: PruneJobProps) => Effect.Effect<config.PutConfigPruneResponse, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | config.ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
9
+ /** Deleting the schedule never deletes backups; already missing is a successful deletion. */
10
+ export declare const deleteOne: (props: PruneJobProps) => Effect.Effect<config.DeleteConfigPruneResponse | undefined, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | config.ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
11
+ //# sourceMappingURL=pbs-prune-job-wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-prune-job-wire.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-prune-job-wire.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,KAAK,MAAM,MAAM,wCAAwC,CAAC;AACjE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA4CxD,yGAAyG;AACzG,eAAO,MAAM,OAAO,UAAW,aAAa,uQAIzC,CAAC;AAEJ,eAAO,MAAM,SAAS,UAAW,aAAa,4OACqC,CAAC;AAEpF,eAAO,MAAM,SAAS,UAAW,aAAa,yOACkC,CAAC;AAEjF,6FAA6F;AAC7F,eAAO,MAAM,SAAS,UAAW,aAAa,wPAK1C,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * `Pbs.PruneJob` — a Proxmox Backup Server retention schedule, declared. PBS is a SIBLING of PVE,
3
- * so this family reuses `pveHandlers` wholesale rather than growing a second factory.
3
+ * and this family uses its own distilled SDK's typed config operations (PBS 4.2.6-1).
4
4
  *
5
5
  * ⛔ THIS IS THE ONE RESOURCE IN THIS PACKAGE THAT DESTROYS DATA ON AN ORDINARY *UPDATE*. CephPool,
6
6
  * ZfsPool and Storage can destroy data too — which is exactly why they default to `retain` and
@@ -26,8 +26,9 @@
26
26
  * `-1` in the attributes means "absent from prune.cfg", the sentinel storage.ts uses for
27
27
  * `maxfiles`, because `0` here is a real and very different setting.
28
28
  *
29
- * ⛔ THE CREDENTIAL DOES NOT EXIST YET, SO NOTHING BELOW HAS EVER MADE A CALL. PBS is a different
30
- * host and a different auth realm from PVE. MEASURED 2026-09-13: pbs.example.com:8007 answers
29
+ * ⚠️ HISTORICAL BOOTSTRAP BLOCKER, 2026-09-13: PBS was a different
30
+ * host and auth realm from PVE. The later PBS credential lane and SDK resolved this blocker.
31
+ * MEASURED 2026-09-13: pbs.example.com:8007 answers
31
32
  * HTTP 401 under STRICT TLS behind a real Let's Encrypt certificate (CN=pbs.example.com, issuer
32
33
  * YR1, valid 2026-09-02 to 2026-12-01) — so there is no `-k` to reach for and `client.ts` needs
33
34
  * no TLS escape hatch, exactly as on PVE. What it does need is a header it cannot build today.
@@ -47,7 +48,7 @@
47
48
  * ★ WHAT A `PbsTarget` NEEDS, AND WHY IT IS ALMOST `PveTarget`. Structurally `PveTarget` already
48
49
  * fits a PBS host: a credential mount name and an `/api2/json` base are the whole of it, and PBS
49
50
  * shares the `{"data": …}` envelope, the four-operation shape and the read-back discipline —
50
- * which is exactly why this file declares a spec and stops. The single thing `PveTarget` cannot
51
+ * which is why the pure spec survives the SDK transport migration. The single thing `PveTarget` cannot
51
52
  * carry is WHICH AUTHORIZATION SCHEME the host at the other end speaks, so `PbsTarget` below adds
52
53
  * that and nothing else rather than bending the PVE type in silence.
53
54
  *
@@ -55,9 +56,9 @@
55
56
  * below are MEASURED from the PBS API as published at pbs.proxmox.com/docs/api-viewer, fetched
56
57
  * 2026-09-13 — current PBS 4.x. Before PBS 2.2 there was no `/config/prune` at all: retention
57
58
  * lived on the datastore section itself, as `keep-*` plus `prune-schedule` under
58
- * `/config/datastore/{name}`. Against anything older every path here 404s, `pveOperations.read`
59
- * folds that into "absent", and the plan says create forever. Check `GET /api2/json/version`
60
- * before the first plan.
59
+ * `/config/datastore/{name}`. The old `pveOperations.read` folded those 404s into "absent",
60
+ * producing a create forever. The SDK path now propagates an unknown route's 404; only the
61
+ * vendor's typed missing-prune response means absent. Check the PBS version before planning.
61
62
  *
62
63
  * ★ THE READ LANE NEEDS NOTHING EXTRA, UNLIKE THREE PVE FAMILIES — so there is no `readRole:
63
64
  * 'provision'` below and there should not be one. MEASURED: `GET /config/prune/{id}` requires
@@ -79,7 +80,7 @@
79
80
  import { Resource } from 'alchemy';
80
81
  import * as Provider from 'alchemy/Provider';
81
82
  import type { PbsTarget } from './credentials.ts';
82
- import { type PveRequirements, type WithPbsTarget } from './resource.ts';
83
+ import type { PveRequirements, WithPbsTarget } from './resource-spec.ts';
83
84
  /**
84
85
  * ⚠️ THE PROPS ARE PBS'S OWN KEY NAMES, HYPHENS INCLUDED, for backup-job.ts's reason: the form
85
86
  * builder is then a copy rather than a translation table, and a translation table is one more
@@ -1 +1 @@
1
- {"version":3,"file":"pbs-prune-job.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-prune-job.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6EG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAe,MAAM,eAAe,CAAC;AAGtF;;;;;GAKG;AACH,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,uFAAuF;IACvF,MAAM,EAAE,SAAS,CAAC;IAClB;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;+FAC2F;IAC3F,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,iGAAiG;IACjG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;gGAC4F;IAC5F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,mGAAmG;IACnG,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,8FAA8F;IAC9F,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAY,SAAQ,QAAQ,CAC3C,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ;;;;GAIG;AACH,eAAO,MAAM,WAAW,8CAAwC,CAAC;AAkDjE;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mBAAmB,iIACiD,CAAC"}
1
+ {"version":3,"file":"pbs-prune-job.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-prune-job.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAG7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,uFAAuF;IACvF,MAAM,EAAE,SAAS,CAAC;IAClB;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;+FAC2F;IAC3F,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,iGAAiG;IACjG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;gGAC4F;IAC5F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,mGAAmG;IACnG,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,8FAA8F;IAC9F,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAY,SAAQ,QAAQ,CAC3C,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ;;;;GAIG;AACH,eAAO,MAAM,WAAW,8CAAwC,CAAC;AAEjE;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mBAAmB,iIACiD,CAAC"}
@@ -0,0 +1,34 @@
1
+ /** Stable PBS sync-job state; only vendor configuration, never runtime task status. */
2
+ export interface SyncJobAttributes {
3
+ /** From the props — it is the path this object was read by. */
4
+ id: string;
5
+ store: string;
6
+ /** `''` is the root namespace, which is also how PBS spells it. */
7
+ ns: string;
8
+ /** `''` means a LOCAL sync — datastore to datastore on this PBS. */
9
+ remote: string;
10
+ 'remote-store': string;
11
+ 'remote-ns': string;
12
+ /** `''` means the job runs only when somebody starts it. */
13
+ schedule: string;
14
+ comment: string;
15
+ 'remove-vanished': boolean;
16
+ /** ⚠️ Absent on the wire means `false`, PBS's own default. */
17
+ 'verified-only': boolean;
18
+ /** `''` means no owner in the config, i.e. `root@pam` at runtime. An identifier, never a secret. */
19
+ owner: string;
20
+ /** Bytes per second, or `UNSET` (-1). See `bytes()`. */
21
+ 'rate-in': number;
22
+ /** `UNSET` (-1) means unset, which means full recursion. `0` is a real value meaning none. */
23
+ 'max-depth': number;
24
+ /** `UNSET` (-1) means all snapshots. */
25
+ 'transfer-last': number;
26
+ /**
27
+ * ⚠️ REPORTED, NEVER SENT, NEVER COMPARED — the live filter list joined for display only. See the
28
+ * ⛔ on the prop for why it is not declarable.
29
+ */
30
+ 'group-filter': string;
31
+ /** `pull` or `push`. Reported, never compared — create-only here. */
32
+ 'sync-direction': string;
33
+ }
34
+ //# sourceMappingURL=pbs-sync-job-attributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-sync-job-attributes.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-sync-job-attributes.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,8DAA8D;IAC9D,eAAe,EAAE,OAAO,CAAC;IACzB,oGAAoG;IACpG,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,8FAA8F;IAC9F,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,CAAC;CAC1B"}
@@ -1,4 +1,24 @@
1
1
  import type { SyncJobAttributes, SyncJobProps } from './pbs-sync-job.ts';
2
+ /**
3
+ * A sync job on the wire: how a PBS answer becomes comparable values, how a declaration becomes a
4
+ * create or an update, and — because that question is downstream of this one — when it has changed.
5
+ *
6
+ * ★ SPLIT OUT OF pbs-sync-job.ts FOR THE 250-LINE CAP; the ★ SEAM there says why `matches` came
7
+ * with the wire instead of staying with the props. The `import type` back is a cycle on paper
8
+ * only — erased before anything runs, so the runtime arrow points one way, resource to wire.
9
+ *
10
+ * ★ HISTORICALLY IT USED THE SHARED PVE CLIENT, NOT A PBS ONE. An earlier draft of this file was written
11
+ * against a `./pbs-client.ts` that never existed, and spelled out what it would have to export.
12
+ * That module is not needed: PBS speaks the same `/api2/json` paths and the same `{"data": …}`
13
+ * envelope, its OpenBao mount vends the same `{token_id, secret}`, and the only difference is
14
+ * the authorization header — so `PveTarget` carries a `scheme` and `authorization()` spells
15
+ * `PBSAPIToken=<id>:<secret>` for `'pbs'`. The SDK now owns that header; the pure spec below
16
+ * preserves the existing field and retention semantics.
17
+ * The one PBS-specific thing that survived is the FORM TYPE: PBS decodes a multi-valued field
18
+ * from repeated keys, and the distilled PBS protocol must preserve that encoding.
19
+
20
+ */
21
+ import type { PveSpec } from './resource-spec.ts';
2
22
  /**
3
23
  * The marker for "PBS has no value for this number".
4
24
  *
@@ -58,26 +78,5 @@ export declare const createBody: (props: SyncJobProps) => Record<string, string>
58
78
  * there rather than a change.
59
79
  */
60
80
  export declare const updateBody: (props: SyncJobProps) => Record<string, string>;
61
- export declare const handlers: {
62
- list: () => import("effect/Effect").Effect<never[], never, never>;
63
- read: ({ olds }: {
64
- olds: SyncJobProps;
65
- }) => import("effect/Effect").Effect<SyncJobAttributes | undefined, never, import("effect/unstable/http/HttpClient").HttpClient>;
66
- diff: ({ news, output }: {
67
- news: import("alchemy").Input<SyncJobProps>;
68
- output: SyncJobAttributes | undefined;
69
- }) => import("effect/Effect").Effect<{
70
- readonly action: 'update';
71
- } | {
72
- readonly action: 'noop';
73
- } | {
74
- readonly action: 'replace';
75
- } | undefined, never, import("effect/unstable/http/HttpClient").HttpClient>;
76
- reconcile: ({ news }: {
77
- news: SyncJobProps;
78
- }) => import("effect/Effect").Effect<SyncJobAttributes, Error | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
79
- delete: ({ olds }: {
80
- olds: SyncJobProps;
81
- }) => import("effect/Effect").Effect<unknown, Error | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
82
- };
81
+ export declare const spec: PveSpec<SyncJobProps, SyncJobAttributes>;
83
82
  //# sourceMappingURL=pbs-sync-job-form.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pbs-sync-job-form.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-sync-job-form.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAsBzE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,KAAK,CAAC;AAgBxB;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,KAAK,UAAW,OAAO,KAAG,MAOtC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,UAAW,OAAO,KAAG,MACsD,CAAC;AA0ChG;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,UAAW,YAAY,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAIpE,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,UAAW,YAAY,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAiB,CAAC;AAExF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;CAmFnB,CAAC"}
1
+ {"version":3,"file":"pbs-sync-job-form.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-sync-job-form.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACzE;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGlD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,KAAK,CAAC;AAgBxB;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,KAAK,UAAW,OAAO,KAAG,MAOtC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,UAAW,OAAO,KAAG,MACsD,CAAC;AA0ChG;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,UAAW,YAAY,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAIpE,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,UAAW,YAAY,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAiB,CAAC;AAExF,eAAO,MAAM,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,iBAAiB,CAmFzD,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { Input } from 'alchemy/Input';
2
+ import * as Effect from 'effect/Effect';
3
+ import type { SyncJobAttributes, SyncJobProps } from './pbs-sync-job.ts';
4
+ export declare const handlers: {
5
+ list: () => Effect.Effect<never[], never, never>;
6
+ read: ({ olds }: {
7
+ olds: SyncJobProps;
8
+ }) => Effect.Effect<SyncJobAttributes | undefined, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | import("@distilled.cloud/proxmox-backup/Protocol").ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
9
+ diff: ({ news, output }: {
10
+ news: Input<SyncJobProps>;
11
+ output: SyncJobAttributes | undefined;
12
+ }) => Effect.Effect<{
13
+ readonly action: "noop" | "update";
14
+ } | undefined, Error | import("effect/unstable/http/HttpClientError").HttpClientError | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
15
+ reconcile: ({ news }: {
16
+ news: SyncJobProps;
17
+ }) => Effect.Effect<SyncJobAttributes, Error | import("effect/unstable/http/HttpClientError").HttpClientError | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
18
+ delete: ({ olds }: {
19
+ olds: SyncJobProps;
20
+ }) => Effect.Effect<import("@distilled.cloud/proxmox-backup/config").DeleteConfigSyncResponse | undefined, Error | import("./credential-errors.ts").PveCredentialDenied | import("effect/Cause").TimeoutError | import("@distilled.cloud/proxmox-backup/Protocol").ProxmoxBackupOpError, import("effect/unstable/http/HttpClient").HttpClient>;
21
+ };
22
+ //# sourceMappingURL=pbs-sync-job-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-sync-job-lifecycle.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-sync-job-lifecycle.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAMzE,eAAO,MAAM,QAAQ;IAEnB,IAAI;IACJ,IAAI,aAAa;QAAE,IAAI,EAAE,YAAY,CAAA;KAAE;IACvC,IAAI,qBAAqB;QAAE,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;QAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAA;KAAE;;;IAa7F,SAAS,aAAa;QAAE,IAAI,EAAE,YAAY,CAAA;KAAE;IAgB5C,MAAM,aAAa;QAAE,IAAI,EAAE,YAAY,CAAA;KAAE;CAC1C,CAAC"}