@homeflare/alchemy 0.47.0 → 0.48.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 (130) hide show
  1. package/README.md +6 -32
  2. package/dist/talos/bao-env.d.ts +7 -0
  3. package/dist/talos/bao-env.d.ts.map +1 -0
  4. package/dist/talos/cluster-adapter-errors.d.ts +134 -0
  5. package/dist/talos/cluster-adapter-errors.d.ts.map +1 -0
  6. package/dist/talos/cluster-adapter.d.ts +115 -0
  7. package/dist/talos/cluster-adapter.d.ts.map +1 -0
  8. package/dist/talos/cluster-identity.d.ts +28 -0
  9. package/dist/talos/cluster-identity.d.ts.map +1 -0
  10. package/dist/talos/cluster-transport.d.ts +64 -0
  11. package/dist/talos/cluster-transport.d.ts.map +1 -0
  12. package/dist/talos/credentials-write.d.ts.map +1 -1
  13. package/dist/talos/credentials.d.ts +10 -19
  14. package/dist/talos/credentials.d.ts.map +1 -1
  15. package/dist/talos/fake-apiserver.d.ts +9 -0
  16. package/dist/talos/fake-apiserver.d.ts.map +1 -0
  17. package/dist/talos/index.d.ts +7 -0
  18. package/dist/talos/index.d.ts.map +1 -1
  19. package/dist/talos/index.js +669 -167
  20. package/dist/talos/index.js.map +22 -10
  21. package/dist/talos/kubeconfig-attrs.d.ts +14 -0
  22. package/dist/talos/kubeconfig-attrs.d.ts.map +1 -1
  23. package/dist/talos/kubeconfig-doc.d.ts +23 -0
  24. package/dist/talos/kubeconfig-doc.d.ts.map +1 -0
  25. package/dist/talos/kubeconfig.d.ts +0 -12
  26. package/dist/talos/kubeconfig.d.ts.map +1 -1
  27. package/dist/talos/literal-connection.d.ts +16 -0
  28. package/dist/talos/literal-connection.d.ts.map +1 -0
  29. package/dist/talos/machine-config-read.d.ts +1 -1
  30. package/dist/talos/machine-config-read.d.ts.map +1 -1
  31. package/dist/talos/mint-temp-file.d.ts +20 -0
  32. package/dist/talos/mint-temp-file.d.ts.map +1 -0
  33. package/dist/talos/node-temp.harness.d.ts +2 -0
  34. package/dist/talos/node-temp.harness.d.ts.map +1 -0
  35. package/dist/talos/talos-bootstrap-etcd.d.ts +1 -1
  36. package/dist/talos/talos-bootstrap-etcd.d.ts.map +1 -1
  37. package/dist/talos/talos-cluster-health.d.ts +15 -15
  38. package/dist/talos/talos-cluster-health.d.ts.map +1 -1
  39. package/dist/talos/talos-cluster-identity.d.ts +65 -0
  40. package/dist/talos/talos-cluster-identity.d.ts.map +1 -0
  41. package/dist/talos/talosctl-binary.d.ts +43 -0
  42. package/dist/talos/talosctl-binary.d.ts.map +1 -0
  43. package/dist/talos/talosctl.d.ts +12 -15
  44. package/dist/talos/talosctl.d.ts.map +1 -1
  45. package/dist/talos/trust-boundary.d.ts +8 -0
  46. package/dist/talos/trust-boundary.d.ts.map +1 -0
  47. package/dist/talos/values.d.ts.map +1 -1
  48. package/dist/talos/yaml-parse.d.ts +3 -0
  49. package/dist/talos/yaml-parse.d.ts.map +1 -0
  50. package/dist/verify/fake-engine.d.ts +2 -0
  51. package/dist/verify/fake-engine.d.ts.map +1 -1
  52. package/docs/peers.md +32 -5
  53. package/docs/talos-openbao-adapter.md +44 -0
  54. package/docs/upstream-conformance-bun.md +61 -24
  55. package/package.json +116 -2
  56. package/src/talos/bao-env.ts +16 -0
  57. package/src/talos/bao-vetting.test.ts +97 -0
  58. package/src/talos/cluster-adapter-deadline.test.ts +110 -0
  59. package/src/talos/cluster-adapter-errors.ts +192 -0
  60. package/src/talos/cluster-adapter-move.test.ts +129 -0
  61. package/src/talos/cluster-adapter-reconcile.test.ts +165 -0
  62. package/src/talos/cluster-adapter-refusals.test.ts +102 -0
  63. package/src/talos/cluster-adapter-rename.test.ts +87 -0
  64. package/src/talos/cluster-adapter-secrecy.test.ts +243 -0
  65. package/src/talos/cluster-adapter.fixtures.ts +125 -0
  66. package/src/talos/cluster-adapter.test.ts +240 -0
  67. package/src/talos/cluster-adapter.ts +249 -0
  68. package/src/talos/cluster-identity.ts +63 -0
  69. package/src/talos/cluster-transport.ts +110 -0
  70. package/src/talos/credentials-write.ts +27 -5
  71. package/src/talos/credentials.ts +51 -45
  72. package/src/talos/fake-apiserver.ts +55 -0
  73. package/src/talos/fake-process.ts +47 -1
  74. package/src/talos/index.ts +32 -0
  75. package/src/talos/kubeconfig-adapter.test.ts +37 -0
  76. package/src/talos/kubeconfig-attrs.ts +12 -28
  77. package/src/talos/kubeconfig-doc.ts +74 -0
  78. package/src/talos/kubeconfig.fixtures.ts +52 -0
  79. package/src/talos/kubeconfig.test.ts +6 -54
  80. package/src/talos/kubeconfig.ts +18 -34
  81. package/src/talos/literal-connection.ts +59 -0
  82. package/src/talos/mint-temp-file.ts +56 -0
  83. package/src/talos/node-connect.harness.ts +78 -0
  84. package/src/talos/node-connect.test.ts +27 -0
  85. package/src/talos/node-temp.harness.ts +40 -0
  86. package/src/talos/node-temp.test.ts +26 -0
  87. package/src/talos/talos-cluster-health-declare.test.ts +54 -0
  88. package/src/talos/talos-cluster-health-literal.test.ts +69 -0
  89. package/src/talos/talos-cluster-health.test.ts +104 -18
  90. package/src/talos/talos-cluster-health.ts +46 -14
  91. package/src/talos/talos-cluster-identity.test.ts +96 -0
  92. package/src/talos/talos-cluster-identity.ts +130 -0
  93. package/src/talos/talosctl-binary.ts +150 -0
  94. package/src/talos/talosctl-vetting.test.ts +212 -0
  95. package/src/talos/talosctl.test.ts +110 -0
  96. package/src/talos/talosctl.ts +101 -15
  97. package/src/talos/trust-boundary.test.ts +17 -0
  98. package/src/talos/trust-boundary.ts +45 -0
  99. package/src/talos/values.ts +5 -12
  100. package/src/talos/yaml-parse.test.ts +41 -0
  101. package/src/talos/yaml-parse.ts +28 -0
  102. package/src/verify/fake-engine.ts +10 -0
  103. package/dist/talos/fake-process.d.ts +0 -56
  104. package/dist/talos/fake-process.d.ts.map +0 -1
  105. package/dist/talos/machine-config-fixtures.d.ts +0 -60
  106. package/dist/talos/machine-config-fixtures.d.ts.map +0 -1
  107. package/src/postgres/fixtures/pg-REL_18_6-acl.h.txt +0 -147
  108. package/src/postgres/fixtures/pg-REL_18_6-aclexplode-func.txt +0 -31
  109. package/src/postgres/fixtures/pg-REL_18_6-alter-default-privileges-synopsis.txt +0 -82
  110. package/src/postgres/fixtures/pg-REL_18_6-alter_role.sgml.txt +0 -44
  111. package/src/postgres/fixtures/pg-REL_18_6-create-database-synopsis.txt +0 -26
  112. package/src/postgres/fixtures/pg-REL_18_6-create_role.sgml.txt +0 -26
  113. package/src/postgres/fixtures/pg-REL_18_6-grant-synopsis.txt +0 -95
  114. package/src/postgres/fixtures/pg-REL_18_6-pg_attribute.h.txt +0 -24
  115. package/src/postgres/fixtures/pg-REL_18_6-pg_auth_members.h.txt +0 -62
  116. package/src/postgres/fixtures/pg-REL_18_6-pg_authid.h.txt +0 -70
  117. package/src/postgres/fixtures/pg-REL_18_6-pg_class.h.txt +0 -33
  118. package/src/postgres/fixtures/pg-REL_18_6-pg_database.h.txt +0 -67
  119. package/src/postgres/fixtures/pg-REL_18_6-pg_default_acl.h.txt +0 -81
  120. package/src/postgres/fixtures/pg-REL_18_6-pg_namespace.h.txt +0 -28
  121. package/src/postgres/fixtures/pg-REL_18_6-revoke-synopsis.txt +0 -124
  122. package/src/release/fixtures/openbao/checksums.txt +0 -83
  123. package/src/release/fixtures/openbao/checksums.txt.gpgsig +0 -0
  124. package/src/release/fixtures/openbao/darwin-assets.txt +0 -12
  125. package/src/release/fixtures/openbao/openbao-gpg-pub-20240618.asc +0 -109
  126. package/src/release/fixtures/victoria/darwin-arm64-assets.txt +0 -22
  127. package/src/release/fixtures/victoria/victoria-logs-darwin-arm64-v1.52.0_checksums.txt +0 -2
  128. package/src/release/fixtures/victoria/victoria-metrics-darwin-arm64-v1.151.0_checksums.txt +0 -2
  129. package/src/release/fixtures/victoria/victoria-traces-darwin-arm64-v0.10.0_checksums.txt +0 -2
  130. package/src/release/fixtures/victoria/vmutils-darwin-arm64-v1.151.0_checksums.txt +0 -8
