@homeflare/alchemy 0.1.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 (417) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/dist/cloudflare/client.d.ts +45 -0
  4. package/dist/cloudflare/client.d.ts.map +1 -0
  5. package/dist/cloudflare/index.d.ts +11 -0
  6. package/dist/cloudflare/index.d.ts.map +1 -0
  7. package/dist/cloudflare/index.js +129 -0
  8. package/dist/cloudflare/index.js.map +13 -0
  9. package/dist/cloudflare/lock-rules.d.ts +50 -0
  10. package/dist/cloudflare/lock-rules.d.ts.map +1 -0
  11. package/dist/cloudflare/providers.d.ts +19 -0
  12. package/dist/cloudflare/providers.d.ts.map +1 -0
  13. package/dist/cloudflare/r2-bucket-lock.d.ts +100 -0
  14. package/dist/cloudflare/r2-bucket-lock.d.ts.map +1 -0
  15. package/dist/forgejo/branch-protection-form.d.ts +19 -0
  16. package/dist/forgejo/branch-protection-form.d.ts.map +1 -0
  17. package/dist/forgejo/branch-protection.d.ts +47 -0
  18. package/dist/forgejo/branch-protection.d.ts.map +1 -0
  19. package/dist/forgejo/client.d.ts +37 -0
  20. package/dist/forgejo/client.d.ts.map +1 -0
  21. package/dist/forgejo/index.d.ts +18 -0
  22. package/dist/forgejo/index.d.ts.map +1 -0
  23. package/dist/forgejo/index.js +479 -0
  24. package/dist/forgejo/index.js.map +21 -0
  25. package/dist/forgejo/org-actions-secrets.d.ts +45 -0
  26. package/dist/forgejo/org-actions-secrets.d.ts.map +1 -0
  27. package/dist/forgejo/org-label.d.ts +46 -0
  28. package/dist/forgejo/org-label.d.ts.map +1 -0
  29. package/dist/forgejo/org-team.d.ts +42 -0
  30. package/dist/forgejo/org-team.d.ts.map +1 -0
  31. package/dist/forgejo/repo-webhook-form.d.ts +27 -0
  32. package/dist/forgejo/repo-webhook-form.d.ts.map +1 -0
  33. package/dist/forgejo/repo-webhook.d.ts +46 -0
  34. package/dist/forgejo/repo-webhook.d.ts.map +1 -0
  35. package/dist/forgejo/repository.d.ts +45 -0
  36. package/dist/forgejo/repository.d.ts.map +1 -0
  37. package/dist/forgejo/resource.d.ts +83 -0
  38. package/dist/forgejo/resource.d.ts.map +1 -0
  39. package/dist/forgejo/team-member.d.ts +39 -0
  40. package/dist/forgejo/team-member.d.ts.map +1 -0
  41. package/dist/forgejo/values.d.ts +24 -0
  42. package/dist/forgejo/values.d.ts.map +1 -0
  43. package/dist/index.d.ts +18 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +3 -0
  46. package/dist/index.js.map +9 -0
  47. package/dist/openbao/auth-role-form.d.ts +38 -0
  48. package/dist/openbao/auth-role-form.d.ts.map +1 -0
  49. package/dist/openbao/auth-role.d.ts +20 -0
  50. package/dist/openbao/auth-role.d.ts.map +1 -0
  51. package/dist/openbao/bao-address.d.ts +72 -0
  52. package/dist/openbao/bao-address.d.ts.map +1 -0
  53. package/dist/openbao/bao-http.d.ts +71 -0
  54. package/dist/openbao/bao-http.d.ts.map +1 -0
  55. package/dist/openbao/bao-status.d.ts +74 -0
  56. package/dist/openbao/bao-status.d.ts.map +1 -0
  57. package/dist/openbao/cloudflare-group-scope.d.ts +73 -0
  58. package/dist/openbao/cloudflare-group-scope.d.ts.map +1 -0
  59. package/dist/openbao/cloudflare-parity-catalog.d.ts +28 -0
  60. package/dist/openbao/cloudflare-parity-catalog.d.ts.map +1 -0
  61. package/dist/openbao/cloudflare-parity-snapshot.d.ts +31 -0
  62. package/dist/openbao/cloudflare-parity-snapshot.d.ts.map +1 -0
  63. package/dist/openbao/cloudflare-parity.d.ts +14 -0
  64. package/dist/openbao/cloudflare-parity.d.ts.map +1 -0
  65. package/dist/openbao/cloudflare-permission-groups-solve.d.ts +85 -0
  66. package/dist/openbao/cloudflare-permission-groups-solve.d.ts.map +1 -0
  67. package/dist/openbao/cloudflare-permission-groups.d.ts +87 -0
  68. package/dist/openbao/cloudflare-permission-groups.d.ts.map +1 -0
  69. package/dist/openbao/cloudflare-policy.d.ts +65 -0
  70. package/dist/openbao/cloudflare-policy.d.ts.map +1 -0
  71. package/dist/openbao/cloudflare-role-form.d.ts +110 -0
  72. package/dist/openbao/cloudflare-role-form.d.ts.map +1 -0
  73. package/dist/openbao/cloudflare-role-wire.d.ts +27 -0
  74. package/dist/openbao/cloudflare-role-wire.d.ts.map +1 -0
  75. package/dist/openbao/cloudflare-role.d.ts +35 -0
  76. package/dist/openbao/cloudflare-role.d.ts.map +1 -0
  77. package/dist/openbao/cloudflare-roles-config.d.ts +67 -0
  78. package/dist/openbao/cloudflare-roles-config.d.ts.map +1 -0
  79. package/dist/openbao/cloudflare-roles-expand.d.ts +76 -0
  80. package/dist/openbao/cloudflare-roles-expand.d.ts.map +1 -0
  81. package/dist/openbao/digest.d.ts +24 -0
  82. package/dist/openbao/digest.d.ts.map +1 -0
  83. package/dist/openbao/fake-bao.d.ts +40 -0
  84. package/dist/openbao/fake-bao.d.ts.map +1 -0
  85. package/dist/openbao/forgejo-bootstrap-parse.d.ts +46 -0
  86. package/dist/openbao/forgejo-bootstrap-parse.d.ts.map +1 -0
  87. package/dist/openbao/forgejo-bootstrap.d.ts +29 -0
  88. package/dist/openbao/forgejo-bootstrap.d.ts.map +1 -0
  89. package/dist/openbao/index.d.ts +18 -0
  90. package/dist/openbao/index.d.ts.map +1 -0
  91. package/dist/openbao/index.js +1158 -0
  92. package/dist/openbao/index.js.map +33 -0
  93. package/dist/openbao/mount-form.d.ts +60 -0
  94. package/dist/openbao/mount-form.d.ts.map +1 -0
  95. package/dist/openbao/mount-wire.d.ts +24 -0
  96. package/dist/openbao/mount-wire.d.ts.map +1 -0
  97. package/dist/openbao/mount.d.ts +20 -0
  98. package/dist/openbao/mount.d.ts.map +1 -0
  99. package/dist/openbao/pki-role-form.d.ts +118 -0
  100. package/dist/openbao/pki-role-form.d.ts.map +1 -0
  101. package/dist/openbao/pki-role.d.ts +50 -0
  102. package/dist/openbao/pki-role.d.ts.map +1 -0
  103. package/dist/openbao/policy-assembly.d.ts +13 -0
  104. package/dist/openbao/policy-assembly.d.ts.map +1 -0
  105. package/dist/openbao/policy-wire.d.ts +41 -0
  106. package/dist/openbao/policy-wire.d.ts.map +1 -0
  107. package/dist/openbao/policy.d.ts +83 -0
  108. package/dist/openbao/policy.d.ts.map +1 -0
  109. package/dist/openbao/proxmox-role-form.d.ts +92 -0
  110. package/dist/openbao/proxmox-role-form.d.ts.map +1 -0
  111. package/dist/openbao/proxmox-role.d.ts +47 -0
  112. package/dist/openbao/proxmox-role.d.ts.map +1 -0
  113. package/dist/openbao/ssh-role-form.d.ts +99 -0
  114. package/dist/openbao/ssh-role-form.d.ts.map +1 -0
  115. package/dist/openbao/ssh-role.d.ts +43 -0
  116. package/dist/openbao/ssh-role.d.ts.map +1 -0
  117. package/dist/proxmox/acl.d.ts +72 -0
  118. package/dist/proxmox/acl.d.ts.map +1 -0
  119. package/dist/proxmox/api-token-form.d.ts +59 -0
  120. package/dist/proxmox/api-token-form.d.ts.map +1 -0
  121. package/dist/proxmox/api-token.d.ts +159 -0
  122. package/dist/proxmox/api-token.d.ts.map +1 -0
  123. package/dist/proxmox/backup-job.d.ts +112 -0
  124. package/dist/proxmox/backup-job.d.ts.map +1 -0
  125. package/dist/proxmox/ceph-daemon-form.d.ts +70 -0
  126. package/dist/proxmox/ceph-daemon-form.d.ts.map +1 -0
  127. package/dist/proxmox/ceph-daemon.d.ts +162 -0
  128. package/dist/proxmox/ceph-daemon.d.ts.map +1 -0
  129. package/dist/proxmox/ceph-flag.d.ts +131 -0
  130. package/dist/proxmox/ceph-flag.d.ts.map +1 -0
  131. package/dist/proxmox/ceph-fs-wire.d.ts +106 -0
  132. package/dist/proxmox/ceph-fs-wire.d.ts.map +1 -0
  133. package/dist/proxmox/ceph-fs.d.ts +124 -0
  134. package/dist/proxmox/ceph-fs.d.ts.map +1 -0
  135. package/dist/proxmox/ceph-osd-tree.d.ts +154 -0
  136. package/dist/proxmox/ceph-osd-tree.d.ts.map +1 -0
  137. package/dist/proxmox/ceph-osd-write.d.ts +36 -0
  138. package/dist/proxmox/ceph-osd-write.d.ts.map +1 -0
  139. package/dist/proxmox/ceph-osd.d.ts +102 -0
  140. package/dist/proxmox/ceph-osd.d.ts.map +1 -0
  141. package/dist/proxmox/ceph-pool-form.d.ts +217 -0
  142. package/dist/proxmox/ceph-pool-form.d.ts.map +1 -0
  143. package/dist/proxmox/ceph-pool-settle.d.ts +39 -0
  144. package/dist/proxmox/ceph-pool-settle.d.ts.map +1 -0
  145. package/dist/proxmox/ceph-pool.d.ts +48 -0
  146. package/dist/proxmox/ceph-pool.d.ts.map +1 -0
  147. package/dist/proxmox/client.d.ts +64 -0
  148. package/dist/proxmox/client.d.ts.map +1 -0
  149. package/dist/proxmox/credentials.d.ts +153 -0
  150. package/dist/proxmox/credentials.d.ts.map +1 -0
  151. package/dist/proxmox/firewall-alias-form.d.ts +98 -0
  152. package/dist/proxmox/firewall-alias-form.d.ts.map +1 -0
  153. package/dist/proxmox/firewall-alias.d.ts +141 -0
  154. package/dist/proxmox/firewall-alias.d.ts.map +1 -0
  155. package/dist/proxmox/generated/pbs.d.ts +388 -0
  156. package/dist/proxmox/generated/pbs.d.ts.map +1 -0
  157. package/dist/proxmox/generated/pve.d.ts +4713 -0
  158. package/dist/proxmox/generated/pve.d.ts.map +1 -0
  159. package/dist/proxmox/group.d.ts +104 -0
  160. package/dist/proxmox/group.d.ts.map +1 -0
  161. package/dist/proxmox/ha-resource.d.ts +104 -0
  162. package/dist/proxmox/ha-resource.d.ts.map +1 -0
  163. package/dist/proxmox/ha-rule-form.d.ts +103 -0
  164. package/dist/proxmox/ha-rule-form.d.ts.map +1 -0
  165. package/dist/proxmox/ha-rule.d.ts +156 -0
  166. package/dist/proxmox/ha-rule.d.ts.map +1 -0
  167. package/dist/proxmox/index.d.ts +43 -0
  168. package/dist/proxmox/index.d.ts.map +1 -0
  169. package/dist/proxmox/index.js +2322 -0
  170. package/dist/proxmox/index.js.map +70 -0
  171. package/dist/proxmox/lease-cache.d.ts +98 -0
  172. package/dist/proxmox/lease-cache.d.ts.map +1 -0
  173. package/dist/proxmox/lxc.d.ts +59 -0
  174. package/dist/proxmox/lxc.d.ts.map +1 -0
  175. package/dist/proxmox/members.d.ts +56 -0
  176. package/dist/proxmox/members.d.ts.map +1 -0
  177. package/dist/proxmox/metric-server-form.d.ts +53 -0
  178. package/dist/proxmox/metric-server-form.d.ts.map +1 -0
  179. package/dist/proxmox/metric-server-otel.d.ts +49 -0
  180. package/dist/proxmox/metric-server-otel.d.ts.map +1 -0
  181. package/dist/proxmox/metric-server.d.ts +123 -0
  182. package/dist/proxmox/metric-server.d.ts.map +1 -0
  183. package/dist/proxmox/network-apply-read.d.ts +93 -0
  184. package/dist/proxmox/network-apply-read.d.ts.map +1 -0
  185. package/dist/proxmox/network-apply.d.ts +102 -0
  186. package/dist/proxmox/network-apply.d.ts.map +1 -0
  187. package/dist/proxmox/node-network-form.d.ts +128 -0
  188. package/dist/proxmox/node-network-form.d.ts.map +1 -0
  189. package/dist/proxmox/node-network.d.ts +173 -0
  190. package/dist/proxmox/node-network.d.ts.map +1 -0
  191. package/dist/proxmox/notification-target-form.d.ts +44 -0
  192. package/dist/proxmox/notification-target-form.d.ts.map +1 -0
  193. package/dist/proxmox/notification-target.d.ts +146 -0
  194. package/dist/proxmox/notification-target.d.ts.map +1 -0
  195. package/dist/proxmox/pbs-datastore-form.d.ts +147 -0
  196. package/dist/proxmox/pbs-datastore-form.d.ts.map +1 -0
  197. package/dist/proxmox/pbs-datastore-guard.d.ts +55 -0
  198. package/dist/proxmox/pbs-datastore-guard.d.ts.map +1 -0
  199. package/dist/proxmox/pbs-datastore.d.ts +140 -0
  200. package/dist/proxmox/pbs-datastore.d.ts.map +1 -0
  201. package/dist/proxmox/pbs-prune-job-form.d.ts +97 -0
  202. package/dist/proxmox/pbs-prune-job-form.d.ts.map +1 -0
  203. package/dist/proxmox/pbs-prune-job.d.ts +168 -0
  204. package/dist/proxmox/pbs-prune-job.d.ts.map +1 -0
  205. package/dist/proxmox/pbs-sync-job-form.d.ts +83 -0
  206. package/dist/proxmox/pbs-sync-job-form.d.ts.map +1 -0
  207. package/dist/proxmox/pbs-sync-job.d.ts +246 -0
  208. package/dist/proxmox/pbs-sync-job.d.ts.map +1 -0
  209. package/dist/proxmox/pbs-verify-job-form.d.ts +114 -0
  210. package/dist/proxmox/pbs-verify-job-form.d.ts.map +1 -0
  211. package/dist/proxmox/pbs-verify-job.d.ts +145 -0
  212. package/dist/proxmox/pbs-verify-job.d.ts.map +1 -0
  213. package/dist/proxmox/pool.d.ts +42 -0
  214. package/dist/proxmox/pool.d.ts.map +1 -0
  215. package/dist/proxmox/qemu.d.ts +46 -0
  216. package/dist/proxmox/qemu.d.ts.map +1 -0
  217. package/dist/proxmox/replication-job-form.d.ts +71 -0
  218. package/dist/proxmox/replication-job-form.d.ts.map +1 -0
  219. package/dist/proxmox/replication-job.d.ts +162 -0
  220. package/dist/proxmox/replication-job.d.ts.map +1 -0
  221. package/dist/proxmox/resource.d.ts +157 -0
  222. package/dist/proxmox/resource.d.ts.map +1 -0
  223. package/dist/proxmox/role.d.ts +97 -0
  224. package/dist/proxmox/role.d.ts.map +1 -0
  225. package/dist/proxmox/sdn-apply-read.d.ts +80 -0
  226. package/dist/proxmox/sdn-apply-read.d.ts.map +1 -0
  227. package/dist/proxmox/sdn-apply.d.ts +63 -0
  228. package/dist/proxmox/sdn-apply.d.ts.map +1 -0
  229. package/dist/proxmox/sdn-subnet-form.d.ts +111 -0
  230. package/dist/proxmox/sdn-subnet-form.d.ts.map +1 -0
  231. package/dist/proxmox/sdn-subnet.d.ts +161 -0
  232. package/dist/proxmox/sdn-subnet.d.ts.map +1 -0
  233. package/dist/proxmox/sdn-vnet.d.ts +113 -0
  234. package/dist/proxmox/sdn-vnet.d.ts.map +1 -0
  235. package/dist/proxmox/sdn-zone.d.ts +126 -0
  236. package/dist/proxmox/sdn-zone.d.ts.map +1 -0
  237. package/dist/proxmox/storage.d.ts +120 -0
  238. package/dist/proxmox/storage.d.ts.map +1 -0
  239. package/dist/proxmox/user.d.ts +107 -0
  240. package/dist/proxmox/user.d.ts.map +1 -0
  241. package/dist/proxmox/values.d.ts +134 -0
  242. package/dist/proxmox/values.d.ts.map +1 -0
  243. package/dist/proxmox/zfs-pool-write.d.ts +76 -0
  244. package/dist/proxmox/zfs-pool-write.d.ts.map +1 -0
  245. package/dist/proxmox/zfs-pool.d.ts +146 -0
  246. package/dist/proxmox/zfs-pool.d.ts.map +1 -0
  247. package/dist/talos/credentials.d.ts +30 -0
  248. package/dist/talos/credentials.d.ts.map +1 -0
  249. package/dist/talos/index.d.ts +15 -0
  250. package/dist/talos/index.d.ts.map +1 -0
  251. package/dist/talos/index.js +392 -0
  252. package/dist/talos/index.js.map +16 -0
  253. package/dist/talos/kubeconfig.d.ts +53 -0
  254. package/dist/talos/kubeconfig.d.ts.map +1 -0
  255. package/dist/talos/resource.d.ts +32 -0
  256. package/dist/talos/resource.d.ts.map +1 -0
  257. package/dist/talos/talos-bootstrap.d.ts +27 -0
  258. package/dist/talos/talos-bootstrap.d.ts.map +1 -0
  259. package/dist/talos/talos-cluster-health.d.ts +36 -0
  260. package/dist/talos/talos-cluster-health.d.ts.map +1 -0
  261. package/dist/talos/talos-machine-config.d.ts +41 -0
  262. package/dist/talos/talos-machine-config.d.ts.map +1 -0
  263. package/dist/talos/talosctl.d.ts +29 -0
  264. package/dist/talos/talosctl.d.ts.map +1 -0
  265. package/dist/talos/values.d.ts +20 -0
  266. package/dist/talos/values.d.ts.map +1 -0
  267. package/package.json +57 -0
  268. package/src/cloudflare/client.ts +76 -0
  269. package/src/cloudflare/index.ts +10 -0
  270. package/src/cloudflare/lock-rules.ts +60 -0
  271. package/src/cloudflare/providers.ts +23 -0
  272. package/src/cloudflare/r2-bucket-lock.ts +220 -0
  273. package/src/forgejo/branch-protection-form.ts +29 -0
  274. package/src/forgejo/branch-protection.ts +101 -0
  275. package/src/forgejo/client.ts +136 -0
  276. package/src/forgejo/index.ts +17 -0
  277. package/src/forgejo/org-actions-secrets.ts +99 -0
  278. package/src/forgejo/org-label.ts +100 -0
  279. package/src/forgejo/org-team.ts +105 -0
  280. package/src/forgejo/repo-webhook-form.ts +47 -0
  281. package/src/forgejo/repo-webhook.ts +118 -0
  282. package/src/forgejo/repository.ts +126 -0
  283. package/src/forgejo/resource.ts +171 -0
  284. package/src/forgejo/team-member.ts +97 -0
  285. package/src/forgejo/values.test.ts +48 -0
  286. package/src/forgejo/values.ts +61 -0
  287. package/src/index.ts +18 -0
  288. package/src/openbao/auth-role-form.ts +112 -0
  289. package/src/openbao/auth-role.ts +101 -0
  290. package/src/openbao/bao-address.test.ts +89 -0
  291. package/src/openbao/bao-address.ts +97 -0
  292. package/src/openbao/bao-http-gate.test.ts +88 -0
  293. package/src/openbao/bao-http-unix.test.ts +70 -0
  294. package/src/openbao/bao-http.test.ts +161 -0
  295. package/src/openbao/bao-http.ts +185 -0
  296. package/src/openbao/bao-status.test.ts +114 -0
  297. package/src/openbao/bao-status.ts +137 -0
  298. package/src/openbao/cloudflare-group-scope.test.ts +103 -0
  299. package/src/openbao/cloudflare-group-scope.ts +83 -0
  300. package/src/openbao/cloudflare-parity-catalog.ts +104 -0
  301. package/src/openbao/cloudflare-parity-snapshot.ts +84 -0
  302. package/src/openbao/cloudflare-parity.ts +152 -0
  303. package/src/openbao/cloudflare-permission-groups-solve.test.ts +171 -0
  304. package/src/openbao/cloudflare-permission-groups-solve.ts +197 -0
  305. package/src/openbao/cloudflare-permission-groups.test.ts +369 -0
  306. package/src/openbao/cloudflare-permission-groups.ts +299 -0
  307. package/src/openbao/cloudflare-policy.ts +180 -0
  308. package/src/openbao/cloudflare-role-form.test.ts +177 -0
  309. package/src/openbao/cloudflare-role-form.ts +183 -0
  310. package/src/openbao/cloudflare-role-wire.test.ts +132 -0
  311. package/src/openbao/cloudflare-role-wire.ts +41 -0
  312. package/src/openbao/cloudflare-role.ts +189 -0
  313. package/src/openbao/cloudflare-roles-config.ts +230 -0
  314. package/src/openbao/cloudflare-roles-expand-bucket.test.ts +134 -0
  315. package/src/openbao/cloudflare-roles-expand.ts +231 -0
  316. package/src/openbao/digest.ts +26 -0
  317. package/src/openbao/fake-bao.ts +84 -0
  318. package/src/openbao/forgejo-bootstrap-parse.test.ts +76 -0
  319. package/src/openbao/forgejo-bootstrap-parse.ts +90 -0
  320. package/src/openbao/forgejo-bootstrap.ts +181 -0
  321. package/src/openbao/index.ts +17 -0
  322. package/src/openbao/mount-form.ts +147 -0
  323. package/src/openbao/mount-wire.test.ts +108 -0
  324. package/src/openbao/mount-wire.ts +79 -0
  325. package/src/openbao/mount.ts +132 -0
  326. package/src/openbao/pki-role-form.ts +248 -0
  327. package/src/openbao/pki-role.ts +202 -0
  328. package/src/openbao/policy-assembly.test.ts +28 -0
  329. package/src/openbao/policy-assembly.ts +13 -0
  330. package/src/openbao/policy-wire.test.ts +90 -0
  331. package/src/openbao/policy-wire.ts +53 -0
  332. package/src/openbao/policy.ts +212 -0
  333. package/src/openbao/proxmox-role-form.ts +174 -0
  334. package/src/openbao/proxmox-role.ts +214 -0
  335. package/src/openbao/ssh-role-form.ts +248 -0
  336. package/src/openbao/ssh-role.ts +240 -0
  337. package/src/proxmox/acl.ts +267 -0
  338. package/src/proxmox/api-token-form.ts +122 -0
  339. package/src/proxmox/api-token.ts +222 -0
  340. package/src/proxmox/backup-job.ts +213 -0
  341. package/src/proxmox/ceph-daemon-form.ts +84 -0
  342. package/src/proxmox/ceph-daemon.ts +243 -0
  343. package/src/proxmox/ceph-flag.ts +249 -0
  344. package/src/proxmox/ceph-fs-wire.ts +246 -0
  345. package/src/proxmox/ceph-fs.ts +249 -0
  346. package/src/proxmox/ceph-osd-tree.ts +193 -0
  347. package/src/proxmox/ceph-osd-write.ts +76 -0
  348. package/src/proxmox/ceph-osd.ts +244 -0
  349. package/src/proxmox/ceph-pool-form.ts +249 -0
  350. package/src/proxmox/ceph-pool-settle.ts +70 -0
  351. package/src/proxmox/ceph-pool.ts +212 -0
  352. package/src/proxmox/client.test.ts +185 -0
  353. package/src/proxmox/client.ts +240 -0
  354. package/src/proxmox/credentials.test.ts +144 -0
  355. package/src/proxmox/credentials.ts +254 -0
  356. package/src/proxmox/firewall-alias-form.ts +112 -0
  357. package/src/proxmox/firewall-alias.ts +208 -0
  358. package/src/proxmox/generated/pbs.ts +461 -0
  359. package/src/proxmox/generated/pve.ts +7344 -0
  360. package/src/proxmox/group.ts +199 -0
  361. package/src/proxmox/ha-resource.ts +169 -0
  362. package/src/proxmox/ha-rule-form.ts +185 -0
  363. package/src/proxmox/ha-rule.ts +240 -0
  364. package/src/proxmox/index.ts +42 -0
  365. package/src/proxmox/lease-cache.test.ts +163 -0
  366. package/src/proxmox/lease-cache.ts +131 -0
  367. package/src/proxmox/lxc.ts +117 -0
  368. package/src/proxmox/members.test.ts +54 -0
  369. package/src/proxmox/members.ts +174 -0
  370. package/src/proxmox/metric-server-form.ts +128 -0
  371. package/src/proxmox/metric-server-otel.ts +99 -0
  372. package/src/proxmox/metric-server.ts +214 -0
  373. package/src/proxmox/network-apply-read.ts +228 -0
  374. package/src/proxmox/network-apply.ts +244 -0
  375. package/src/proxmox/node-network-form.ts +213 -0
  376. package/src/proxmox/node-network.ts +243 -0
  377. package/src/proxmox/notification-target-form.ts +104 -0
  378. package/src/proxmox/notification-target.ts +222 -0
  379. package/src/proxmox/pbs-datastore-form.ts +248 -0
  380. package/src/proxmox/pbs-datastore-guard.ts +105 -0
  381. package/src/proxmox/pbs-datastore.ts +271 -0
  382. package/src/proxmox/pbs-prune-job-form.ts +208 -0
  383. package/src/proxmox/pbs-prune-job.ts +227 -0
  384. package/src/proxmox/pbs-sync-job-form.ts +234 -0
  385. package/src/proxmox/pbs-sync-job.ts +258 -0
  386. package/src/proxmox/pbs-verify-job-form.ts +131 -0
  387. package/src/proxmox/pbs-verify-job.ts +227 -0
  388. package/src/proxmox/pool.test.ts +42 -0
  389. package/src/proxmox/pool.ts +80 -0
  390. package/src/proxmox/qemu.ts +89 -0
  391. package/src/proxmox/replication-job-form.ts +89 -0
  392. package/src/proxmox/replication-job.ts +248 -0
  393. package/src/proxmox/resource.ts +257 -0
  394. package/src/proxmox/role.ts +161 -0
  395. package/src/proxmox/sdn-apply-read.test.ts +152 -0
  396. package/src/proxmox/sdn-apply-read.ts +189 -0
  397. package/src/proxmox/sdn-apply.ts +154 -0
  398. package/src/proxmox/sdn-subnet-form.ts +156 -0
  399. package/src/proxmox/sdn-subnet.ts +238 -0
  400. package/src/proxmox/sdn-vnet.ts +228 -0
  401. package/src/proxmox/sdn-zone.ts +246 -0
  402. package/src/proxmox/storage.ts +245 -0
  403. package/src/proxmox/user.ts +214 -0
  404. package/src/proxmox/values.test.ts +193 -0
  405. package/src/proxmox/values.ts +203 -0
  406. package/src/proxmox/zfs-pool-write.ts +130 -0
  407. package/src/proxmox/zfs-pool.ts +253 -0
  408. package/src/talos/credentials.ts +136 -0
  409. package/src/talos/index.ts +14 -0
  410. package/src/talos/kubeconfig.ts +170 -0
  411. package/src/talos/resource.ts +31 -0
  412. package/src/talos/talos-bootstrap.ts +109 -0
  413. package/src/talos/talos-cluster-health.ts +119 -0
  414. package/src/talos/talos-machine-config.ts +146 -0
  415. package/src/talos/talosctl.ts +94 -0
  416. package/src/talos/values.test.ts +80 -0
  417. package/src/talos/values.ts +70 -0
