@homeflare/alchemy 0.39.0 → 0.40.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 (207) hide show
  1. package/README.md +10 -8
  2. package/dist/ceph/auth-entity.d.ts +34 -0
  3. package/dist/ceph/auth-entity.d.ts.map +1 -0
  4. package/dist/ceph/ceph-argv-config.d.ts +10 -0
  5. package/dist/ceph/ceph-argv-config.d.ts.map +1 -0
  6. package/dist/ceph/ceph-argv.d.ts +19 -0
  7. package/dist/ceph/ceph-argv.d.ts.map +1 -0
  8. package/dist/ceph/ceph-auth-form.d.ts +54 -0
  9. package/dist/ceph/ceph-auth-form.d.ts.map +1 -0
  10. package/dist/ceph/ceph-auth-parse.d.ts +56 -0
  11. package/dist/ceph/ceph-auth-parse.d.ts.map +1 -0
  12. package/dist/ceph/ceph-auth-reconcile.d.ts +35 -0
  13. package/dist/ceph/ceph-auth-reconcile.d.ts.map +1 -0
  14. package/dist/ceph/ceph-config-options.d.ts +23 -0
  15. package/dist/ceph/ceph-config-options.d.ts.map +1 -0
  16. package/dist/ceph/ceph-key-leak-assert.d.ts +25 -0
  17. package/dist/ceph/ceph-key-leak-assert.d.ts.map +1 -0
  18. package/dist/ceph/ceph-transport.d.ts +37 -0
  19. package/dist/ceph/ceph-transport.d.ts.map +1 -0
  20. package/dist/ceph/fake-ceph-dial.d.ts +35 -0
  21. package/dist/ceph/fake-ceph-dial.d.ts.map +1 -0
  22. package/dist/ceph/index.d.ts +13 -0
  23. package/dist/ceph/index.d.ts.map +1 -0
  24. package/dist/ceph/index.js +1609 -0
  25. package/dist/ceph/index.js.map +38 -0
  26. package/dist/index.d.ts +1 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/proxmox/index.js +15 -6
  29. package/dist/proxmox/index.js.map +3 -3
  30. package/dist/proxmox/qemu-volume.d.ts +12 -2
  31. package/dist/proxmox/qemu-volume.d.ts.map +1 -1
  32. package/dist/talos/credentials-write.d.ts +46 -0
  33. package/dist/talos/credentials-write.d.ts.map +1 -0
  34. package/dist/talos/credentials.d.ts +51 -9
  35. package/dist/talos/credentials.d.ts.map +1 -1
  36. package/dist/talos/fake-process.d.ts +56 -0
  37. package/dist/talos/fake-process.d.ts.map +1 -0
  38. package/dist/talos/index.d.ts +19 -4
  39. package/dist/talos/index.d.ts.map +1 -1
  40. package/dist/talos/index.js +357 -173
  41. package/dist/talos/index.js.map +16 -10
  42. package/dist/talos/kubeconfig-attrs.d.ts +4 -0
  43. package/dist/talos/kubeconfig-attrs.d.ts.map +1 -0
  44. package/dist/talos/kubeconfig.d.ts +41 -23
  45. package/dist/talos/kubeconfig.d.ts.map +1 -1
  46. package/dist/talos/machine-config-fixtures.d.ts +60 -0
  47. package/dist/talos/machine-config-fixtures.d.ts.map +1 -0
  48. package/dist/talos/machine-config-poll.d.ts +43 -0
  49. package/dist/talos/machine-config-poll.d.ts.map +1 -0
  50. package/dist/talos/machine-config-read.d.ts +49 -0
  51. package/dist/talos/machine-config-read.d.ts.map +1 -0
  52. package/dist/talos/resource.d.ts +18 -0
  53. package/dist/talos/resource.d.ts.map +1 -1
  54. package/dist/talos/talos-bootstrap-etcd.d.ts +38 -0
  55. package/dist/talos/talos-bootstrap-etcd.d.ts.map +1 -0
  56. package/dist/talos/talos-bootstrap.d.ts +87 -0
  57. package/dist/talos/talos-bootstrap.d.ts.map +1 -1
  58. package/dist/talos/talos-cluster-health.d.ts +43 -1
  59. package/dist/talos/talos-cluster-health.d.ts.map +1 -1
  60. package/dist/talos/talos-errors.d.ts +68 -0
  61. package/dist/talos/talos-errors.d.ts.map +1 -0
  62. package/dist/talos/talos-machine-config.d.ts +51 -15
  63. package/dist/talos/talos-machine-config.d.ts.map +1 -1
  64. package/dist/talos/talosctl.d.ts +7 -0
  65. package/dist/talos/talosctl.d.ts.map +1 -1
  66. package/dist/talos/values.d.ts +23 -3
  67. package/dist/talos/values.d.ts.map +1 -1
  68. package/dist/unifi/acl-rule-drift.d.ts +22 -0
  69. package/dist/unifi/acl-rule-drift.d.ts.map +1 -0
  70. package/dist/unifi/acl-rule-form.d.ts +90 -0
  71. package/dist/unifi/acl-rule-form.d.ts.map +1 -0
  72. package/dist/unifi/acl-rule-ordering-form.d.ts +49 -0
  73. package/dist/unifi/acl-rule-ordering-form.d.ts.map +1 -0
  74. package/dist/unifi/acl-rule-ordering.d.ts +54 -0
  75. package/dist/unifi/acl-rule-ordering.d.ts.map +1 -0
  76. package/dist/unifi/acl-rule.d.ts +49 -0
  77. package/dist/unifi/acl-rule.d.ts.map +1 -0
  78. package/dist/unifi/dns-policy-drift.d.ts +21 -0
  79. package/dist/unifi/dns-policy-drift.d.ts.map +1 -0
  80. package/dist/unifi/dns-policy-form.d.ts +97 -0
  81. package/dist/unifi/dns-policy-form.d.ts.map +1 -0
  82. package/dist/unifi/dns-policy.d.ts +55 -0
  83. package/dist/unifi/dns-policy.d.ts.map +1 -0
  84. package/dist/unifi/firewall-policy-drift.d.ts +26 -0
  85. package/dist/unifi/firewall-policy-drift.d.ts.map +1 -0
  86. package/dist/unifi/firewall-policy-form.d.ts +102 -0
  87. package/dist/unifi/firewall-policy-form.d.ts.map +1 -0
  88. package/dist/unifi/firewall-policy-ordering-form.d.ts +66 -0
  89. package/dist/unifi/firewall-policy-ordering-form.d.ts.map +1 -0
  90. package/dist/unifi/firewall-policy-ordering.d.ts +57 -0
  91. package/dist/unifi/firewall-policy-ordering.d.ts.map +1 -0
  92. package/dist/unifi/firewall-policy.d.ts +57 -0
  93. package/dist/unifi/firewall-policy.d.ts.map +1 -0
  94. package/dist/unifi/index.d.ts +7 -0
  95. package/dist/unifi/index.d.ts.map +1 -1
  96. package/dist/unifi/index.js +588 -3
  97. package/dist/unifi/index.js.map +24 -4
  98. package/dist/unifi/paginate.d.ts +0 -12
  99. package/dist/unifi/paginate.d.ts.map +1 -1
  100. package/dist/unifi/providers.d.ts +1 -1
  101. package/dist/unifi/providers.d.ts.map +1 -1
  102. package/dist/unifi/scan-source.d.ts +11 -0
  103. package/dist/unifi/scan-source.d.ts.map +1 -0
  104. package/dist/unifi/traffic-matching-list-drift.d.ts +22 -0
  105. package/dist/unifi/traffic-matching-list-drift.d.ts.map +1 -0
  106. package/dist/unifi/traffic-matching-list-form.d.ts +56 -0
  107. package/dist/unifi/traffic-matching-list-form.d.ts.map +1 -0
  108. package/dist/unifi/traffic-matching-list.d.ts +51 -0
  109. package/dist/unifi/traffic-matching-list.d.ts.map +1 -0
  110. package/dist/unifi/wifi-broadcast-drift.d.ts +22 -0
  111. package/dist/unifi/wifi-broadcast-drift.d.ts.map +1 -0
  112. package/dist/unifi/wifi-broadcast-form.d.ts +127 -0
  113. package/dist/unifi/wifi-broadcast-form.d.ts.map +1 -0
  114. package/dist/unifi/wifi-broadcast.d.ts +73 -0
  115. package/dist/unifi/wifi-broadcast.d.ts.map +1 -0
  116. package/docs/unifi-acl-rule.md +122 -0
  117. package/docs/unifi-dns-policy.md +75 -0
  118. package/docs/unifi-firewall-policy.md +109 -0
  119. package/docs/unifi-traffic-matching-list.md +82 -0
  120. package/docs/unifi-wifi.md +120 -0
  121. package/docs/unifi.md +10 -5
  122. package/package.json +6 -2
  123. package/src/ceph/auth-entity.ts +74 -0
  124. package/src/ceph/ceph-argv-config.ts +78 -0
  125. package/src/ceph/ceph-argv.test.ts +226 -0
  126. package/src/ceph/ceph-argv.ts +189 -0
  127. package/src/ceph/ceph-auth-form.test.ts +103 -0
  128. package/src/ceph/ceph-auth-form.ts +107 -0
  129. package/src/ceph/ceph-auth-parse.test.ts +155 -0
  130. package/src/ceph/ceph-auth-parse.ts +121 -0
  131. package/src/ceph/ceph-auth-reconcile-secrecy.test.ts +82 -0
  132. package/src/ceph/ceph-auth-reconcile.test.ts +233 -0
  133. package/src/ceph/ceph-auth-reconcile.ts +119 -0
  134. package/src/ceph/ceph-config-options.test.ts +44 -0
  135. package/src/ceph/ceph-config-options.ts +36 -0
  136. package/src/ceph/ceph-key-leak-assert.ts +35 -0
  137. package/src/ceph/ceph-no-output-logging.test.ts +52 -0
  138. package/src/ceph/ceph-transport.test.ts +125 -0
  139. package/src/ceph/ceph-transport.ts +117 -0
  140. package/src/ceph/fake-ceph-dial.ts +55 -0
  141. package/src/ceph/index.ts +12 -0
  142. package/src/index.ts +1 -0
  143. package/src/proxmox/qemu-volume.test.ts +153 -4
  144. package/src/proxmox/qemu-volume.ts +71 -14
  145. package/src/talos/credentials-write.test.ts +81 -0
  146. package/src/talos/credentials-write.ts +95 -0
  147. package/src/talos/credentials.test.ts +157 -0
  148. package/src/talos/credentials.ts +160 -90
  149. package/src/talos/fake-process.ts +94 -0
  150. package/src/talos/index.ts +39 -4
  151. package/src/talos/kubeconfig-attrs.ts +55 -0
  152. package/src/talos/kubeconfig.test.ts +256 -0
  153. package/src/talos/kubeconfig.ts +170 -90
  154. package/src/talos/machine-config-fixtures.ts +86 -0
  155. package/src/talos/machine-config-poll.test.ts +57 -0
  156. package/src/talos/machine-config-poll.ts +82 -0
  157. package/src/talos/machine-config-read.ts +118 -0
  158. package/src/talos/resource.ts +19 -0
  159. package/src/talos/secrets-gate.test.ts +63 -0
  160. package/src/talos/talos-bootstrap-etcd.ts +71 -0
  161. package/src/talos/talos-bootstrap.test.ts +218 -0
  162. package/src/talos/talos-bootstrap.ts +151 -45
  163. package/src/talos/talos-cluster-health.test.ts +143 -0
  164. package/src/talos/talos-cluster-health.ts +91 -28
  165. package/src/talos/talos-errors.ts +85 -0
  166. package/src/talos/talos-machine-config.test.ts +189 -0
  167. package/src/talos/talos-machine-config.ts +102 -88
  168. package/src/talos/talosctl.ts +8 -0
  169. package/src/talos/values.test.ts +34 -6
  170. package/src/talos/values.ts +41 -7
  171. package/src/unifi/acl-rule-drift.ts +57 -0
  172. package/src/unifi/acl-rule-form.ts +135 -0
  173. package/src/unifi/acl-rule-ordering-form.ts +79 -0
  174. package/src/unifi/acl-rule-ordering.test.ts +141 -0
  175. package/src/unifi/acl-rule-ordering.ts +70 -0
  176. package/src/unifi/acl-rule.test.ts +183 -0
  177. package/src/unifi/acl-rule.ts +61 -0
  178. package/src/unifi/discriminated-filter-decode.test.ts +134 -0
  179. package/src/unifi/dns-policy-drift.ts +48 -0
  180. package/src/unifi/dns-policy-form.ts +142 -0
  181. package/src/unifi/dns-policy.test.ts +154 -0
  182. package/src/unifi/dns-policy.ts +67 -0
  183. package/src/unifi/firewall-policy-drift.test.ts +151 -0
  184. package/src/unifi/firewall-policy-drift.ts +55 -0
  185. package/src/unifi/firewall-policy-filter-roundtrip.test.ts +143 -0
  186. package/src/unifi/firewall-policy-form.ts +146 -0
  187. package/src/unifi/firewall-policy-ordering-form.ts +111 -0
  188. package/src/unifi/firewall-policy-ordering.test.ts +185 -0
  189. package/src/unifi/firewall-policy-ordering.ts +87 -0
  190. package/src/unifi/firewall-policy.test.ts +183 -0
  191. package/src/unifi/firewall-policy.ts +73 -0
  192. package/src/unifi/index.ts +63 -0
  193. package/src/unifi/paginate.test.ts +24 -0
  194. package/src/unifi/paginate.ts +15 -3
  195. package/src/unifi/providers.ts +19 -1
  196. package/src/unifi/scan-source.ts +64 -0
  197. package/src/unifi/traffic-matching-list-drift.ts +40 -0
  198. package/src/unifi/traffic-matching-list-form.ts +77 -0
  199. package/src/unifi/traffic-matching-list.test.ts +202 -0
  200. package/src/unifi/traffic-matching-list.ts +78 -0
  201. package/src/unifi/wifi-broadcast-details-call.test.ts +92 -0
  202. package/src/unifi/wifi-broadcast-drift.ts +69 -0
  203. package/src/unifi/wifi-broadcast-form.ts +211 -0
  204. package/src/unifi/wifi-broadcast-secrets.test.ts +145 -0
  205. package/src/unifi/wifi-broadcast.test.ts +155 -0
  206. package/src/unifi/wifi-broadcast.ts +90 -0
  207. package/src/unifi/write-op-reference.test.ts +8 -54