@@ -1,3 +1,17 @@
1
+ /**
2
+ * `Talos.Kubeconfig`'s attribute builder — split out of kubeconfig.ts (LAND, 2026-09-26, C1/I2
3
+ * fixes) once fixing those findings pushed the file over the 250-line cap. Only `import type`
4
+ * comes back from kubeconfig.ts, so there is no runtime cycle.
5
+ *
6
+ * ⛔ NO `connection` HERE. A connection names the PHYSICAL cluster (`{ kind, uid }`,
7
+ * cluster-adapter.ts's identity rule) and the uid is only knowable from the cluster, which does
8
+ * not exist yet when this resource writes the vault key. Workloads get their connection from the
9
+ * operator's pinned literal (`talosOpenBaoConnection(uid)`) or `Talos.ClusterHealth`'s
10
+ * pass-through; `Talos.ClusterIdentity` publishes `{ uid }` only; a name-only connection
11
+ * (`cluster` present) is refused by the adapter as legacy. Neither the
12
+ * stock `kubeconfig` kind (an absent path falls back to `$KUBECONFIG`) nor `client-cert` (PEM on
13
+ * every workload's attributes, `Connection.ts` v2.0.0-beta.79 lines 12-14) is ever used.
14
+ */
1
15
  import type { KubeconfigAttributes, KubeconfigProps } from './kubeconfig.ts';
2
16
  /** Parse `raw` kubeconfig YAML into public, persistable attributes, or `undefined` if it fails to. */
3
17
  export declare const buildAttrs: (raw: string, props: KubeconfigProps) => KubeconfigAttributes | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"kubeconfig-attrs.d.ts","sourceRoot":"","sources":["../../src/talos/kubeconfig-attrs.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AA+B7E,sGAAsG;AACtG,eAAO,MAAM,UAAU,QAChB,MAAM,SACJ,eAAe,KACrB,oBAAoB,GAAG,SAWzB,CAAC"}