@@ -0,0 +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;AAgDjE;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mBAAmB,iIACiD,CAAC"}
@@ -0,0 +1,83 @@
1
+ import type { SyncJobAttributes, SyncJobProps } from './pbs-sync-job.ts';
2
+ /**
3
+ * The marker for "PBS has no value for this number".
4
+ *
5
+ * ⚠️ `-1` RATHER THAN `0`, AND metric-server.ts's `UNSET = -1` IS THE PRECEDENT. `max-depth` has a
6
+ * legal value of 0 — sync this namespace and no child of it — which is a completely different
7
+ * instruction from the absent field, where PBS recurses as deep as it is allowed. Using 0 as the
8
+ * marker would make "no recursion" and "full recursion" the same attribute. `rate-in` and
9
+ * `transfer-last` take the same marker for uniformity rather than because 0 is legal for them:
10
+ * depending on a schema minimum I could not measure is exactly the kind of guess that becomes a
11
+ * forever-diff.
12
+ */
13
+ export declare const UNSET = -1;
14
+ /**
15
+ * A PBS rate limit off the wire, as a plain byte count.
16
+ *
17
+ * ⛔ THE VALUE GOES OUT AS A NUMBER AND COMES BACK AS PROSE. PBS types `rate-in` as a `HumanByte`,
18
+ * which parses `10485760` on the way in and prints something like `10.00 MiB` on the way out, so
19
+ * the two sides of a comparison are never the same string. Flattening both to bytes is what makes
20
+ * the field comparable at all. REASONED from the type's parse/print asymmetry, NOT measured —
21
+ * there was no credential to round-trip one with.
22
+ * ⚠️ IT ROUNDS, AND A RATE THAT DOES NOT DIVIDE EVENLY WILL NEVER SETTLE. `10.00 MiB` carries two
23
+ * decimals, so a declared 10485761 reads back as 10485760, `matches` reports an update, the PUT
24
+ * writes the same rounded value, and the next plan reports it again — forever. Declare a whole
25
+ * multiple of a binary unit. This is the likeliest forever-diff in the family and the first thing
26
+ * to check on the first plan against a live PBS.
27
+ * ⚠️ AN UNPARSEABLE ANSWER READS AS `UNSET`, which for a DECLARED rate means "not equal" and so an
28
+ * update rather than a silent noop. Wrong-but-loud is the right way round here.
29
+ */
30
+ export declare const bytes: (value: unknown) => number;
31
+ /**
32
+ * The live group filters, joined for a human.
33
+ *
34
+ * ⚠️ DISPLAY ONLY — NEVER SENT, NEVER COMPARED. The ⛔ on the `group-filter` prop says why the field
35
+ * is not declarable; this exists so that a plan against an adopted job SHOWS the filters this
36
+ * resource is deliberately leaving alone, rather than making them invisible.
37
+ * ⚠️ THE SEPARATOR IS ` | `, NOT A COMMA: a `regex:` filter may contain either, so no join here is
38
+ * unambiguous — and a comma is the one that would invite somebody to parse this back.
39
+ */
40
+ export declare const filters: (value: unknown) => string;
41
+ /**
42
+ * ⛔ `id` IS SENT AND IS NOT OPTIONAL. PBS's create takes it rather than inventing one, so this
43
+ * family avoids backup-job.ts's worst failure by construction — but only while the id is here.
44
+ * A POST without one would be refused rather than silently duplicating the job, which is the
45
+ * better failure, and it is still not a reason to leave it out.
46
+ * ⛔ `sync-direction` IS THE ONE FIELD SENT ONLY ON CREATE. It decides which side `remove-vanished`
47
+ * deletes from, it is not compared (see `matches`), and on a PBS old enough to have no push
48
+ * support it is an unknown parameter — so sending it on every update would turn every deploy
49
+ * against such a server into a 400 over a field nobody was changing.
50
+ */
51
+ export declare const createBody: (props: SyncJobProps) => Record<string, string>;
52
+ /**
53
+ * ⚠️ THE UPDATE IS THE SHARED HALF AND NOTHING ELSE — no `id` (it is the path), no
54
+ * `sync-direction`, no `delete` list. The factory only PUTs when `matches` is false and the form
55
+ * is non-empty, and this form is never empty because `remove-vanished` and the two store names
56
+ * are always present. That is fine here: reconcile reaches this line only when something really
57
+ * does differ, and re-sending the two store names it just compared is a write of what is already
58
+ * there rather than a change.
59
+ */
60
+ 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("effect/unstable/http/HttpClient").HttpClient>;
79
+ delete: ({ olds }: {
80
+ olds: SyncJobProps;
81
+ }) => import("effect/Effect").Effect<unknown, Error, import("effect/unstable/http/HttpClient").HttpClient>;
82
+ };
83
+ //# sourceMappingURL=pbs-sync-job-form.d.ts.map
@@ -0,0 +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;;;;;;;;;;;;;;;;;;;;;CAiFnB,CAAC"}
@@ -0,0 +1,246 @@
1
+ /**
2
+ * `Pbs.SyncJob` — one section of Proxmox Backup Server's `sync.cfg`, declared: a remote datastore's
3
+ * snapshots pulled into a local one on a schedule.
4
+ *
5
+ * ★ IT USES THE SHARED PVE CLIENT, AND THE TYPES STOP THE TWO HOSTS BEING SWAPPED. An earlier
6
+ * draft imported a `./pbs-client.ts` that never existed, arguing that reusing the PVE machinery
7
+ * would COMPILE and that this was the danger — a PBS host accepted wherever a PVE one belongs,
8
+ * every call 401ing, `read` folding that into "absent". The argument was right and the fix is
9
+ * the discriminant rather than a second client: `scheme` is REQUIRED on a target, so a PBS host
10
+ * is not assignable to a PVE resource or the reverse, and the mistake is a compile error. See
11
+ * the ⛔ on `scheme` in credentials.ts.
12
+ *
13
+ * ⛔ THE CREDENTIAL IS A PBS TOKEN AND IT DOES NOT EXIST YET; NO MOUNT NAME IS INVENTED IN THIS
14
+ * FILE. PBS wants `user@realm!tokenname` plus a UUID secret, issued by PBS — a PVE token is not
15
+ * one, whatever it is spelled like. MEASURED from this machine on 2026-09-13: the `claude-code`
16
+ * approle cannot enumerate mounts (`bao secrets list` -> 403) and
17
+ * `bao token capabilities kv/infra/proxmox/pbs` -> `deny`, so I could not confirm from here what
18
+ * does or does not exist. What credentials.ts records is that every PBS token on the kv shelf is
19
+ * READ-ONLY (`Audit`, as `monitoring@pve`) and STATIC — too narrow to create a sync job, and
20
+ * exactly the kind of credential this provider exists to avoid writing with.
21
+ * ★ SO THE MOUNT IS A `PbsTarget.mount` THE STACK SUPPLIES, and somebody has to build it first:
22
+ * a dynamic PBS mount with `read` and `provision` roles mirroring `proxmox-tb4`. Until it
23
+ * exists this family can be declared and cannot be deployed. `permission denied` means the
24
+ * grant is missing — say which mount and role you needed; do not fall back to the shelf token.
25
+ *
26
+ * ⚠️ WHAT IS MEASURED AND WHAT IS NOT. MEASURED on 2026-09-13 from this machine, read-only and
27
+ * under STRICT TLS (no `-k`; curl reports `ssl_verify_result` 0):
28
+ * `GET https://pbs.example.com:8007/api2/json/ping` -> HTTP 200 `{"data":{"pong":true}}`. So
29
+ * the host is real, its certificate validates, and PBS WRAPS ITS ANSWER IN THE SAME `{"data": …}`
30
+ * ENVELOPE AS PVE — which is what lets the PVE-shaped client body be reused at all.
31
+ * ⛔ EVERYTHING ELSE BELOW IS DOCUMENTED, FROM PBS'S PUBLISHED API SCHEMA, AND NOT MEASURED — the
32
+ * field list, the parameter spellings, which of them a PUT accepts, the privileges. Without a
33
+ * credential every other endpoint answers 401, and PBS answers 401 BEFORE it routes:
34
+ * `/api2/json/config/nosuchthing` -> 401, not 404 (measured). So the 401 from
35
+ * `/api2/json/config/sync` is not even evidence that the endpoint exists. THE FIRST PLAN
36
+ * AGAINST A LIVE PBS IS THE MEASUREMENT. Read it; do not deploy it unseen.
37
+ * ⚠️ AN ERROR BODY IS NOT WRAPPED: the 401 body is the bare text `authentication failed`, not
38
+ * JSON. `pve()` checks `response.ok` before it parses, so a `pbs()` copied from it is safe —
39
+ * provided the check stays in that order.
40
+ *
41
+ * ⚠️ `Proxmox.BackupJob` AND `Pbs.SyncJob` ARE NOT THE SAME FAMILY AND THE NAMES NEARLY COLLIDE.
42
+ * The first is a PVE vzdump schedule; this is a Proxmox Backup SERVER sync job, on a different
43
+ * host. The `Pbs.` prefix is what keeps them apart in a plan, so it is not shortened.
44
+ *
45
+ * ★ THE SEAM, SINCE IT IS NOT THE USUAL ONE. This file answers "what a sync job is and what it
46
+ * costs to declare one": the props, the attributes, the resource. pbs-sync-job-form.ts answers
47
+ * "how it meets PBS": the coercions, the create and update bodies, and — the part that normally
48
+ * lives here — `matches`. `matches` went with the wire because it is DOWNSTREAM of the wire:
49
+ * ha-rule.ts's rule is that only a field a write can actually set may be compared, so every line
50
+ * of that predicate is an argument about what the PUT accepts. Splitting it from the forms would
51
+ * have put the claim and its evidence in different files. `Provider.of(handlers)` stays HERE, for
52
+ * resource.ts's ⛔: it is the one place the handlers are checked against the concrete resource
53
+ * types, and a cast there would be a lie about whether they match.
54
+ */
55
+ import { Resource } from 'alchemy';
56
+ import * as Provider from 'alchemy/Provider';
57
+ import type { PveRequirements } from './resource.ts';
58
+ import type { WithPbsTarget } from './resource.ts';
59
+ /**
60
+ * ⚠️ THE PROPS ARE PBS'S OWN PARAMETER NAMES, DASHES INCLUDED, for backup-job.ts's reason: the form
61
+ * builder is then a copy rather than a translation table, and a translation table is one more
62
+ * place for a key to be renamed and silently never sent.
63
+ */
64
+ export interface SyncJobProps extends WithPbsTarget {
65
+ /**
66
+ * ⛔ PBS'S SECTION ID AND THIS RESOURCE'S KEY, REQUIRED. Unlike a PVE vzdump job PBS does not
67
+ * autogenerate one — `POST /config/sync` takes `id` — so the backup-job.ts failure of creating
68
+ * a second job beside the first on every reconcile cannot happen here. It is still required
69
+ * rather than derived: to adopt a job that exists, declare the id it already has.
70
+ * ⚠️ A PROXMOX SAFE ID — letters, digits, `_`, `.`, `-`, 3 to 32 characters — so there is nothing
71
+ * in it for `path` below to encode.
72
+ */
73
+ id: string;
74
+ /** The LOCAL datastore the snapshots land in. Required by PBS at create. */
75
+ store: string;
76
+ /** Local namespace, e.g. `tenant/db`. Unset means the root namespace, which PBS spells `''`. */
77
+ ns?: string;
78
+ /**
79
+ * ⛔ A REMOTE BY NAME ONLY. THIS RESOURCE NEVER MODELS THE CREDENTIAL BEHIND IT, and a
80
+ * `Pbs.Remote` family is OUT OF SCOPE for this package rather than merely unwritten:
81
+ * `POST /config/remote` requires `password`, and Alchemy persists props and attributes to its
82
+ * state store UNENCRYPTED (StateEncoding.ts tags Redacted values rather than encrypting them),
83
+ * which here is the `alchemy` Postgres that pg-backup.sh dumps nightly to CT100. A remote's
84
+ * password in a prop is that password in four places, for months. The only Remote resource that
85
+ * could exist would refuse `password` the way storage.ts refuses it — as a `never` — and could
86
+ * therefore never CREATE a remote, which is a resource that cannot do what its name promises.
87
+ * Create remotes out of band (`proxmox-backup-manager remote create`) and name one here.
88
+ * ⚠️ The fingerprint is not the problem: a certificate fingerprint is public. The password is.
89
+ * ⚠️ UNSET MEANS A LOCAL SYNC — datastore to datastore on this same PBS — which is a real and
90
+ * supported mode, not an omission. See `matches`: an unset `remote` is NOT compared, so leaving
91
+ * it out does not claim a job with a remote is local; it claims nothing at all.
92
+ */
93
+ remote?: string;
94
+ /** The datastore on that remote. Required by PBS at create. */
95
+ 'remote-store': string;
96
+ /** Namespace on the remote. Unset means its root namespace. */
97
+ 'remote-ns'?: string;
98
+ /**
99
+ * A PBS calendar event — `daily`, `hourly`, `mon..fri 02:30`. Unset means the job runs ONLY when
100
+ * somebody starts it by hand, which is a sync that is not happening; declare one.
101
+ * ⚠️ THIS COMPARES STRINGS, NOT MEANINGS. A calendar event has many equivalent spellings and PBS
102
+ * stores the one it was handed, so declare the spelling the server echoes back.
103
+ */
104
+ schedule?: string;
105
+ /** Single line only — PBS's comment schema rejects a newline. */
106
+ comment?: string;
107
+ /**
108
+ * ⛔ THIS DELETES SNAPSHOTS. NOT "prunes", NOT "tidies" — DELETES, on a schedule, driven by
109
+ * ANOTHER SERVER'S STATE. On a PULL job (the default), every backup group in the local `store`
110
+ * and `ns` that is no longer on the remote is REMOVED LOCALLY the next time the job runs. The
111
+ * remote decides; this side obeys. Somebody pruning hard on the remote, a remote datastore
112
+ * restored from an older copy, a remote namespace renamed, or a remote that has simply lost
113
+ * data — each of those becomes deletion HERE, and the local copy is usually the copy that was
114
+ * supposed to survive the remote.
115
+ * ⛔ AND ON A PUSH JOB IT DELETES ON THE REMOTE INSTEAD — same flag, opposite victim. Read
116
+ * `sync-direction` before reading this one.
117
+ * ⚠️ IT IS COMPARED AND SENT EVEN WHEN UNDECLARED, unlike every other optional field here, and
118
+ * that is deliberate: undeclared means `false`, so adopting a job somebody had switched this on
119
+ * for plans as an UPDATE that switches it off — a real edit, and NOT a free one. It is the
120
+ * direction that does not delete, but a job that was BOUNDING a datastore now grows it, and a
121
+ * full PBS datastore fails every backup on it. The plan says only "update"; read the live job.
122
+ */
123
+ 'remove-vanished'?: boolean;
124
+ /**
125
+ * The PBS Authid that owns the synced groups, e.g. `sync@pbs` or `sync@pbs!job1`. Unset leaves
126
+ * the config without one, which PBS reads as `root@pam` AT RUNTIME — so unset and `root@pam` are
127
+ * not the same value in the config even though they behave alike. Owning a group is what lets an
128
+ * Authid prune or delete it, so changing this is a permissions change, not a label.
129
+ * ⚠️ AN AUTHID IS AN IDENTIFIER, NEVER A SECRET — it may name an API token (`user@realm!name`),
130
+ * and the token's VALUE is the secret. This resource stores the name and never the value.
131
+ */
132
+ owner?: string;
133
+ /**
134
+ * Incoming rate limit in BYTES PER SECOND. Unset means unlimited.
135
+ * ⚠️ DECLARED IN BYTES, STORED AS A HUMAN STRING. PBS types this as a `HumanByte`, so a written
136
+ * `10485760` comes back as something like `10.00 MiB`; `bytes()` in the form file parses both
137
+ * ends back to a byte count so the two can be compared at all. REASONED from the type, NOT
138
+ * measured — I had no credential to round-trip one.
139
+ * ⛔ DECLARE A VALUE PBS CAN PRINT EXACTLY — a whole multiple of a binary unit. A rate that
140
+ * rounds in the printed form (10485761) reads back as the rounded value, never equals what was
141
+ * declared, and becomes an update reported on every plan forever. This is the single most
142
+ * likely forever-diff in this file; it is the first thing to check on the first plan.
143
+ * ⚠️ `burst-in`, `rate-out` AND `burst-out` ARE NOT MODELLED. PBS's rate limit is four fields
144
+ * flattened into the job; this resource manages one and leaves the others alone, which is safe
145
+ * because PBS's update assigns only the parameters it was sent.
146
+ */
147
+ 'rate-in'?: number;
148
+ /**
149
+ * How many namespace levels below `remote-ns` to sync, 0 (no recursion) upwards. Unset means PBS
150
+ * recurses as deep as it is allowed — which is MORE data, not less, so it is not a safe default
151
+ * to leave implicit on a job whose target namespace has children.
152
+ */
153
+ 'max-depth'?: number;
154
+ /** Sync only the last N snapshots of each group. Unset means all of them. */
155
+ 'transfer-last'?: number;
156
+ /**
157
+ * ⛔ NOT DECLARABLE, AND A COMPILE ERROR RATHER THAN A PROP THAT HALF WORKS — the storage.ts
158
+ * `password` idiom, for two independent reasons, either of which alone would be enough.
159
+ * 1. THE WIRE FORM IS AN ARRAY. PBS takes `group-filter` as a repeated parameter
160
+ * (`group-filter=type:ct&group-filter=regex:^web`), and `pve()`'s form is
161
+ * `Record<string, string>` — one value per key — so a list cannot be expressed at all.
162
+ * 2. NARROWING A FILTER MAY BE A DELETE. Whether `remove-vanished` skips the groups a filter
163
+ * excludes is NOT something I could measure without a credential. If it does not, then
164
+ * editing this field on a job with `remove-vanished` set removes every local group the new
165
+ * filter excludes. A field that MIGHT delete snapshots when changed does not get a
166
+ * half-working prop.
167
+ * ★ IT IS STILL REPORTED in the attributes, so a plan shows the filters a hand-made job carries
168
+ * and this resource never strips them: undeclared is unmanaged, and PBS's update assigns only
169
+ * what it was sent. To make it declarable, fix both halves — a form type that can repeat a
170
+ * key, and a MEASURED answer to (2) — in that order.
171
+ */
172
+ 'group-filter'?: never;
173
+ /**
174
+ * `pull` (default) or `push`. ⛔ IT DECIDES WHICH SIDE `remove-vanished` DELETES FROM. Push also
175
+ * needs a newer PBS: on a server that predates it the parameter is unknown and the create is
176
+ * refused, which is the honest failure.
177
+ * ⚠️ CREATE-ONLY HERE, SO A CHANGED DIRECTION PLANS AS NOOP — see `matches`. That is the
178
+ * deliberately safe half of an unmeasured question: if PBS does accept it on PUT, the cost of
179
+ * this choice is a noop; if PBS refuses it, comparing it would be an update the PUT can never
180
+ * perform, on every plan, forever. Retire the declaration and add another, as user.ts says for
181
+ * `userid`.
182
+ */
183
+ 'sync-direction'?: 'pull' | 'push';
184
+ /**
185
+ * ⚠️ SYNC ONLY SNAPSHOTS THAT HAVE PASSED VERIFICATION. Present on 4.2 (`sync-job update
186
+ * --verified-only <boolean>`, and in its `--delete` enum), and the estate sets it: the parked
187
+ * `sync-all-to-dc` job carries `verified-only: true`, so without this prop that job cannot be
188
+ * declared as it actually is.
189
+ * ⛔ IT PAIRS WITH A VERIFICATION JOB THAT ACTUALLY RUNS. With PBS's defaults a snapshot is
190
+ * verified once and never again — see `rechecks` in pbs-verify-job-form.ts — so `verified-only`
191
+ * on a datastore whose verify job is parked means "sync only what was checked once, long ago".
192
+ */
193
+ 'verified-only'?: boolean;
194
+ }
195
+ export interface SyncJobAttributes {
196
+ /** From the props — it is the path this object was read by. */
197
+ id: string;
198
+ store: string;
199
+ /** `''` is the root namespace, which is also how PBS spells it. */
200
+ ns: string;
201
+ /** `''` means a LOCAL sync — datastore to datastore on this PBS. */
202
+ remote: string;
203
+ 'remote-store': string;
204
+ 'remote-ns': string;
205
+ /** `''` means the job runs only when somebody starts it. */
206
+ schedule: string;
207
+ comment: string;
208
+ 'remove-vanished': boolean;
209
+ /** ⚠️ Absent on the wire means `false`, PBS's own default. */
210
+ 'verified-only': boolean;
211
+ /** `''` means no owner in the config, i.e. `root@pam` at runtime. An identifier, never a secret. */
212
+ owner: string;
213
+ /** Bytes per second, or `UNSET` (-1). See `bytes()`. */
214
+ 'rate-in': number;
215
+ /** `UNSET` (-1) means unset, which means full recursion. `0` is a real value meaning none. */
216
+ 'max-depth': number;
217
+ /** `UNSET` (-1) means all snapshots. */
218
+ 'transfer-last': number;
219
+ /**
220
+ * ⚠️ REPORTED, NEVER SENT, NEVER COMPARED — the live filter list joined for display only. See the
221
+ * ⛔ on the prop for why it is not declarable.
222
+ */
223
+ 'group-filter': string;
224
+ /** `pull` or `push`. Reported, never compared — create-only here. */
225
+ 'sync-direction': string;
226
+ }
227
+ export interface PbsSyncJob extends Resource<'Pbs.SyncJob', SyncJobProps, SyncJobAttributes, never, PveRequirements> {
228
+ }
229
+ /**
230
+ * ⚠️ NO `defaultRemovalPolicy: 'retain'`, and the reasoning is replication-job.ts's. Deleting this
231
+ * object removes a SCHEDULE, not data: every snapshot already synced stays in the local
232
+ * datastore, and PBS's own pruning is a different job. What is lost is freshness — which is
233
+ * destructive in six months rather than today, and is exactly why the plan line deserves reading.
234
+ */
235
+ export declare const PbsSyncJob: import("alchemy").ResourceClass<PbsSyncJob>;
236
+ /**
237
+ * ⛔ THE EMPTY `list` FROM THE FACTORY STANDS. `GET /config/sync` hands back every sync job an
238
+ * operator ever made in the UI, and adopting one is how a later `alchemy destroy` silently stops
239
+ * a second copy being refreshed. Adoption is an explicit act — declare the `id` you mean.
240
+ * ⚠️ DELETING THE JOB DOES NOT DELETE SNAPSHOTS, AND `remove-vanished` DOES. Those two sentences
241
+ * are the whole risk model of this family and they point opposite ways: the DELETE plan line is
242
+ * safe today and expensive in six months, while a single `remove-vanished: true` is a standing
243
+ * instruction to delete local snapshots whenever another server loses them.
244
+ */
245
+ export declare const PbsSyncJobProvider: () => import("effect/Layer").Layer<Provider.Provider<PbsSyncJob>, never, import("effect/unstable/http/HttpClient").HttpClient>;
246
+ //# sourceMappingURL=pbs-sync-job.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-sync-job.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-sync-job.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAG7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;;GAIG;AACH,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD;;;;;;;OAOG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,gGAAgG;IAChG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;;;;;OAeG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;;;;;;OAeG;IACH,cAAc,CAAC,EAAE,KAAK,CAAC;IACvB;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,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;AAED,MAAM,WAAW,UAAW,SAAQ,QAAQ,CAC1C,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,UAAU,6CAAsC,CAAC;AAE9D;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,gIACgD,CAAC"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * A verification job's props as the form PBS wants, and the one derived string worth reporting.
3
+ *
4
+ * ★ SPLIT OUT OF pbs-verify-job.ts TO KEEP BOTH FILES UNDER THE 250-LINE CAP, on the seam
5
+ * replication-job-form.ts and ha-rule-form.ts already cut: this file answers "how does a
6
+ * declaration become a PBS write, and what do the two filter fields actually mean", and
7
+ * pbs-verify-job.ts answers "what is a verification job and when has it changed". Nothing here
8
+ * reads the host and nothing here decides a diff.
9
+ *
10
+ * ⚠️ THE `import type` BACK TO pbs-verify-job.ts IS A CYCLE ON PAPER ONLY — type-only, erased
11
+ * before anything runs, and `PbsVerifyJobProps` stays public in the file declaring the resource.
12
+ *
13
+ * ⛔ THERE IS NO `disable` FIELD ON A PBS VERIFICATION JOB, AND SHIPPING A PROP FOR ONE WOULD HAVE
14
+ * BEEN THE WORST BUG IN THIS FAMILY. Prune jobs have `disable` and sync jobs have `disable`;
15
+ * `VerificationJobConfig` does not, in the struct, in the API schema, or in the update handler's
16
+ * `DeletableProperty` enum — read at HEAD of pbs-api-types and src/api2/config/verify.rs on
17
+ * 2026-09-13. A `disable` prop would therefore be a prop that either does nothing or 400s the
18
+ * whole call (the create schema has `additional_properties: false`, so an unknown key is
19
+ * rejected with "schema does not allow additional properties"). Either way it would be a
20
+ * declaration saying "verification is paused" that PBS never agreed to. The real off switch is
21
+ * an absent `schedule`.
22
+ * ★ NOW VERIFIED AGAINST THE RUNNING HOST, which this comment previously said it was not.
23
+ * `proxmox-backup-manager verify-job update --help` on the live 4.2 server offers
24
+ * `--comment --delete --digest --ignore-verified --max-depth --ns --outdated-after
25
+ * --read-threads --schedule --store --verify-threads` — no `--disable` — and its `--delete`
26
+ * enum contains `schedule`. Both halves of the claim hold on this estate's actual version.
27
+ * ⚠️ `read-threads` AND `verify-threads` EXIST ON 4.2 AND ARE NOT PROPS HERE. Nothing on this
28
+ * estate sets either, and a prop nobody uses is an abstraction with no user — the same reason
29
+ * `PveSpec.immutable` was backed out. Add them when something needs them.
30
+ *
31
+ * ⛔ `withClears` FROM values.ts IS DELIBERATELY NOT USED HERE, AND USING IT WOULD BREAK EVERY
32
+ * UPDATE. PVE's `delete` is ONE comma-separated string; PBS's is an ARRAY of an enum. MEASURED in
33
+ * proxmox-schema's `do_parse_parameter_strings`: for an `Schema::Array` property each occurrence
34
+ * of the key pushes ONE element, so a form body must REPEAT the key — `delete=ns&delete=comment`.
35
+ * `withClears` emits `delete: 'ns,comment'`, which PBS parses as a single element `"ns,comment"`,
36
+ * which is not a `DeletableProperty` variant, so the call fails with a parameter error. It fails
37
+ * loudly rather than quietly, which is the only good news in it.
38
+ * ★ AND IT COULD NOT BE FIXED IN THIS FILE ANYWAY. `client.ts` types a form as
39
+ * `Record<string, string>` and builds it with `new URLSearchParams(form)`; neither a plain
40
+ * object nor that constructor overload can express a repeated key. Clearing a PBS field needs
41
+ * a client that takes entry pairs. Until one exists, this form SETS and never CLEARS — so an
42
+ * undeclared field is left alone and, in pbs-verify-job.ts, is not compared either.
43
+ */
44
+ import type { PbsVerifyJobProps } from './pbs-verify-job.ts';
45
+ /**
46
+ * What the live pair actually causes, rendered for a plan line.
47
+ *
48
+ * ⛔ THE DEFAULTS MEAN "VERIFY EACH SNAPSHOT EXACTLY ONCE, EVER", AND THAT IS THE FAILURE THIS
49
+ * WHOLE FAMILY EXISTS TO MAKE VISIBLE. Read from src/backup/verify.rs `verify_filter` and
50
+ * src/server/verify_job.rs at HEAD on 2026-09-13, the filter is:
51
+ *
52
+ * ignore_verified = ignore_verified.unwrap_or(true) // absent means TRUE
53
+ * if !ignore_verified -> verify
54
+ * manifest has no verify state -> verify
55
+ * outdated_after is None -> SKIP, forever
56
+ * days_since_last_verify > outdated_after -> verify
57
+ *
58
+ * So a job created with neither field set — the shape the PBS web UI produces when nobody
59
+ * touches those two boxes — checks every snapshot once on the run after it is written and then
60
+ * never looks at it again. Bit rot that appears a month later is never found. The job stays
61
+ * green the entire time, because a job that verified nothing verified nothing badly.
62
+ *
63
+ * ⚠️ A FAILED PAST VERIFICATION IS SKIPPED TOO. `verify_filter` looks only at whether a verify
64
+ * state EXISTS, never at whether it says Ok or Failed, so a snapshot that failed once is not
65
+ * re-checked by a defaulted job either. Pair that with a prune job and the failure ages out
66
+ * without anyone confirming it.
67
+ *
68
+ * ⛔ `outdated-after: 0` DOES NOT MEAN "NEVER", THOUGH PBS'S OWN STRUCT DOC SAYS IT DOES. That
69
+ * comment — "Reverify snapshots after X days, never if 0" — contradicts the code beside it: the
70
+ * test is `days_since_last_verify > max_age`, so `0` re-verifies everything checked more than a
71
+ * day ago, i.e. very nearly every run. The schema text calls `0` deprecated and the minimum is
72
+ * `0`, so it is accepted. "Never" is the ABSENT value, not the zero — and this resource cannot
73
+ * get a job back to absent (see the ⛔ on `withClears` above), so a declaration that sets
74
+ * `outdated-after` has made a one-way choice. Undo it by hand:
75
+ * `proxmox-backup-manager verify-job update <id> --delete outdated-after`.
76
+ *
77
+ * ⚠️ THE COMPARISON IS INTEGER DAYS SINCE THE LAST RUN'S START, `(now - upid.starttime) / 86400`,
78
+ * and it is strictly greater-than. `outdated-after: 30` therefore re-checks on day 31.
79
+ */
80
+ export declare const rechecks: (ignoreVerified: boolean, outdatedAfter: number) => string;
81
+ /**
82
+ * The form for create and update alike.
83
+ *
84
+ * ⛔ `schedule: null` OMITS THE KEY, AND ON AN UPDATE THAT DOES NOT CLEAR AN EXISTING ONE. This
85
+ * form SETS and never CLEARS — the ⛔ on `withClears` above is why — so declaring `null` against
86
+ * a job that already has a schedule plans an update that changes nothing, every time. Park a job
87
+ * by hand once and the declaration then describes it truthfully:
88
+ * `proxmox-backup-manager verify-job update <id> --delete schedule`. The honest failure is a
89
+ * plan that keeps asking; the dishonest one would be a form that quietly reported success.
90
+ *
91
+ * ⚠️ `store` AND `ignore-verified` ARE ALWAYS SENT BECAUSE THEY ARE ALWAYS COMPARED.
92
+ * A field compared against a default but not sent as that default is an update reported on every
93
+ * plan that the write never performs — backup-job.ts and replication-job-form.ts both record the
94
+ * same trade. `ignore-verified` is the only one of the three with a PBS-side default, and it is
95
+ * TRUE, so an undeclared prop is sent as `1` rather than left out.
96
+ *
97
+ * ⚠️ THE BOOLEAN IS SPELLED INLINE RATHER THAN THROUGH `flag()` FROM values.ts, AND THAT IS A TYPE
98
+ * FACT RATHER THAN A STYLE ONE. `flag` answers `'1' | '0' | undefined` so that an undeclared
99
+ * field is dropped; here the field must never be dropped, and the `undefined` in its return type
100
+ * is not assignable to a `Record<string, string>` form body.
101
+ *
102
+ * ⚠️ PBS ACCEPTS BOTH `application/x-www-form-urlencoded` AND `application/json` AND NOTHING ELSE —
103
+ * any other content type is rejected outright with "unsupported content type", measured in
104
+ * proxmox-rest-server's `get_request_parameters`. `client.ts` sends the form encoding whenever a
105
+ * body is present, so it is already speaking one of the two. Numbers are stringified here for
106
+ * that reason; PBS parses them back through the integer schema.
107
+ *
108
+ * ⛔ `ns` IS DROPPED WHEN IT IS EMPTY, NOT SENT AS `''`. The empty string IS a legal namespace
109
+ * value — `BACKUP_NS_RE` is wrapped in `(?:…)?`, so it passes the schema and reaches the update
110
+ * handler — and the handler then throws it away at `if !ns.is_root()`. Sending it would look like
111
+ * a write that moves the job to the root namespace and would silently be nothing at all.
112
+ */
113
+ export declare const shape: (props: PbsVerifyJobProps) => Record<string, string>;
114
+ //# sourceMappingURL=pbs-verify-job-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-verify-job-form.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-verify-job-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,QAAQ,mBAAoB,OAAO,iBAAiB,MAAM,KAAG,MAMzE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,KAAK,UAAW,iBAAiB,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAUpE,CAAC"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * `Pbs.VerifyJob` — one section of PBS's `verification.cfg`, declared.
3
+ *
4
+ * ★ THIS IS THE FAMILY THAT ANSWERS "ARE THE BACKUPS ACTUALLY GOOD", AND NOTHING ELSE IN THIS
5
+ * PACKAGE DOES. A datastore reports free space, a prune job reports that it ran, and every
6
+ * snapshot in the store can still be unreadable: PBS learns a chunk has rotted only when
7
+ * something reads it back and checks its digest, and verification is the only thing that does
8
+ * that on a schedule. An undeclared verify job is the reason nobody notices for months — and a
9
+ * green `Proxmox.BackupJob` makes it worse rather than better, because a vzdump job that says
10
+ * "OK" every night is exactly the evidence people stop at.
11
+ *
12
+ * ⛔ THIS FILE CANNOT AUTHENTICATE UNTIL TWO THINGS OUTSIDE IT CHANGE, AND IT IS SHIPPED SAYING SO
13
+ * RATHER THAN SHIPPED LOOKING FINISHED. Both are recorded on `PbsTarget` below:
14
+ * 1. `credentials.ts` has no PBS mint. MEASURED 2026-09-13 from this Mac: the `claude-code`
15
+ * approle is refused `sys/mounts`, `kv/infra/proxmox` and `proxmox-pbs/creds/read` alike —
16
+ * 403 permission denied on all three — so there is no mount to name and none is invented.
17
+ * 2. `client.ts`'s `authorization()` builds a PVE header, and PBS will not accept it. See the
18
+ * ⛔ on `PbsTarget`.
19
+ * Until both land, every call 401s, `pveOperations.read` folds that into "absent", and the plan
20
+ * reports `create` for a job that is plainly there. The deploy then FAILS at the POST rather
21
+ * than clobbering anything — an unauthenticated POST 401s, and an authenticated one is refused
22
+ * because PBS will not take a duplicate section id — so the cost is a LYING PLAN and a broken
23
+ * run, not a lost job. That is still reason enough not to wire it into a stack yet: a plan
24
+ * nobody can trust is its own outage.
25
+ *
26
+ * ⚠️ THE SHAPES BELOW ARE READ FROM PUBLISHED SOURCE, NOT MEASURED ON THIS ESTATE. Everything is
27
+ * taken from `pbs-api-types/src/jobs.rs`, `src/api2/config/verify.rs`, `src/server/verify_job.rs`
28
+ * and `src/backup/verify.rs` at HEAD of the Proxmox git mirrors on 2026-09-13. What WAS measured
29
+ * here: `pbs.example.com:8007` and `pbs.mgmt.example.com:8007` both answer HTTP 401 under
30
+ * STRICT TLS (curl `ssl_verify_result=0`), so no `-k` is needed and `client.ts`'s plain `fetch`
31
+ * reaches PBS unchanged. The running host's own schema was NOT read — no credential — so a PBS
32
+ * older than HEAD may differ.
33
+ */
34
+ import { Resource } from 'alchemy';
35
+ import * as Provider from 'alchemy/Provider';
36
+ import type { PbsTarget } from './credentials.ts';
37
+ import { type PveRequirements } from './resource.ts';
38
+ export interface PbsVerifyJobProps {
39
+ /** ⛔ A PBS host, never a PVE cluster. See `PbsTarget`. */
40
+ target: PbsTarget;
41
+ /**
42
+ * ⛔ The primary key, REQUIRED, and never left to PBS. 3–32 chars of
43
+ * `[A-Za-z0-9_][A-Za-z0-9._-]*`. PBS refuses a duplicate section id outright, which is the loud
44
+ * failure `Proxmox.BackupJob` had to engineer for itself — but only because the id is sent.
45
+ */
46
+ id: string;
47
+ /** Datastore name, 3–32 safe-id chars. ⚠️ MUTABLE — see the ⚠️ on `matches`. */
48
+ store: string;
49
+ /**
50
+ * ⛔ THE KEY IS REQUIRED AND THE VALUE MAY BE `null`. PBS makes the field optional; this family
51
+ * refuses to let you OMIT it, which is not the same thing. A verification job with no schedule
52
+ * never runs on its own and PBS reports it as perfectly healthy — and an absent schedule is also
53
+ * the only way to turn one off, because there is NO `disable` field on a verification job.
54
+ * ⛔ THAT LAST CLAIM IS NOW MEASURED, not read from source. `proxmox-backup-manager verify-job
55
+ * update --help` on the live 4.2 host lists `--delete
56
+ * ignore-verified|comment|schedule|outdated-after|ns|max-depth|read-threads|verify-threads`
57
+ * and no `--disable` anywhere. So `schedule` is deletable — "parked" is a state PBS supports —
58
+ * and `disable` genuinely does not exist. pbs-verify-job-form.ts said this was read off the
59
+ * source and NOT verified against a running host; it is now verified, on this one.
60
+ * ★ SO `null` MEANS "DELIBERATELY PARKED" AND OMITTING IT IS STILL AN ERROR. The original
61
+ * required-string kept you from declaring verification that never happens, which is right, but
62
+ * it also made a genuinely parked job UNDECLARABLE — and the estate has one: `v-datacenter` is
63
+ * parked because syno1 is powered off, comment and runbook and all. A resource that cannot
64
+ * describe what is really there pushes the operator back to the CLI, which is the failure this
65
+ * package exists to end. Writing `schedule: null` costs a word and says the quiet part out
66
+ * loud; leaving the key out still will not compile.
67
+ * ⚠️ ADOPTING A SCHEDULELESS JOB WITH A SCHEDULE DECLARED GIVES IT ONE ON THE FIRST DEPLOY, which
68
+ * is the intended direction and is still a write nobody asked for in words. `matches` compares
69
+ * `schedule`, the live value reads `''`, so the first reconcile PUTs the declared one and
70
+ * verification starts running that night. Read the first plan against an adopted job.
71
+ * ⚠️ A systemd calendar event. Spelled `daily`, `sat 02:00`, `mon..fri 23:00`. A step expression
72
+ * is legal too and is not written out here: those two characters would close this comment.
73
+ */
74
+ schedule: string | null;
75
+ /**
76
+ * The namespace to verify, e.g. `tier1/prod`. Omitted means the datastore root.
77
+ * ⛔ NEVER SENT AS THE EMPTY STRING. MEASURED in the update handler: `if !ns.is_root()` — a root
78
+ * namespace on a PUT is accepted by the schema, reaches the handler and is then SILENTLY
79
+ * DISCARDED. A job cannot be moved back to the root namespace by this resource at all; that
80
+ * needs `--delete ns` by hand. So an undeclared `ns` is neither sent nor compared.
81
+ */
82
+ ns?: string;
83
+ /**
84
+ * How many namespace levels below `ns` to descend. `0` is that level only; PBS's maximum is 7.
85
+ * ⚠️ PBS's own default is FULL recursion (7), not 0. Undeclared means undeclared here: not sent,
86
+ * not compared, because "unset" and "7" are stored differently and only one is reachable.
87
+ */
88
+ 'max-depth'?: number;
89
+ /**
90
+ * ⛔ THE HALF OF THE PAIR THAT DECIDES WHETHER THIS JOB EVER RE-CHECKS ANYTHING. Defaults to
91
+ * TRUE. Read `rechecks` and the ⛔ in pbs-verify-job-form.ts before setting either of these.
92
+ */
93
+ 'ignore-verified'?: boolean;
94
+ /** Days after which a past verification is stale. ⛔ See the pair's ⛔ in the form file. */
95
+ 'outdated-after'?: number;
96
+ /** ⚠️ PBS TRIMS IT AND STORES AN EMPTY ONE AS ABSENT, so `' '` reads back as `''`. */
97
+ comment?: string;
98
+ }
99
+ export interface PbsVerifyJobAttributes {
100
+ id: string;
101
+ store: string;
102
+ schedule: string;
103
+ ns: string;
104
+ /** ⚠️ `-1` means "no max-depth in the section". `0` is a real setting meaning no recursion. */
105
+ 'max-depth': number;
106
+ 'ignore-verified': boolean;
107
+ /** ⚠️ `-1` means "unset", which is NOT `0`. See the ⛔ in the form file. */
108
+ 'outdated-after': number;
109
+ comment: string;
110
+ /**
111
+ * ★ WHAT THIS JOB ACTUALLY RE-CHECKS, IN ENGLISH, COMPUTED FROM THE LIVE PAIR. REPORTED, NEVER
112
+ * COMPARED — it is derived from two fields `matches` already compares, so diffing it would
113
+ * double-count them. It exists because the failure this family guards against is a job that
114
+ * looks healthy in every column and verifies each snapshot exactly once, ever; that job reads
115
+ * `never` here. A plan line is the only place anyone will see it.
116
+ */
117
+ rechecks: string;
118
+ }
119
+ export interface PbsVerifyJob extends Resource<'Pbs.VerifyJob', PbsVerifyJobProps, PbsVerifyJobAttributes, never, PveRequirements> {
120
+ }
121
+ /**
122
+ * ⚠️ NO `defaultRemovalPolicy: 'retain'`, DELIBERATELY, AND IT IS THE CLOSER CALL THAN IT LOOKS.
123
+ * The section holds no data — deleting it destroys nothing, the way `Proxmox.BackupJob`'s delete
124
+ * destroys no archives. What it destroys is the CHECKING, silently and permanently, and PBS will
125
+ * not refuse it the way it refuses to remove a datastore in use. `retain` would hide that behind
126
+ * a state-row drop instead of showing it as a plan line, and the plan line is the only warning
127
+ * anyone gets. Pipe `RemovalPolicy.retain()` per declaration where the job must outlive the code.
128
+ */
129
+ export declare const PbsVerifyJob: import("alchemy").ResourceClass<PbsVerifyJob>;
130
+ /**
131
+ * ⛔ `list` IS EMPTY, INHERITED FROM `pveHandlers`, AND THE REASON IS SHARPER HERE THAN ELSEWHERE.
132
+ * `GET /config/verify` returns every verification job the caller can see, including the
133
+ * ones the PBS installer and a human made. Adopting those would put Alchemy one dropped line
134
+ * away from DELETING a datastore's only verification schedule — and deleting it destroys nothing
135
+ * visible, so the loss is discovered the day a restore fails and there is no verification history
136
+ * to say when the rot started. Adoption stays explicit: declare the existing id.
137
+ *
138
+ * ⚠️ NO `digest` IS SENT ON UPDATE OR DELETE, SO THIS IS LAST-WRITER-WINS. PBS accepts an optional
139
+ * `digest` on both and would refuse a write made against a stale read. Sending one would need a
140
+ * read-then-write window this provider does not have — `pveOperations` reads and writes in two
141
+ * separate calls with two separate mints — so a concurrent edit from the PBS UI is overwritten
142
+ * rather than refused. Same behaviour as every PVE family here; stated because PBS offers better.
143
+ */
144
+ export declare const PbsVerifyJobProvider: () => import("effect/Layer").Layer<Provider.Provider<PbsVerifyJob>, never, import("effect/unstable/http/HttpClient").HttpClient>;
145
+ //# sourceMappingURL=pbs-verify-job.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-verify-job.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-verify-job.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;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,MAAM,eAAe,CAAC;AAGlE,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,MAAM,EAAE,SAAS,CAAC;IAClB;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;;;;OAMG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,0FAA0F;IAC1F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,+FAA+F;IAC/F,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAa,SAAQ,QAAQ,CAC5C,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,+CAA0C,CAAC;AAuEpE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,kIACkD,CAAC"}