@@ -1,12 +1,22 @@
1
1
  export type Disk = {
2
- /** `fresh`: either new-disk spelling above. `volume`: an existing volume, `storage:volname,...`. */
2
+ /** `fresh`: a new-disk spelling (`storage:GiB`, `storage:cloudinit`, or `storage:0,import-from=...`
3
+ * possibly with more options). `volume`: an existing volume, `storage:volname,...`. */
3
4
  readonly kind: 'fresh' | 'volume';
4
5
  readonly source: string;
5
6
  readonly volname: string;
6
7
  readonly size: string | undefined;
7
8
  readonly options: Map<string, string>;
8
9
  };
9
- /** `storage:volname,k=v,...` (or one of the two "fresh" spellings) into its comparable parts. */
10
+ /**
11
+ * `storage:volname,k=v,...` (or one of the "fresh" spellings) into its comparable parts.
12
+ * ⚠️ THE IMPORT SPELLING IS DETECTED AFTER THE GENERAL SPLIT, NOT BY ITS OWN REGEX: `import-from`'s
13
+ * value can itself contain a colon (e.g. `cephfs-tb4:import/talos-factory.raw`) and other options
14
+ * can come before or after it, so a regex anchored on `:0,import-from=` right after the colon (as
15
+ * the first cut had) misses that ordering and swallows everything after it into one opaque match.
16
+ * Splitting on commas like any `volume` spelling first, THEN checking for a literal `"0"` volname
17
+ * plus an `import-from` key among the parsed options, catches every ordering and keeps every other
18
+ * declared option (`iothread=1`, `discard=on`, …) visible to `judgeDisk` instead of swallowed.
19
+ */
10
20
  export declare const parseDisk: (text: string) => Disk;