1
+ {"version":3,"file":"kubeconfig-attrs.d.ts","sourceRoot":"","sources":["../../src/talos/kubeconfig-attrs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAU7E,sGAAsG;AACtG,eAAO,MAAM,UAAU,QAChB,MAAM,SACJ,eAAe,KACrB,oBAAoB,GAAG,SAUzB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * In-memory kubeconfig parse for `talos-openbao` connect.
3
+ *
4
+ * ⛔ THE RESULT HOLDS PEM. Callers may put it on a `ClusterTransport` for one request.
5
+ * They must not persist it, log it, or copy it onto a `Connection`. Alchemy stores
6
+ * connection attributes in plaintext (`credentials.ts`'s own header).
7
+ * ★ YAML IS `yaml-parse.ts` (runtime-neutral: Bun.YAML does not exist under Node, where the
8
+ * published dist runs). Nothing here touches a filesystem or OpenBao — the caller has already
9
+ * read the bytes.
10
+ *
11
+ * Walked against alchemy 2.0.0-beta.79 `Kubernetes/internal/client.ts`: `certificateAuthorityData`
12
+ * stays base64 (the client decodes it) and `clientCert` is PEM. The document shape is the one
13
+ * `values.ts` parses from the Talos v1.13 kubeconfig reference. Not measured on a live cluster.
14
+ */
15
+ import type { ClusterTransport } from 'alchemy/Kubernetes/ClusterAdapter';
16
+ export type KubeconfigMaterial = Pick<ClusterTransport, 'certificateAuthorityData' | 'clientCert' | 'endpoint'>;
17
+ /**
18
+ * Resolve `contextName` to endpoint, base64 CA, and PEM client cert/key.
19
+ * `undefined` for any shape that is not that context's admin kubeconfig — the caller
20
+ * fails closed without embedding the document in the error.
21
+ */
22
+ export declare const kubeconfigTransport: (yamlText: string, contextName: string) => KubeconfigMaterial | undefined;
23
+ //# sourceMappingURL=kubeconfig-doc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kubeconfig-doc.d.ts","sourceRoot":"","sources":["../../src/talos/kubeconfig-doc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAe1E,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,gBAAgB,EAChB,0BAA0B,GAAG,YAAY,GAAG,UAAU,CACvD,CAAC;AASF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,aACpB,MAAM,eACH,MAAM,KAClB,kBAAkB,GAAG,SAwBvB,CAAC"}
@@ -1,6 +1,5 @@
1
1
  import { Resource } from 'alchemy';
2
2
  import type { Input } from 'alchemy/Input';
3
- import type { Connection } from 'alchemy/Kubernetes/Connection';
4
3
  import * as Provider from 'alchemy/Provider';
5
4
  import * as Effect from 'effect/Effect';
6
5
  import type { TalosRequirements, WithTarget } from './resource.ts';
@@ -20,17 +19,6 @@ export interface KubeconfigAttributes {
20
19
  clientCertificateFingerprint: string;
21
20
  /** Digest of endpoint+context+fingerprints — detects credential rotation without storing PEM. */
22
21
  credentialGeneration: string;
23
- /**
24
- * Serializable `Kubernetes.Connection` for downstream workloads.
25
- *
26
- * ★ auth.kind `kubeconfig` is the stock ClusterAdapter — provider-roadmap.md names this seam.
27
- * `path` is a sentinel that can never resolve (LAND red team I2, `kubeconfig-attrs.ts`'s own
28
- * `toConnection` header): the content lives in OpenBao, not at a fixed host path, and a real
29
- * `Kubernetes.ClusterAdapter` wiring is later work, so this must fail rather than silently
30
- * reach the operator's own kubeconfig. A consumer materializes its own scoped temp file via
31
- * `credentials.ts`'s `mintKubeconfig` in the meantime.
32
- */
33
- connection: Connection;
34
22
  }
35
23
  export interface TalosKubeconfig extends Resource<'Talos.Kubeconfig', KubeconfigProps, KubeconfigAttributes, never, TalosRequirements> {
36
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"kubeconfig.d.ts","sourceRoot":"","sources":["../../src/talos/kubeconfig.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAIxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGnE,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,+FAA+F;IAC/F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B,EAAE,MAAM,CAAC;IACxC,4BAA4B,EAAE,MAAM,CAAC;IACrC,iGAAiG;IACjG,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;;;;OASG;IACH,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,eAAgB,SAAQ,QAAQ,CAC/C,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,KAAK,EACL,iBAAiB,CAClB;CAAG;AAEJ,eAAO,MAAM,eAAe,kDAAgD,CAAC;AAmB7E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,UAAW,eAAe,6HAgBjD,CAAC;AAEL,eAAO,MAAM,cAAc,SACnB,KAAK,CAAC,eAAe,CAAC,UACpB,oBAAoB,GAAG,SAAS;qBAWnB,MAAM;;qBAER,QAAQ;uFACzB,CAAC;AAEL;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,UACvB,eAAe,UACd,oBAAoB,GAAG,SAAS,gKA2DvC,CAAC;AAsBJ,eAAO,MAAM,uBAAuB,iJACqD,CAAC"}
1
+ {"version":3,"file":"kubeconfig.d.ts","sourceRoot":"","sources":["../../src/talos/kubeconfig.ts"],"names":[],"mappings":"AAiCA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AASxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGnE,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,+FAA+F;IAC/F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B,EAAE,MAAM,CAAC;IACxC,4BAA4B,EAAE,MAAM,CAAC;IACrC,iGAAiG;IACjG,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,eAAgB,SAAQ,QAAQ,CAC/C,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,KAAK,EACL,iBAAiB,CAClB;CAAG;AAEJ,eAAO,MAAM,eAAe,kDAAgD,CAAC;AAQ7E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,UAAW,eAAe,6HAgBjD,CAAC;AAEL,eAAO,MAAM,cAAc,SACnB,KAAK,CAAC,eAAe,CAAC,UACpB,oBAAoB,GAAG,SAAS;qBAenB,MAAM;;qBAER,QAAQ;uFACzB,CAAC;AAEL;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,UACvB,eAAe,UACd,oBAAoB,GAAG,SAAS,gKA2DvC,CAAC;AAsBJ,eAAO,MAAM,uBAAuB,iJACqD,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { TalosUidNotLiteral } from './cluster-adapter-errors.ts';
2
+ /**
3
+ * The typed refusal unless `connection` is `{ auth: { kind, uid: literal } }`, else `undefined`.
4
+ * ★ A value, never a throw: a throw inside `Effect.gen` would become a defect, not a failure.
5
+ */
6
+ export declare const literalConnectionRefusal: (connection: unknown) => TalosUidNotLiteral | undefined;
7
+ /**
8
+ * ⛔ THE `diff` GUARD ALONE IS NOT ENOUGH (round-4 review): alchemy skips `diff` for a FRESH
9
+ * resource whose inputs are unresolved, and reconcile then copies the resolved string downstream
10
+ * — an Output uid slips through on exactly the first deploy. So the same refusal runs when the
11
+ * resource is DECLARED, before any input resolution, by wrapping its constructor.
12
+ * ★ A Proxy over the class (not a new function) keeps `.Provider`, `.Self`, `.ref` and the type.
13
+ * Plain props fail the declaring Effect; a props Effect fails once it yields.
14
+ */
15
+ export declare const withLiteralConnection: <C extends (...args: never[]) => unknown>(resource: C) => C;
16
+ //# sourceMappingURL=literal-connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"literal-connection.d.ts","sourceRoot":"","sources":["../../src/talos/literal-connection.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,wBAAwB,eAAgB,OAAO,KAAG,kBAAkB,GAAG,SAYnF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,YAAY,CAAC,KAAG,CAkBzF,CAAC"}
@@ -13,7 +13,7 @@ import type { MachineConfigAttributes, MachineConfigProps } from './talos-machin
13
13
  * talosconfig context's own endpoints, which may be a control-plane VIP that only comes up AFTER
14
14
  * bootstrap; every pre-bootstrap call in this file targets the node directly instead.
15
15
  */
16
- export declare const liveSpecDigest: (props: MachineConfigProps, talosconfigPath: string) => Effect.Effect<string, Error | import("effect/PlatformError").PlatformError | import("./talosctl.ts").TalosError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
16
+ export declare const liveSpecDigest: (props: MachineConfigProps, talosconfigPath: string) => Effect.Effect<string, Error | import("effect/PlatformError").PlatformError | import("./talosctl-binary.ts").TalosBinaryRefused | import("./talosctl.ts").TalosError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
17
17
  /**
18
18
  * ⛔ NO SWALLOWING. A transport failure here propagates as its own error (TalosError or the
19
19
  * shape error above) — never as `converged: false`. A false only means "read succeeded, and
@@ -1 +1 @@
1
- {"version":3,"file":"machine-config-read.d.ts","sourceRoot":"","sources":["../../src/talos/machine-config-read.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAI7F;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,UAAW,kBAAkB,mBAAmB,MAAM,uLAiB9E,CAAC;AAuBJ;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,iBAAiB,UAAW,kBAAkB;;;;;sIAiBxD,CAAC;AAEJ,eAAO,MAAM,iBAAiB,SACtB,KAAK,CAAC,kBAAkB,CAAC,UACvB,uBAAuB,GAAG,SAAS;qBAK4B,MAAM;;qBAC1D,QAAQ;sIACzB,CAAC"}
1
+ {"version":3,"file":"machine-config-read.d.ts","sourceRoot":"","sources":["../../src/talos/machine-config-read.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAI7F;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,UAAW,kBAAkB,mBAAmB,MAAM,2OAiB9E,CAAC;AAuBJ;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,iBAAiB,UAAW,kBAAkB;;;;;sIAiBxD,CAAC;AAEJ,eAAO,MAAM,iBAAiB,SACtB,KAAK,CAAC,kBAAkB,CAAC,UACvB,uBAAuB,GAAG,SAAS;qBAK4B,MAAM;;qBAC1D,QAAQ;sIACzB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import * as Effect from 'effect/Effect';
2
+ import type * as Scope from 'effect/Scope';
3
+ /**
4
+ * Write `raw` to a session-temp, 0600, exclusively-created file whose lifetime is the CALLER's
5
+ * `Effect.scoped`, not this call's. See the ⛔ C1 FIX note at the top of credentials.ts.
6
+ *
7
+ * ⛔ 0600, CREATED EXCLUSIVELY, AND `Bun.write` CANNOT DO EITHER. This file can hold a cluster
8
+ * admin client certificate or a machine config's bootstrap token. `Bun.write` takes no mode, so
9
+ * it lands at the process umask — world-readable on this estate — for as long as the resource
10
+ * runs. The name is unguessable, and "unguessable" is not a permission.
11
+ * ⚠️ `wx` IS THE OTHER HALF. `O_EXCL` means this cannot be made to write through a path an
12
+ * attacker pre-created (the classic /tmp symlink race), and with a UUID name a collision is a
13
+ * genuine error rather than something to paper over.
14
+ * ⚠️ A HARD KILL (SIGKILL, power loss) skips the finalizer and leaves the file behind. 0600 is
15
+ * what makes that survivable rather than a disclosure.
16
+ */
17
+ export declare const mintKvTempFile: (raw: string, label: string) => Effect.Effect<{
18
+ readonly path: string;
19
+ }, Error, Scope.Scope>;
20
+ //# sourceMappingURL=mint-temp-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mint-temp-file.d.ts","sourceRoot":"","sources":["../../src/talos/mint-temp-file.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C;;;;;;;;;;;;;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,CAyB1D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=node-temp.harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-temp.harness.d.ts","sourceRoot":"","sources":["../../src/talos/node-temp.harness.ts"],"names":[],"mappings":""}
@@ -15,7 +15,7 @@ import { TalosReBootstrapRefused } from './talos-errors.ts';
15
15
  * failure here means (talos-bootstrap.ts's `read`/`reconcile`, and `assertNoLivePeers` below), so
16
16
  * it is not decided here.
17
17
  */
18
- export declare const isBootstrapped: (props: BootstrapProps, talosconfigPath: string) => Effect.Effect<boolean, import("effect/PlatformError").PlatformError | import("./talosctl.ts").TalosError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
18
+ export declare const isBootstrapped: (props: BootstrapProps, talosconfigPath: string) => Effect.Effect<boolean, import("effect/PlatformError").PlatformError | import("./talosctl-binary.ts").TalosBinaryRefused | import("./talosctl.ts").TalosError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
19
19
  /**
20
20
  * ⛔ I4 FIX (LAND red team, 2026-09-26) — THE CREATE PATH ONLY CHECKED THIS NODE. If the state row
21
21
  * is lost (wrong `--stage`, an FQN rename, a wiped state store) while the cluster already lives on
@@ -1 +1 @@
1
- {"version":3,"file":"talos-bootstrap-etcd.d.ts","sourceRoot":"","sources":["../../src/talos/talos-bootstrap-etcd.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAG5D;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,UAAW,cAAc,mBAAmB,MAAM,gLAIM,CAAC;AAEpF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,iBAAiB,UAAW,cAAc,mBAAmB,MAAM,mHA2B7E,CAAC"}
1
+ {"version":3,"file":"talos-bootstrap-etcd.d.ts","sourceRoot":"","sources":["../../src/talos/talos-bootstrap-etcd.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAG5D;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,UAAW,cAAc,mBAAmB,MAAM,oOAIM,CAAC;AAEpF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,iBAAiB,UAAW,cAAc,mBAAmB,MAAM,mHA2B7E,CAAC"}
@@ -22,11 +22,16 @@
22
22
  * rollout would never learn the real problem was vault. Both `read` and `reconcile` now only
23
23
  * catch `TalosError` (`talosctl health` itself ran and exited non-zero — the one case this
24
24
  * family may honestly call "not healthy"); anything else propagates untouched.
25
+ * ★ `connection` IS A PASS-THROUGH so this resource is `ClusterLike`. Later rows take
26
+ * `cluster: health`. The health check itself still uses `target` and `talosctl`; the field is
27
+ * copied onto attributes and is not a credential. It is required: an optional field would not
28
+ * satisfy `{ connection: Connection }`.
25
29
  */
26
30
  import { Resource } from 'alchemy';
27
31
  import type { Input } from 'alchemy/Input';
28
32
  import * as Provider from 'alchemy/Provider';
29
33
  import * as Effect from 'effect/Effect';
34
+ import type { TalosOpenBaoConnection } from './cluster-adapter.ts';
30
35
  import type { TalosRequirements, WithTarget } from './resource.ts';
31
36
  export interface ClusterHealthProps extends WithTarget {
32
37
  /** Control-plane node IPs passed to `--control-plane-nodes`. */
@@ -45,34 +50,29 @@ export interface ClusterHealthProps extends WithTarget {
45
50
  * on kube-proxy and CoreDNS, both of which wait on a CNI that does not exist yet at bootstrap.
46
51
  */
47
52
  after?: readonly unknown[];
53
+ /**
54
+ * Kubernetes connection copied onto attributes so a later row can take `cluster: this`.
55
+ * Not read by the health check. Persist only a secret-free connection (`talos-openbao`).
56
+ */
57
+ connection: TalosOpenBaoConnection;
48
58
  }
49
59
  export interface ClusterHealthAttributes {
50
60
  healthy: boolean;
51
61
  controlPlaneNodes: string;
52
62
  workerNodes: string;
63
+ /** Same object as the prop. Makes these attributes `ClusterLike`. */
64
+ connection: TalosOpenBaoConnection;
53
65
  }
54
66
  export interface TalosClusterHealth extends Resource<'Talos.ClusterHealth', ClusterHealthProps, ClusterHealthAttributes, never, TalosRequirements> {
55
67
  }
56
68
  export declare const TalosClusterHealth: import("alchemy").ResourceClass<TalosClusterHealth>;
57
69
  /** ★ EXPORTED for talos-cluster-health.test.ts — see talos-bootstrap.ts's own note on the pattern. */
58
- export declare const readClusterHealth: (props: ClusterHealthProps) => Effect.Effect<{
59
- controlPlaneNodes: string;
60
- healthy: boolean;
61
- workerNodes: string;
62
- } | {
63
- controlPlaneNodes: string;
64
- healthy: boolean;
65
- workerNodes: string;
66
- }, Error | import("effect/PlatformError").PlatformError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
70
+ export declare const readClusterHealth: (props: ClusterHealthProps) => Effect.Effect<ClusterHealthAttributes, Error | import("effect/PlatformError").PlatformError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
67
71
  export declare const diffClusterHealth: (news: Input<ClusterHealthProps>, output: ClusterHealthAttributes | undefined) => Effect.Effect<{
68
72
  readonly action: 'noop';
69
73
  } | {
70
74
  readonly action: 'update';
71
- } | undefined, Error | import("effect/PlatformError").PlatformError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
72
- export declare const reconcileClusterHealth: (props: ClusterHealthProps) => Effect.Effect<{
73
- controlPlaneNodes: string;
74
- healthy: boolean;
75
- workerNodes: string;
76
- }, Error | import("effect/PlatformError").PlatformError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
75
+ } | undefined, Error | import("effect/PlatformError").PlatformError | import("./cluster-adapter-errors.ts").TalosUidNotLiteral, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
76
+ export declare const reconcileClusterHealth: (props: ClusterHealthProps) => Effect.Effect<ClusterHealthAttributes, Error | import("effect/PlatformError").PlatformError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
77
77
  export declare const TalosClusterHealthProvider: () => import("effect/Layer").Layer<Provider.Provider<TalosClusterHealth>, never, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
78
78
  //# sourceMappingURL=talos-cluster-health.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"talos-cluster-health.d.ts","sourceRoot":"","sources":["../../src/talos/talos-cluster-health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGnE,MAAM,WAAW,kBAAmB,SAAQ,UAAU;IACpD,gEAAgE;IAChE,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,kDAAkD;IAClD,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAmB,SAAQ,QAAQ,CAClD,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,KAAK,EACL,iBAAiB,CAClB;CAAG;AAEJ,eAAO,MAAM,kBAAkB,qDAAsD,CAAC;AAgEtF,sGAAsG;AACtG,eAAO,MAAM,iBAAiB,UAAW,kBAAkB;;;;;;;;0HASxD,CAAC;AAEJ,eAAO,MAAM,iBAAiB,SACtB,KAAK,CAAC,kBAAkB,CAAC,UACvB,uBAAuB,GAAG,SAAS;qBAKN,MAAM;;qBACxB,QAAQ;sIACzB,CAAC;AAEL,eAAO,MAAM,sBAAsB,UAAW,kBAAkB;;;;0HAU7D,CAAC;AAgBJ,eAAO,MAAM,0BAA0B,oJACwD,CAAC"}
1
+ {"version":3,"file":"talos-cluster-health.d.ts","sourceRoot":"","sources":["../../src/talos/talos-cluster-health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAGnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGnE,MAAM,WAAW,kBAAmB,SAAQ,UAAU;IACpD,gEAAgE;IAChE,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,kDAAkD;IAClD,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAC3B;;;OAGG;IACH,UAAU,EAAE,sBAAsB,CAAC;CACpC;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,UAAU,EAAE,sBAAsB,CAAC;CACpC;AAED,MAAM,WAAW,kBAAmB,SAAQ,QAAQ,CAClD,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,KAAK,EACL,iBAAiB,CAClB;CAAG;AAGJ,eAAO,MAAM,kBAAkB,qDAE9B,CAAC;AAgFF,sGAAsG;AACtG,eAAO,MAAM,iBAAiB,UAAW,kBAAkB,mKAGxD,CAAC;AAEJ,eAAO,MAAM,iBAAiB,SACtB,KAAK,CAAC,kBAAkB,CAAC,UACvB,uBAAuB,GAAG,SAAS;qBAUtB,MAAM;;qBAER,QAAQ;iMACzB,CAAC;AAEL,eAAO,MAAM,sBAAsB,UAAW,kBAAkB,mKAU7D,CAAC;AAgBJ,eAAO,MAAM,0BAA0B,oJACwD,CAAC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * `Talos.ClusterIdentity` — a read-only resource that reports WHICH physical cluster a name means.
3
+ *
4
+ * ★ It reads the vault kubeconfig and GETs the kube-system Namespace once (`cluster-identity.ts`),
5
+ * and publishes `{ uid }`. That is the BOOTSTRAP-THEN-PIN step (cluster-adapter.ts header): the
6
+ * first deploy creates the cluster and this row with no workloads, the operator copies the
7
+ * printed uid into the adapter config, and workloads take `talosOpenBaoConnection(<literal>)`.
8
+ * ⛔ It publishes NO `connection`: an Output uid in a workload's auth is unresolved at plan time
9
+ * and hides a cluster change from the plan (`talosOpenBaoConnection` explains the DELETE on B).
10
+ * ⛔ DRIFT REPAIR CANNOT LAUNDER A MOVE: `read` receives the persisted output and compares it, so
11
+ * `Drift.repair` fails with `TalosClusterMoved` instead of reconciling B against B.
12
+ * ⛔ IT MUTATES NOTHING: no vault write, no cluster write, `delete` is a no-op. Its only effect is
13
+ * the value it reports. `after` must reach past Cilium/CNI only if the apiserver needs it; the
14
+ * kube-system namespace exists as soon as the apiserver answers.
15
+ * ⛔ A CHANGED UID IS REFUSED, NEVER AN UPDATE (`TalosClusterMoved`, in diff AND reconcile). This
16
+ * resource declares no `stables`, so downstream the engine sees an unresolved Output, every
17
+ * workload `diff` returns undefined and the engine plans an UPDATE, not a replace (Plan.ts
18
+ * resourceExpr, `isResolved(news)` in Manifest.ts and HelmChart.ts). Reconcile would then
19
+ * connect with the NEW uid and force-apply onto the new cluster while the old cluster's objects
20
+ * are orphaned (an earlier comment here claimed a replace and a refusal at cleanup: it cannot
21
+ * happen). A real move is a NEW identity resource per physical cluster.
22
+ */
23
+ import { Resource } from 'alchemy';
24
+ import type { Input } from 'alchemy/Input';
25
+ import * as Provider from 'alchemy/Provider';
26
+ import * as Effect from 'effect/Effect';
27
+ import { TalosClusterMoved } from './cluster-adapter-errors.ts';
28
+ import type { KubeconfigProps } from './kubeconfig.ts';
29
+ import type { TalosRequirements } from './resource.ts';
30
+ type KubeconfigSource = Pick<KubeconfigProps, 'context' | 'kubeconfigKey' | 'target'>;
31
+ export interface ClusterIdentityProps extends KubeconfigSource {
32
+ /** Ordering edge: after `Talos.Kubeconfig` (the vault key must exist) and the apiserver is up. */
33
+ after?: readonly unknown[];
34
+ }
35
+ export interface ClusterIdentityAttributes {
36
+ /**
37
+ * The cluster's kube-system `metadata.uid`. Public. ⛔ NOT A `connection`: these attributes are
38
+ * deliberately not `ClusterLike`. Pin this value as a literal in `TalosOpenBaoAdapter` and build
39
+ * workloads' connection from that literal (bootstrap-then-pin, cluster-adapter.ts header).
40
+ */
41
+ uid: string;
42
+ }
43
+ export interface TalosClusterIdentity extends Resource<'Talos.ClusterIdentity', ClusterIdentityProps, ClusterIdentityAttributes, never, TalosRequirements> {
44
+ }
45
+ export declare const TalosClusterIdentity: import("alchemy").ResourceClass<TalosClusterIdentity>;
46
+ /**
47
+ * ★ EXPORTED for talos-cluster-identity.test.ts — see talos-bootstrap.ts's note on the pattern.
48
+ * ⛔ A PERSISTED OUTPUT IS COMPARED HERE TOO, not only in reconcile: `Drift.repair` hands `read`
49
+ * the persisted attributes, then reconciles `news: old.props, output: <what read returned>`.
50
+ * A read that ignored the output returned the NEW uid, so the reconcile guard compared B with B
51
+ * and saved it. Failing in read stops that path with `TalosClusterMoved`.
52
+ */
53
+ export declare const readClusterIdentity: (props: ClusterIdentityProps, output?: ClusterIdentityAttributes) => Effect.Effect<{
54
+ uid: string;
55
+ }, Error | import("alchemy/Kubernetes/internal/client").KubernetesApiError | import("./cluster-adapter-errors.ts").TalosClusterIdentityTimeout | import("./cluster-adapter-errors.ts").TalosClusterIdentityUnreadable | TalosClusterMoved | import("./cluster-adapter-errors.ts").TalosKubeconfigUnreadable | import("./cluster-adapter-errors.ts").TalosOpenBaoConnectTimeout | import("./cluster-adapter-errors.ts").TalosVaultKeyMissing, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
56
+ /** ⛔ Fails closed when a saved uid exists and the live one differs. See the header. */
57
+ export declare const reconcileClusterIdentity: (props: ClusterIdentityProps, output: ClusterIdentityAttributes | undefined) => Effect.Effect<{
58
+ uid: string;
59
+ }, Error | import("alchemy/Kubernetes/internal/client").KubernetesApiError | import("./cluster-adapter-errors.ts").TalosClusterIdentityTimeout | import("./cluster-adapter-errors.ts").TalosClusterIdentityUnreadable | TalosClusterMoved | import("./cluster-adapter-errors.ts").TalosKubeconfigUnreadable | import("./cluster-adapter-errors.ts").TalosOpenBaoConnectTimeout | import("./cluster-adapter-errors.ts").TalosVaultKeyMissing, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
60
+ export declare const diffClusterIdentity: (news: Input<ClusterIdentityProps>, output: ClusterIdentityAttributes | undefined) => Effect.Effect<{
61
+ readonly action: 'noop';
62
+ } | undefined, Error | import("alchemy/Kubernetes/internal/client").KubernetesApiError | import("./cluster-adapter-errors.ts").TalosClusterIdentityTimeout | import("./cluster-adapter-errors.ts").TalosClusterIdentityUnreadable | TalosClusterMoved | import("./cluster-adapter-errors.ts").TalosKubeconfigUnreadable | import("./cluster-adapter-errors.ts").TalosOpenBaoConnectTimeout | import("./cluster-adapter-errors.ts").TalosVaultKeyMissing, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
63
+ export declare const TalosClusterIdentityProvider: () => import("effect/Layer").Layer<Provider.Provider<TalosClusterIdentity>, never, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
64
+ export {};
65
+ //# sourceMappingURL=talos-cluster-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"talos-cluster-identity.d.ts","sourceRoot":"","sources":["../../src/talos/talos-cluster-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,KAAK,gBAAgB,GAAG,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,eAAe,GAAG,QAAQ,CAAC,CAAC;AAEtF,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,kGAAkG;IAClG,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,oBAAqB,SAAQ,QAAQ,CACpD,uBAAuB,EACvB,oBAAoB,EACpB,yBAAyB,EACzB,KAAK,EACL,iBAAiB,CAClB;CAAG;AAEJ,eAAO,MAAM,oBAAoB,uDAA0D,CAAC;AAE5F;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,UACvB,oBAAoB,WAClB,yBAAyB;;8eAgBhC,CAAC;AAEL,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,UAC5B,oBAAoB,UACnB,yBAAyB,GAAG,SAAS;;8eACR,CAAC;AAExC,eAAO,MAAM,mBAAmB,SACxB,KAAK,CAAC,oBAAoB,CAAC,UACzB,yBAAyB,GAAG,SAAS;qBAK1B,MAAM;0fACvB,CAAC;AA4BL,eAAO,MAAM,4BAA4B,sJAC0D,CAAC"}
@@ -0,0 +1,43 @@
1
+ import * as Effect from 'effect/Effect';
2
+ /** `talosctl` on `PATH`. A lane pins another build with {@link TALOSCTL_BINARY_ENV} or `binary`. */
3
+ export declare const DEFAULT_TALOSCTL_BINARY = "talosctl";
4
+ /**
5
+ * Executable override, read at call time. The Mac PATH measured 2026-10-05 has v1.13.8; the
6
+ * cluster is v1.14.2. Set this to the v1.14.2 binary. A per-call `binary` option wins.
7
+ */
8
+ export declare const TALOSCTL_BINARY_ENV = "HF_TALOSCTL";
9
+ /** `bao` on `PATH` — the OpenBao CLI that fetches the cluster credentials at connect time. */
10
+ export declare const DEFAULT_BAO_BINARY = "bao";
11
+ /** `bao` executable override, read at call time and vetted exactly like {@link TALOSCTL_BINARY_ENV}. */
12
+ export declare const BAO_BINARY_ENV = "HF_BAO";
13
+ export declare class TalosBinaryRefused extends Error {
14
+ readonly command: string;
15
+ readonly binary: string;
16
+ constructor(command: string, detail: string, binary?: string);
17
+ }
18
+ /**
19
+ * ⛔ THE DEFAULT IS VETTED TOO (hunt round 5): a bare `talosctl` is resolved against `PATH` here
20
+ * (not `Bun.which` — the published dist runs on Node, where that global is missing), symlinks are
21
+ * followed, and the REAL file is vetted, version-checked and executed by absolute path.
22
+ */
23
+ export declare const resolveDefault: (binary: string) => Effect.Effect<string, TalosBinaryRefused, never>;
24
+ /**
25
+ * ⛔ THE BINARY GETS THE VAULT-MINTED TALOSCONFIG: absolute, owned, not writable, executable, trusted
26
+ * path. ⛔ RETURNS THE CANONICAL PATH (round 7): the override's directory is resolved ONCE
27
+ * (realpath), that path and every ancestor of it are vetted, and the caller must launch exactly
28
+ * the returned path for the version probe AND the credential-bearing call. Vetting the given path
29
+ * and executing it again let a symlinked ancestor be repointed between the two launches. The leaf
30
+ * itself is still lstat'd, so a symlink leaf is refused rather than followed.
31
+ */
32
+ export declare const checkBinaryPath: (binary: string, source: string) => Effect.Effect<string, TalosBinaryRefused, never>;
33
+ /**
34
+ * Resolve and vet the `bao` binary: {@link BAO_BINARY_ENV} wins over `bao` on `PATH`, and either is
35
+ * checked exactly like talosctl (absolute, owned, not writable, executable, not a symlink, every
36
+ * ancestor trusted). Returns the canonical path to launch.
37
+ *
38
+ * ⛔ `bao` FETCHES THE CLUSTER CREDENTIALS (`readKvValue` / `writeKvValue`), so an un-vetted `bao`
39
+ * on a group/world-writable PATH folder (umask 002, the round-10 incident) could answer with an
40
+ * attacker's kubeconfig. The same walk that vets `talosctl` must gate every `bao` launch.
41
+ */
42
+ export declare const resolveBao: () => Effect.Effect<string, TalosBinaryRefused>;
43
+ //# sourceMappingURL=talosctl-binary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"talosctl-binary.d.ts","sourceRoot":"","sources":["../../src/talos/talosctl-binary.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,oGAAoG;AACpG,eAAO,MAAM,uBAAuB,aAAa,CAAC;AAElD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAEjD,8FAA8F;AAC9F,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAExC,wGAAwG;AACxG,eAAO,MAAM,cAAc,WAAW,CAAC;AAEvC,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,YAAY,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAA0B,EAK5E;CACF;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,WAAY,MAAM,qDAgBzC,CAAC;AA6BL;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,WAAY,MAAM,UAAU,MAAM,qDAgC7D,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,QAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAOrE,CAAC"}
@@ -1,24 +1,21 @@
1
- /**
2
- * One `talosctl` invocation — stdout/stderr captured, secrets never echoed.
3
- *
4
- * ★ SHELL OUT LIKE ALCHEMY'S DOCKER PROVIDER (ChildProcessSpawner), NOT A SECOND SDK. Talos speaks
5
- * gRPC; the published, stable surface for operators is `talosctl`. No Talos npm package is added.
6
- *
7
- * ⚠️ REASONED FROM docs.siderolabs.com/talos/v1.13/reference/cli — nothing here was measured on a
8
- * live cluster in this session.
9
- *
10
- * ⛔ DO NOT LOG STDOUT ON FAILURE. `talosctl kubeconfig` and error paths have been observed in the
11
- * wild to include credential material; stderr is the safe diagnostic channel.
12
- */
13
1
  import * as Effect from 'effect/Effect';
14
2
  import * as ChildProcessSpawner from 'effect/process/ChildProcessSpawner';
3
+ import { DEFAULT_TALOSCTL_BINARY, TALOSCTL_BINARY_ENV, TalosBinaryRefused } from './talosctl-binary.ts';
4
+ export { DEFAULT_TALOSCTL_BINARY, TALOSCTL_BINARY_ENV, TalosBinaryRefused };
15
5
  export declare class TalosError extends Error {
16
6
  readonly command: string;
17
7
  readonly exitCode: number;
18
- constructor(command: string, exitCode: number, detail: string);
8
+ constructor(command: string, exitCode: number, detail: string, binary?: string);
19
9
  }
10
+ /** The Talos client version this family is written against (`--client` of the pinned binary). */
11
+ export declare const TALOSCTL_PINNED_VERSION = "v1.14.2";
20
12
  export type TalosRunOptions = {
21
13
  readonly talosconfigPath: string;
14
+ /**
15
+ * `talosctl` executable. Wins over {@link TALOSCTL_BINARY_ENV}.
16
+ * @default `talosctl` on `PATH`, or `HF_TALOSCTL` when that variable is set.
17
+ */
18
+ readonly binary?: string;
22
19
  readonly nodes?: readonly string[];
23
20
  readonly endpoints?: readonly string[];
24
21
  /**
@@ -30,7 +27,7 @@ export type TalosRunOptions = {
30
27
  readonly insecure?: boolean;
31
28
  };
32
29
  /** Run `talosctl <args…>`. Returns trimmed stdout, or '' when empty. */
33
- export declare const talosctl: (args: readonly string[], options: TalosRunOptions) => Effect.Effect<string, import("effect/PlatformError").PlatformError | TalosError, ChildProcessSpawner.ChildProcessSpawner>;
30
+ export declare const talosctl: (args: readonly string[], options: TalosRunOptions) => Effect.Effect<string, import("effect/PlatformError").PlatformError | TalosBinaryRefused | TalosError, ChildProcessSpawner.ChildProcessSpawner>;
34
31
  /** Like `talosctl`, but exit code 1 with "already" in stderr is treated as success. */
35
- export declare const talosctlOrAlready: (args: readonly string[], options: TalosRunOptions) => Effect.Effect<string, import("effect/PlatformError").PlatformError, ChildProcessSpawner.ChildProcessSpawner>;
32
+ export declare const talosctlOrAlready: (args: readonly string[], options: TalosRunOptions) => Effect.Effect<string, import("effect/PlatformError").PlatformError | TalosBinaryRefused, ChildProcessSpawner.ChildProcessSpawner>;
36
33
  //# sourceMappingURL=talosctl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"talosctl.d.ts","sourceRoot":"","sources":["../../src/talos/talosctl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,mBAAmB,MAAM,oCAAoC,CAAC;AAE1E,qBAAa,UAAW,SAAQ,KAAK;IAEjC,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAF3B,YACW,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,EAIf;CACF;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,QAAQ,SAAU,SAAS,MAAM,EAAE,WAAW,eAAe,8HA+CtE,CAAC;AAEL,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,SAAU,SAAS,MAAM,EAAE,WAAW,eAAe,iHAShF,CAAC"}
1
+ {"version":3,"file":"talosctl.d.ts","sourceRoot":"","sources":["../../src/talos/talosctl.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,mBAAmB,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAGnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;AAE5E,qBAAa,UAAW,SAAQ,KAAK;IAEjC,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAF3B,YACW,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,EACd,MAAM,SAA0B,EAIjC;CACF;AAED,iGAAiG;AACjG,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAwBjD,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AA8DF,wEAAwE;AACxE,eAAO,MAAM,QAAQ,SAAU,SAAS,MAAM,EAAE,WAAW,eAAe,mJAgCtE,CAAC;AAEL,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,SAAU,SAAS,MAAM,EAAE,WAAW,eAAe,sIAShF,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Canonical compare: the walk hands over a real path, but the boundary is a security decision —
3
+ * resolving again makes it independent of what a caller (now or future) cached. ⛔ A directory
4
+ * that cannot be resolved is answered FALSE, never thrown: it is certainly not a registered
5
+ * boundary, and the walk must treat "no boundary" as "vet everything" (fail closed).
6
+ */
7
+ export declare const isTrustedBoundary: (dir: string) => boolean;
8
+ //# sourceMappingURL=trust-boundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust-boundary.d.ts","sourceRoot":"","sources":["../../src/talos/trust-boundary.ts"],"names":[],"mappings":"AAoBA;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAAS,MAAM,KAAG,OAM/C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../src/talos/values.ts"],"names":[],"mappings":"AASA,2EAA2E;AAC3E,eAAO,MAAM,aAAa,SAAU,MAAM,WAAmB,CAAC;AAE9D,iGAAiG;AACjG,eAAO,MAAM,MAAM,SAAU,MAAM,WAC6B,CAAC;AAEjE,oFAAoF;AACpF,eAAO,MAAM,YAAY,SAAU,MAAM,WAAiB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,wBAAwB,gBAAiB,MAAM,KAAG,MAAM,GAAG,SAcvE,CAAC;AAeF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,aACnB,MAAM,eACH,MAAM,KAClB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,GAAG,SAyB3E,CAAC"}
1
+ {"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../src/talos/values.ts"],"names":[],"mappings":"AAUA,2EAA2E;AAC3E,eAAO,MAAM,aAAa,SAAU,MAAM,WAAmB,CAAC;AAE9D,iGAAiG;AACjG,eAAO,MAAM,MAAM,SAAU,MAAM,WAC6B,CAAC;AAEjE,oFAAoF;AACpF,eAAO,MAAM,YAAY,SAAU,MAAM,WAAiB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,wBAAwB,gBAAiB,MAAM,KAAG,MAAM,GAAG,SASvE,CAAC;AAeF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,aACnB,MAAM,eACH,MAAM,KAClB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,GAAG,SAsB3E,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Parse one YAML document, or `undefined` when the text is not valid YAML. */
2
+ export declare const parseYaml: (text: string) => unknown;
3
+ //# sourceMappingURL=yaml-parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml-parse.d.ts","sourceRoot":"","sources":["../../src/talos/yaml-parse.ts"],"names":[],"mappings":"AAcA,+EAA+E;AAC/E,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,OAYxC,CAAC"}
@@ -67,6 +67,8 @@ export interface FakeEngine {
67
67
  * `verify.ts`'s `readWithState`, which already wraps that same call in `Effect.catchCause`.
68
68
  */
69
69
  readonly drift: (body: Body) => Promise<Record<string, DriftRow>>;
70
+ /** `alchemy drift --repair` (`Alchemy.Drift.repair`): read, then reconcile what drifted. */
71
+ readonly repair: (body: Body) => Promise<Record<string, DriftRow>>;
70
72
  /**
71
73
  * Every state row the store holds, as JSON — what a Postgres store would persist. ★ For tests
72
74
  * that must prove a value NEVER reaches state (proxmox/pbs-notification-target-state.test.ts).
@@ -1 +1 @@
1
- {"version":3,"file":"fake-engine.d.ts","sourceRoot":"","sources":["../../src/verify/fake-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAKnC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAiB,MAAM,aAAa,CAAC;AAElF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,KAAM,SAAQ,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,EAAE,eAAe,CAAC;CAAG;AAC7F,eAAO,MAAM,KAAK,8BAAwC,CAAC;AAE3D,4EAA4E;AAC5E,MAAM,WAAW,KAAM,SAAQ,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,EAAE,eAAe,CAAC;CAAG;AAC7F,eAAO,MAAM,KAAK,8BAAwC,CAAC;AAE3D;;;;GAIG;AACH,MAAM,WAAW,QAAS,SAAQ,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE,UAAU,EAAE,eAAe,CAAC;CAAG;AACnG,eAAO,MAAM,QAAQ,iCAA8C,CAAC;AAEpE,gGAAgG;AAChG,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,OAAO,UAAU,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAQ,KAI1D,CAAC;AAEH,8CAA8C;AAC9C,eAAO,MAAM,QAAQ,UAAW,KAAK,KAAG,MAAM,EAC2C,CAAC;AAyB1F,4FAA4F;AAC5F,eAAO,MAAM,cAAc,UAAW,KAAK,8GAmCxC,CAAC;AAEJ,oFAAoF;AACpF,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAK5D,gGAAgG;AAChG,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,MAAM,WAAW,UAAU;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjE,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/E;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAClE;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;CAC/B;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,IAAI,EAAE,CAAC,EAAE,GAAG,SAC9B,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,YACvB;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,KACpC,UAmDF,CAAC;AAEF,oCAAoC;AACpC,eAAO,MAAM,UAAU,UAAW,KAAK,KAAG,UAA+C,CAAC"}
1
+ {"version":3,"file":"fake-engine.d.ts","sourceRoot":"","sources":["../../src/verify/fake-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAKnC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAiB,MAAM,aAAa,CAAC;AAElF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,KAAM,SAAQ,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,EAAE,eAAe,CAAC;CAAG;AAC7F,eAAO,MAAM,KAAK,8BAAwC,CAAC;AAE3D,4EAA4E;AAC5E,MAAM,WAAW,KAAM,SAAQ,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,EAAE,eAAe,CAAC;CAAG;AAC7F,eAAO,MAAM,KAAK,8BAAwC,CAAC;AAE3D;;;;GAIG;AACH,MAAM,WAAW,QAAS,SAAQ,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE,UAAU,EAAE,eAAe,CAAC;CAAG;AACnG,eAAO,MAAM,QAAQ,iCAA8C,CAAC;AAEpE,gGAAgG;AAChG,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,OAAO,UAAU,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAQ,KAI1D,CAAC;AAEH,8CAA8C;AAC9C,eAAO,MAAM,QAAQ,UAAW,KAAK,KAAG,MAAM,EAC2C,CAAC;AAyB1F,4FAA4F;AAC5F,eAAO,MAAM,cAAc,UAAW,KAAK,8GAmCxC,CAAC;AAEJ,oFAAoF;AACpF,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAK5D,gGAAgG;AAChG,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,MAAM,WAAW,UAAU;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjE,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/E;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAClE,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnE;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;CAC/B;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,IAAI,EAAE,CAAC,EAAE,GAAG,SAC9B,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,YACvB;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,KACpC,UA2DF,CAAC;AAEF,oCAAoC;AACpC,eAAO,MAAM,UAAU,UAAW,KAAK,KAAG,UAA+C,CAAC"}
package/docs/peers.md CHANGED
@@ -1,16 +1,43 @@
1
- # Peers — and why each pin exists
2
-
3
- The install line for `@homeflare/alchemy`, and why every peer on it and every entry in the
4
- `overrides` block is required. The block itself, which every consumer copies, is in the
5
- [README](../README.md#peers--and-one-override-you-need).
1
+ # Peers — and one override you need
6
2
 
7
3
  ```sh
8
4
  bun add @homeflare/alchemy alchemy@2.0.0-beta.81 effect@4.0.1 \
9
5
  @effect/platform-node@4.0.1 mime@4.1.0 \
10
6
  @distilled.cloud/cloudflare@1.0.0-rc.13 @distilled.cloud/forgejo@1.0.0-rc.13 \
7
+ @distilled.cloud/discord@1.0.0-rc.13 @distilled.cloud/google-workspace@1.0.0-rc.13 \
8
+ @distilled.cloud/argocd@1.0.0-rc.13 \
11
9
  @effect/sql-pg@4.0.1
12
10
  ```
13
11
 
12
+ ⛔ **Every one of those is required, and you also need an `overrides` block** — see
13
+ below. The install succeeds without them and the import throws.
14
+
15
+ ★ **The machine-readable source of truth** lives in this package's `package.json` under the
16
+ `homeflare.consumer` field. It carries the exact pins, the overrides below, and the import
17
+ moves for `effect/unstable/*` as an ordered **array of `{"from", "to"}` pairs** — not an
18
+ object keyed by the old path. Order is load-bearing: the most specific path comes first
19
+ (`httpapi` before its parent `http`), because consumers apply the moves in published order.
20
+ The install line, the overrides block in this doc, and the smoke test install are all
21
+ asserted against that field; change the field first, then copy its `overrides` block here.
22
+
23
+ ⛔ **Add this to your `package.json`, or the install works and the import throws:**
24
+
25
+ ```json
26
+ {
27
+ "overrides": {
28
+ "effect": "4.0.1",
29
+ "@effect/platform-node": "4.0.1",
30
+ "@effect/platform-node-shared": "4.0.1",
31
+ "@effect/platform-bun": "4.0.1",
32
+ "rolldown": "1.2.8",
33
+ "redis": "6.3.0"
34
+ }
35
+ }
36
+ ```
37
+
38
+ Why each peer is required and each pin exists — the measurements, and the error a missing one
39
+ produces — is below.
40
+
14
41
  🔴 **Why, measured 2026-09-16 on 0.1.0 and re-checked 2026-09-17 against Alchemy 78.**
15
42
  Effect's `rc` line is not semver-compatible with itself. Alchemy 78's peer is
16
43
  `effect >= 4.0.0-rc.115`; an unlocked `@effect/platform-node-shared` still floats to the
@@ -0,0 +1,44 @@
1
+ # `Kubernetes.ClusterAdapter` kind `talos-openbao`
2
+
3
+ Reads the cluster admin kubeconfig from OpenBao KV (`bao kv get`, in memory, nothing on disk)
4
+ when a `Kubernetes.Manifest` / `HelmChart` connects, and proves the answering cluster is the
5
+ pinned one by its kube-system `metadata.uid`. The persisted connection is `{ kind, uid }` only.
6
+ The design, the identity rule and the failure modes are in the header of
7
+ `src/talos/cluster-adapter.ts`; this page is what an operator must do differently.
8
+
9
+ ## Connect deadline
10
+
11
+ Vault read and uid GET share one 10 s deadline. A hung `bao` or a silent apiserver fails closed
12
+ with `TalosOpenBaoConnectTimeout` (the `bao` child is killed with its process group). The HTTPS
13
+ GET itself cannot be cancelled: upstream `readObject` takes no abort signal, so the request may
14
+ linger until the OS gives up. That is an upstream ask, not something to re-implement here.
15
+
16
+ ## Literal connections only
17
+
18
+ `talosOpenBaoConnection(uid)` throws `TalosUidNotLiteral` for an Output, and
19
+ `Talos.ClusterHealth` refuses an Output connection in `diff` for the same reason: `cluster: health`
20
+ passes that connection to workloads, and an unresolved connection hides a cluster change from the
21
+ plan.
22
+
23
+ ## Usage rules
24
+
25
+ Upstream Alchemy behaviour the adapter cannot fix. Follow these or risk deleting objects on the
26
+ wrong cluster.
27
+
28
+ 1. **Move a workload to another cluster only by new logical IDs** (destroy the old, create the new).
29
+ Never change a live workload's `connection` in place: upstream skips the identity comparison
30
+ when any input is unresolved (`HelmChart.ts:246`), so the old generation's cleanup can run
31
+ against the new cluster.
32
+ 2. **Manage namespaces as separate `Manifest`s**, never `HelmChart` `createNamespace`. A replacement
33
+ cleanup deletes a shared `createNamespace` namespace (`HelmChart.ts:257`, `:344`) and everything
34
+ else in it.
35
+ 3. **Never rename a `HelmChart` `releaseName` in place.** It is replaced, and cleanup removes the
36
+ release the new one just took over.
37
+
38
+ ## Upstream asks (alchemy 2.0.0-beta.79)
39
+
40
+ - `HelmChart`/`Manifest` diff skips identity comparison when any input is unresolved.
41
+ - Replacement cleanup deletes a shared `createNamespace` namespace.
42
+ - `readObject` cannot be cancelled (`internal/client.ts:75`).
43
+ - `deleteObject` has no uid precondition.
44
+ - Refresh replaces the saved uids.