11
21
  export type DiskVerdict = {
12
22
  readonly refuse?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"qemu-volume.d.ts","sourceRoot":"","sources":["../../src/proxmox/qemu-volume.ts"],"names":[],"mappings":"AA8BA,MAAM,MAAM,IAAI,GAAG;IACjB,oGAAoG;IACpG,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,IAwBxC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iGAAiG;IACjG,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAmBF,eAAO,MAAM,SAAS,QAAS,MAAM,YAAY,MAAM,QAAQ,MAAM,KAAG,WA+BvE,CAAC"}
1
+ {"version":3,"file":"qemu-volume.d.ts","sourceRoot":"","sources":["../../src/proxmox/qemu-volume.ts"],"names":[],"mappings":"AA+DA,MAAM,MAAM,IAAI,GAAG;IACjB;4FACwF;IACxF,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,IA4BxC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iGAAiG;IACjG,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAmBF,eAAO,MAAM,SAAS,QAAS,MAAM,YAAY,MAAM,QAAQ,MAAM,KAAG,WAyCvE,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * The write half of Talos's OpenBao KV access — split out of credentials.ts (2026-09-26,
3
+ * K-talos-first-boot) once it needed its own header, the same reason machine-config-read.ts,
4
+ * machine-config-poll.ts and talos-errors.ts were split out of talos-machine-config.ts before it.
5
+ * `credentials.ts` stays the read side (mint a talosconfig, read a KV value); this file is the one
6
+ * place anything in this package ever writes TO OpenBao.
7
+ *
8
+ * ★ FIRST CALLER: `Talos.Kubeconfig` (kubeconfig.ts) writing the admin kubeconfig it generates at
9
+ * cluster bring-up into the vault instead of an un-vaulted host `runtimePath` — see that file's
10
+ * own header. `Ceph.AuthEntity` (K-A4, a separate design/PR) is expected to need the same shape
11
+ * for its own vault-written entity keys; this is not yet shared with it on purpose — two callers
12
+ * is the point at which sharing stops being speculative.
13
+ */
14
+ import * as Effect from 'effect/Effect';
15
+ import type * as Scope from 'effect/Scope';
16
+ import * as ChildProcessSpawner from 'effect/unstable/process/ChildProcessSpawner';
17
+ /**
18
+ * A fresh, unguessable temp path for SOME OTHER PROCESS (talosctl) to create — unlike
19
+ * `credentials.ts`'s `mintKvTempFile`, this does NOT pre-create the file with `wx`, because the
20
+ * caller here is capturing a command's OWN output rather than writing known content itself. The
21
+ * random UUIDv7 name is the only pre-fabrication guard (an attacker cannot pre-plant a symlink at a
22
+ * path it cannot predict) — first used by `kubeconfig.ts` to capture `talosctl kubeconfig`'s
23
+ * generated file before reading it back and writing it into the vault.
24
+ */
25
+ export declare const reservedTempPath: (label: string) => Effect.Effect<{
26
+ readonly path: string;
27
+ }, never, Scope.Scope>;
28
+ /**
29
+ * Write one field of an OpenBao KV-v2 value from `value` — never argv, the mirror image of
30
+ * `credentials.ts`'s `readKvValue`.
31
+ *
32
+ * ⛔ C2 FIX (LAND red team, 2026-09-26) — `field=@-` IS WRONG AND WAS NEVER MEASURED. `@value` means
33
+ * "read a file at this path"; a literal path of `-` is not the stdin convention for `@` — it is
34
+ * just a file named `-`. MEASURED against the estate's OpenBao v2.6.2 binary (isolated in-memory
35
+ * dev server, `env -i`, scratch HOME, no estate credentials involved; server removed after):
36
+ * `field=@-` exits 1 with `invalid key/value pair "field=@-": error reading file: open -: no
37
+ * such file or directory`, and if a file literally named `-` exists in the working directory it
38
+ * silently stores THAT file's bytes instead. `field=-` (no `@`) is Vault/OpenBao's own stdin
39
+ * convention and was confirmed against the same binary to read the piped bytes correctly. Every
40
+ * `Talos.Kubeconfig` create failed here — AFTER `talosctl kubeconfig` had already issued a fresh
41
+ * admin client certificate, which cannot be revoked.
42
+ * ⛔ stderr ONLY ON FAILURE — same rule as `readKvValue`: never echo what was being written, on
43
+ * success or failure.
44
+ */
45
+ export declare const writeKvValue: (mount: string, key: string, field: string, value: string) => Effect.Effect<void, Error, ChildProcessSpawner.ChildProcessSpawner>;
46
+ //# sourceMappingURL=credentials-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials-write.d.ts","sourceRoot":"","sources":["../../src/talos/credentials-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAG3C,OAAO,KAAK,mBAAmB,MAAM,6CAA6C,CAAC;AAEnF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,UACpB,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAS1D,CAAC;AAEL;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,YAAY,UAChB,MAAM,OACR,MAAM,SACJ,MAAM,SACN,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,mBAAmB,CAAC,mBAAmB,CAgCjE,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import * as Effect from 'effect/Effect';
2
+ import type * as Scope from 'effect/Scope';
2
3
  import * as ChildProcessSpawner from 'effect/unstable/process/ChildProcessSpawner';
3
4
  /** Where credentials come from. HomeFlare-specific mount names live in the stack, not here. */
4
5
  export type TalosTarget = {
@@ -7,10 +8,10 @@ export type TalosTarget = {
7
8
  /** Logical cluster name — safe to persist and log. */
8
9
  readonly cluster: string;
9
10
  /**
10
- * Path under the mount for the talosconfig YAML.
11
- *
12
- * ⚠️ DEFAULT IS REASONED. The first real deploy will confirm or correct the path; a wrong path
13
- * fails closed with a bao error rather than writing an empty talosconfig.
11
+ * Path under the mount for the talosconfig YAML. Default `'talosconfig'` — FIXED 2026-09-26;
12
+ * the shipped default was `'data/talosconfig'`, which `bao kv get` turned into
13
+ * `<mount>/data/data/talosconfig` (see the ⚠️ above). It failed closed rather than reading an
14
+ * empty talosconfig, but it would have blocked the very first deploy.
14
15
  */
15
16
  readonly talosconfigKey?: string;
16
17
  };
@@ -18,13 +19,54 @@ export type TalosCredential = {
18
19
  /** Absolute path to a temp talosconfig. ⛔ NEVER PERSIST, NEVER LOG CONTENTS. */
19
20
  readonly talosconfigPath: string;
20
21
  };
22
+ /**
23
+ * Default OpenBao KV path (under `target.mount`) for the admin kubeconfig `Talos.Kubeconfig`
24
+ * writes once at cluster bring-up. See kubeconfig.ts's own header (K-talos-first-boot, 2026-09-26)
25
+ * and docs/plans/2026-09-26-talos-secrets-flow.md's O1 key list.
26
+ */
27
+ export declare const DEFAULT_KUBECONFIG_KEY = "kubeconfig";
28
+ /**
29
+ * Read one OpenBao KV-v2 value and return the first of `fields` that is a non-empty string.
30
+ *
31
+ * ★ THE ONE PLACE THIS PACKAGE SHELLS TO `bao` — talosconfig, per-node machine config and any
32
+ * future KV-backed Talos material (secrets.yaml, ceph entity keys) all read through this,
33
+ * so there is exactly one spot that must never echo a KV value on failure.
34
+ * ⛔ stderr ONLY ON FAILURE. stdout may hold the very secret this call exists to fetch.
35
+ */
36
+ export declare const readKvValue: (mount: string, key: string, fields: readonly string[]) => Effect.Effect<string, Error, ChildProcessSpawner.ChildProcessSpawner>;
37
+ /**
38
+ * Write `raw` to a session-temp, 0600, exclusively-created file whose lifetime is the CALLER's
39
+ * `Effect.scoped`, not this call's. See the ⛔ C1 FIX note at the top of this file.
40
+ *
41
+ * ⛔ 0600, CREATED EXCLUSIVELY, AND `Bun.write` CANNOT DO EITHER. This file can hold a cluster
42
+ * admin client certificate or a machine config's bootstrap token. `Bun.write` takes no mode, so
43
+ * it lands at the process umask — world-readable on this estate — for as long as the resource
44
+ * runs. The name is unguessable, and "unguessable" is not a permission.
45
+ * ⚠️ `wx` IS THE OTHER HALF. `O_EXCL` means this cannot be made to write through a path an
46
+ * attacker pre-created (the classic /tmp symlink race), and with a UUIDv7 name a collision is a
47
+ * genuine error rather than something to paper over.
48
+ * ⚠️ A HARD KILL (SIGKILL, power loss) skips the finalizer and leaves the file behind. 0600 is
49
+ * what makes that survivable rather than a disclosure.
50
+ */
51
+ export declare const mintKvTempFile: (raw: string, label: string) => Effect.Effect<{
52
+ readonly path: string;
53
+ }, Error, Scope.Scope>;
21
54
  /**
22
55
  * Mint one talosconfig file for `target`.
23
56
  *
24
- * ★ SHELLS OUT TO `bao` RATHER THAN SPEAKING THE HTTP API — same reasoning as proxmox credentials.
25
- * The estate's BAO_ADDR / BAO_NAMESPACE / approle contract already lives in that binary.
57
+ * ⛔ CALLERS MUST WRAP THEIR WHOLE USE OF `credential.talosconfigPath` — not just this call — in
58
+ * `Effect.scoped(...)`. This function's own `Scope.Scope` requirement is what makes that the
59
+ * caller's job instead of a lie this function tells itself; see the header above.
60
+ */
61
+ export declare const mintTalosconfig: (target: TalosTarget) => Effect.Effect<TalosCredential, Error, ChildProcessSpawner.ChildProcessSpawner | Scope.Scope>;
62
+ /**
63
+ * Mint one temp kubeconfig file from the vault copy `Talos.Kubeconfig` writes at bring-up
64
+ * (K-talos-first-boot, 2026-09-26) — the consumer-side counterpart to {@link mintTalosconfig},
65
+ * named as the future seam for `Kubernetes.ClusterAdapter` in
66
+ * docs/plans/2026-09-26-talos-secrets-flow.md ("consumers mint it the way the talosconfig is
67
+ * minted"). Not yet wired to that adapter — this only makes the read+materialize step exist.
26
68
  */
27
- export declare const mintTalosconfig: (target: TalosTarget) => Effect.Effect<{
28
- talosconfigPath: string;
29
- }, Error | import("effect/PlatformError").PlatformError, ChildProcessSpawner.ChildProcessSpawner>;
69
+ export declare const mintKubeconfig: (target: TalosTarget, key?: string) => Effect.Effect<{
70
+ readonly path: string;
71
+ }, Error, ChildProcessSpawner.ChildProcessSpawner | Scope.Scope>;
30
72
  //# sourceMappingURL=credentials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/talos/credentials.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,mBAAmB,MAAM,6CAA6C,CAAC;AAEnF,+FAA+F;AAC/F,MAAM,MAAM,WAAW,GAAG;IACxB,gEAAgE;IAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,WAAY,WAAW;;iGAsFhD,CAAC"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/talos/credentials.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAG3C,OAAO,KAAK,mBAAmB,MAAM,6CAA6C,CAAC;AAEnF,+FAA+F;AAC/F,MAAM,MAAM,WAAW,GAAG;IACxB,gEAAgE;IAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAEnD;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,UACf,MAAM,OACR,MAAM,UACH,SAAS,MAAM,EAAE,KACxB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,mBAAmB,CAAC,mBAAmB,CAgDnE,CAAC;AAEL;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,cAAc,QACpB,MAAM,SACJ,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAqB1D,CAAC;AAEL;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,WAClB,WAAW,KAClB,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,EAAE,mBAAmB,CAAC,mBAAmB,GAAG,KAAK,CAAC,KAAK,CAO3F,CAAC;AAEJ;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,WACjB,WAAW,mBAElB,MAAM,CAAC,MAAM,CACd;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACzB,KAAK,EACL,mBAAmB,CAAC,mBAAmB,GAAG,KAAK,CAAC,KAAK,CAIpD,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * A fake `ChildProcessSpawner` for offline Talos tests — no real `bao` or `talosctl` process ever
3
+ * starts. Shared by credentials.test.ts and talos-machine-config.test.ts (2026-09-26, K-A3);
4
+ * this package had NO process-level test fake before this file — every Talos resource file spawns
5
+ * a real binary in production and none of that was previously exercised offline.
6
+ *
7
+ * ★ A FULL FAKE SERVICE, NOT A REAL SPAWN WITH A FIXTURE EXECUTABLE ON `PATH`. The alternative —
8
+ * a tiny fake `bao`/`talosctl` script and a mutated `process.env.PATH` — spawns a REAL OS
9
+ * process and mutates process-global state for the test's duration, which is exactly the kind
10
+ * of cross-test interference the house rules ask tests to avoid. `ChildProcessSpawner.make`
11
+ * takes just a `spawn` function and derives everything else, so a fake `spawn` is the whole cost.
12
+ */
13
+ import * as Effect from 'effect/Effect';
14
+ import * as Stream from 'effect/Stream';
15
+ import type { Command } from 'effect/unstable/process/ChildProcess';
16
+ import * as ChildProcessSpawner from 'effect/unstable/process/ChildProcessSpawner';
17
+ export type FakeResult = {
18
+ readonly stdout?: string;
19
+ readonly stderr?: string;
20
+ readonly exitCode?: number;
21
+ };
22
+ export type FakeCall = {
23
+ readonly command: string;
24
+ readonly args: readonly string[];
25
+ /**
26
+ * Decoded stdin text, present only when the real caller piped a `Stream` in (K-talos-first-boot,
27
+ * `credentials-write.ts`'s `writeKvValue`) — the whole reason this fake exists is to prove a
28
+ * value went in via stdin and never via argv, so a test needs to see it.
29
+ */
30
+ readonly stdin?: string;
31
+ };
32
+ export type FakeHandler = (call: FakeCall) => FakeResult;
33
+ /**
34
+ * Build a fake `ChildProcessSpawner.Service` from `handler`, which sees every command's
35
+ * executable + argv (+ decoded stdin, when piped) and returns canned stdout/stderr/exitCode.
36
+ * `credentials.ts` and `talosctl.ts` only ever build `StandardCommand`s (never a piped command),
37
+ * so that is the only shape this fake accepts — a `PipedCommand` is a test-authoring mistake, not
38
+ * something to fake.
39
+ */
40
+ export declare const fakeSpawner: (handler: FakeHandler, calls?: FakeCall[]) => {
41
+ spawn(command: Command): Effect.Effect<ChildProcessSpawner.ChildProcessHandle, import("effect/PlatformError").PlatformError, import("effect/Scope").Scope>;
42
+ exitCode(command: Command): Effect.Effect<ChildProcessSpawner.ExitCode, import("effect/PlatformError").PlatformError>;
43
+ streamString(command: Command, options?: {
44
+ readonly includeStderr?: boolean | undefined;
45
+ }): Stream.Stream<string, import("effect/PlatformError").PlatformError>;
46
+ streamLines(command: Command, options?: {
47
+ readonly includeStderr?: boolean | undefined;
48
+ }): Stream.Stream<string, import("effect/PlatformError").PlatformError>;
49
+ lines(command: Command, options?: {
50
+ readonly includeStderr?: boolean | undefined;
51
+ }): Effect.Effect<Array<string>, import("effect/PlatformError").PlatformError>;
52
+ string(command: Command, options?: {
53
+ readonly includeStderr?: boolean | undefined;
54
+ }): Effect.Effect<string, import("effect/PlatformError").PlatformError>;
55
+ };
56
+ //# sourceMappingURL=fake-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-process.d.ts","sourceRoot":"","sources":["../../src/talos/fake-process.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,KAAK,mBAAmB,MAAM,6CAA6C,CAAC;AAEnF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,QAAQ,KAAK,UAAU,CAAC;AAsCzD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,YAAa,WAAW,UAAS,QAAQ,EAAE;;;;;;;;;;;;;;;CAehE,CAAC"}
@@ -5,11 +5,26 @@
5
5
  * These are the symbols a real stack consumes; the rest of the files are internals a
6
6
  * provider needs but a consumer should not depend on. An `export *` here would publish
7
7
  * every helper as API and make the next refactor a breaking change.
8
+ * ★ `Talos.MachineConfig`'S RESOURCE CLASS JOINED ITS PROVIDER 2026-09-26 (K-A3) — until now this
9
+ * barrel exported only `Talos*Provider`, which builds the provider but gives a consuming stack
10
+ * nothing to `new` or call to actually DECLARE a row (the same gap proxmox/index.ts's own header
11
+ * calls out for `ProxmoxVm`). MachineConfig is safe to declare today: it fails closed on a digest
12
+ * mismatch before touching a node, and its cold-start read never silently adopts (PR 307 fix-first
13
+ * #1, machine-config-read.ts's own header).
14
+ * ★ BOOTSTRAP, CLUSTERHEALTH AND KUBECONFIG JOIN THEM (K-talos-first-boot, 2026-09-26) — PR 307's
15
+ * red team (fix-first #3) held these back because `Talos.Bootstrap` could re-run `talosctl
16
+ * bootstrap` against an already-bootstrapped cluster and `Talos.Kubeconfig` wrote a cluster-admin
17
+ * kubeconfig to un-vaulted host disk. Both are fixed now: bootstrap's "once means once" invariant
18
+ * (talos-bootstrap.ts's own header) and kubeconfig landing in OpenBao, written once at bring-up
19
+ * (kubeconfig.ts's own header) — plus `Talos.ClusterHealth`'s error handling no longer conflates a
20
+ * vault/transport failure with "cluster not healthy yet" (talos-cluster-health.ts's own header).
8
21
  * ★ Anything unlisted is still reachable by path if you genuinely need it — that is a
9
22
  * deliberate, visible act rather than an accident of barrelling.
10
23
  */
11
- export { TalosKubeconfigProvider } from './kubeconfig.ts';
12
- export { TalosBootstrapProvider } from './talos-bootstrap.ts';
13
- export { TalosClusterHealthProvider } from './talos-cluster-health.ts';
14
- export { TalosMachineConfigProvider } from './talos-machine-config.ts';
24
+ export type { TalosCredential, TalosTarget } from './credentials.ts';
25
+ export { type KubeconfigAttributes, type KubeconfigProps, TalosKubeconfig, TalosKubeconfigProvider, } from './kubeconfig.ts';
26
+ export type { ApplyMode, WithTarget } from './resource.ts';
27
+ export { type BootstrapAttributes, type BootstrapProps, TalosBootstrap, TalosBootstrapProvider, } from './talos-bootstrap.ts';
28
+ export { type ClusterHealthAttributes, type ClusterHealthProps, TalosClusterHealth, TalosClusterHealthProvider, } from './talos-cluster-health.ts';
29
+ export { type MachineConfigAttributes, type MachineConfigProps, TalosMachineConfig, TalosMachineConfigProvider, } from './talos-machine-config.ts';
15
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/talos/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/talos/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,eAAe,EACf,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,cAAc,EACd,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC"}