@intentius/chant-lexicon-helm 0.46.0 → 0.49.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 (118) hide show
  1. package/dist/archive-render.d.ts +94 -0
  2. package/dist/archive-render.d.ts.map +1 -0
  3. package/dist/commands.d.ts +54 -0
  4. package/dist/commands.d.ts.map +1 -0
  5. package/dist/config.d.ts +135 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/deep-observe-hooks.d.ts +2 -0
  8. package/dist/deep-observe-hooks.d.ts.map +1 -0
  9. package/dist/deep-observe.d.ts +54 -0
  10. package/dist/deep-observe.d.ts.map +1 -0
  11. package/dist/describe-resources.d.ts +17 -0
  12. package/dist/describe-resources.d.ts.map +1 -0
  13. package/dist/index.d.ts +18 -2
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/integrity.json +5 -3
  16. package/dist/lint/audit-catalog.d.ts.map +1 -1
  17. package/dist/lint/post-synth/index.d.ts.map +1 -1
  18. package/dist/lint/post-synth/whm503.d.ts +34 -0
  19. package/dist/lint/post-synth/whm503.d.ts.map +1 -0
  20. package/dist/lint/post-synth/whm504.d.ts +20 -0
  21. package/dist/lint/post-synth/whm504.d.ts.map +1 -0
  22. package/dist/manifest.json +1 -1
  23. package/dist/okf/index.md +2 -0
  24. package/dist/okf/rules/WHM503.md +15 -0
  25. package/dist/okf/rules/WHM504.md +11 -0
  26. package/dist/okf/types/Values.md +1 -0
  27. package/dist/op/activities/cluster-probe.d.ts +44 -0
  28. package/dist/op/activities/cluster-probe.d.ts.map +1 -0
  29. package/dist/op/activities/helm.d.ts +179 -5
  30. package/dist/op/activities/helm.d.ts.map +1 -1
  31. package/dist/op/activities/index.d.ts +4 -2
  32. package/dist/op/activities/index.d.ts.map +1 -1
  33. package/dist/pinnability/actions.d.ts +76 -0
  34. package/dist/pinnability/actions.d.ts.map +1 -0
  35. package/dist/pinnability/classify.d.ts +129 -0
  36. package/dist/pinnability/classify.d.ts.map +1 -0
  37. package/dist/pinnability/conditions.d.ts +109 -0
  38. package/dist/pinnability/conditions.d.ts.map +1 -0
  39. package/dist/pinnability/index.d.ts +17 -0
  40. package/dist/pinnability/index.d.ts.map +1 -0
  41. package/dist/pinnability/localize.d.ts +124 -0
  42. package/dist/pinnability/localize.d.ts.map +1 -0
  43. package/dist/pinnability/render-stream.d.ts +27 -0
  44. package/dist/pinnability/render-stream.d.ts.map +1 -0
  45. package/dist/pinnability/values.d.ts +69 -0
  46. package/dist/pinnability/values.d.ts.map +1 -0
  47. package/dist/plugin.d.ts.map +1 -1
  48. package/dist/release-observe.d.ts +109 -0
  49. package/dist/release-observe.d.ts.map +1 -0
  50. package/dist/render-diff.d.ts +192 -0
  51. package/dist/render-diff.d.ts.map +1 -0
  52. package/dist/render-digest.d.ts +135 -0
  53. package/dist/render-digest.d.ts.map +1 -0
  54. package/dist/render-store.d.ts +310 -0
  55. package/dist/render-store.d.ts.map +1 -0
  56. package/dist/render-wrapper.d.ts +140 -0
  57. package/dist/render-wrapper.d.ts.map +1 -0
  58. package/dist/render.d.ts +81 -0
  59. package/dist/render.d.ts.map +1 -1
  60. package/dist/rules/whm503.ts +101 -0
  61. package/dist/rules/whm504.ts +52 -0
  62. package/dist/skills/chant-helm.md +7 -0
  63. package/dist/values-probe.d.ts +177 -0
  64. package/dist/values-probe.d.ts.map +1 -0
  65. package/dist/wrapper-chart.d.ts +61 -0
  66. package/dist/wrapper-chart.d.ts.map +1 -0
  67. package/package.json +10 -4
  68. package/src/archive-render.test.ts +201 -0
  69. package/src/archive-render.ts +119 -0
  70. package/src/commands.test.ts +487 -0
  71. package/src/commands.ts +445 -0
  72. package/src/config.test.ts +130 -0
  73. package/src/config.ts +220 -0
  74. package/src/deep-observe-hooks.ts +20 -0
  75. package/src/deep-observe.test.ts +165 -0
  76. package/src/deep-observe.ts +121 -0
  77. package/src/describe-resources.test.ts +255 -0
  78. package/src/describe-resources.ts +198 -0
  79. package/src/index.ts +98 -2
  80. package/src/lifecycle-integration.test.ts +289 -0
  81. package/src/lint/audit-catalog.ts +2 -0
  82. package/src/lint/post-synth/index.ts +4 -0
  83. package/src/lint/post-synth/whm503.test.ts +134 -0
  84. package/src/lint/post-synth/whm503.ts +101 -0
  85. package/src/lint/post-synth/whm504.test.ts +105 -0
  86. package/src/lint/post-synth/whm504.ts +52 -0
  87. package/src/op/activities/cluster-probe.test.ts +66 -0
  88. package/src/op/activities/cluster-probe.ts +148 -0
  89. package/src/op/activities/helm.test.ts +824 -0
  90. package/src/op/activities/helm.ts +628 -5
  91. package/src/op/activities/index.ts +17 -2
  92. package/src/pinnability/actions.ts +263 -0
  93. package/src/pinnability/classify.ts +579 -0
  94. package/src/pinnability/conditions.ts +0 -0
  95. package/src/pinnability/index.ts +77 -0
  96. package/src/pinnability/localize.test.ts +234 -0
  97. package/src/pinnability/localize.ts +644 -0
  98. package/src/pinnability/pinnability.test.ts +560 -0
  99. package/src/pinnability/render-stream.ts +59 -0
  100. package/src/pinnability/values.ts +205 -0
  101. package/src/plugin.test.ts +3 -1
  102. package/src/plugin.ts +47 -0
  103. package/src/release-observe.ts +392 -0
  104. package/src/render-diff.test.ts +366 -0
  105. package/src/render-diff.ts +407 -0
  106. package/src/render-digest.test.ts +186 -0
  107. package/src/render-digest.ts +207 -0
  108. package/src/render-store.test.ts +412 -0
  109. package/src/render-store.ts +621 -0
  110. package/src/render-wrapper.test.ts +259 -0
  111. package/src/render-wrapper.ts +274 -0
  112. package/src/render.test.ts +383 -4
  113. package/src/render.ts +319 -8
  114. package/src/skills/chant-helm.md +7 -0
  115. package/src/values-probe.test.ts +400 -0
  116. package/src/values-probe.ts +627 -0
  117. package/src/wrapper-chart.test.ts +110 -0
  118. package/src/wrapper-chart.ts +124 -0
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Render canonicalization and the contentDigest/inputDigest split
3
+ * (#1237, epic #1228 Phase 2).
4
+ *
5
+ * A pinned render's output is normalized to a canonical byte form before
6
+ * digesting, and two digests are recorded with different jobs:
7
+ *
8
+ * - `inputDigest` answers "same inputs?" cheaply — a `sha256:` over the
9
+ * canonical JSON of { chart reference, chart version, resolved values,
10
+ * capability profile }. It is the same digest `helmInstall` records in the
11
+ * release ledger (#1243), computed by the same helper, so a render and a
12
+ * deploy of the same inputs share an identity.
13
+ * - `contentDigest` answers "same bytes on the cluster?" — a `sha256:` over
14
+ * the canonical rendered bytes. It is the artifact identity.
15
+ *
16
+ * The two diverge exactly when rendering is unpinned or the chart is
17
+ * unstable: two renders with the same inputDigest but different
18
+ * contentDigests mean the render function is not a function of its declared
19
+ * inputs. That divergence is itself a signal — `renderStability` names it.
20
+ *
21
+ * Canonicalization scope (what the epic measured, not more):
22
+ * - Mapping key order is normalized (sorted) — YAML mappings are unordered
23
+ * in Kubernetes semantics, so key order is render noise. Sequence order is
24
+ * never touched; list order is meaningful to Kubernetes.
25
+ * - Document order is preserved, not sorted. The epic verified document
26
+ * ordering is already stable across renders (three renders, again with
27
+ * subcharts), so reordering would only destroy information.
28
+ * - Duplicate documents are preserved. An aliased dependency emits the same
29
+ * CRD twice (epic finding 11); helm dedupes on install, the artifact keeps
30
+ * both, and the digest stays stable because canonicalization is
31
+ * per-document and order-preserving.
32
+ * - The helm-inserted `# Source:` header is kept (it is the origin-routing
33
+ * key the archive wrapper builds on) and normalized to a single leading
34
+ * line. All other comments, trailing whitespace, CRLF line endings, and
35
+ * document-separator styling are render noise and are dropped or
36
+ * normalized.
37
+ */
38
+ import type { HelmRenderRecord } from "./render.js";
39
+ /**
40
+ * The declared inputs of a helm render or deploy, in the exact shape #1243
41
+ * digests for the release ledger. `helmInstallInputDigest`
42
+ * (op/activities/helm.ts) and `HelmRender`'s recorded `inputDigest` both
43
+ * delegate here, so the two cannot drift: the same chart reference, version,
44
+ * resolved values, and capability facts produce the same digest whether they
45
+ * reach helm through a render or a deploy.
46
+ */
47
+ export interface HelmInputDigestSource {
48
+ /** Chart reference — a local path, or `<repo-url>/<chart>` for repo-fetched charts. */
49
+ chart: string;
50
+ /** Pinned chart version. Digested as `null` when absent. */
51
+ chartVersion?: string;
52
+ /** Resolved values (file merged with overrides). Digested as `{}` when absent. */
53
+ values?: Record<string, unknown>;
54
+ /**
55
+ * Capability facts the render is pinned against. Only the facts join the
56
+ * digest — the profile's *name* is a label, not an input, so two profiles
57
+ * declaring the same cluster digest identically. `apiVersions` is sorted:
58
+ * it declares a set, not an order.
59
+ */
60
+ capabilityProfile?: {
61
+ kubeVersion?: string;
62
+ apiVersions?: string[];
63
+ };
64
+ }
65
+ /**
66
+ * The input-side identity of a helm render or deploy: `sha256:` over the
67
+ * canonical JSON (core's `canonicalJson`, RFC 8785 shape) of the declared
68
+ * inputs. Shared with #1243's release-ledger digest — see
69
+ * `HelmInputDigestSource`. Deliberately excludes the release name and
70
+ * namespace: those are baked into the rendered bytes but the ledger uses
71
+ * this digest as a cross-environment join key, and two environments
72
+ * deploying the same chart, version, and values must share it.
73
+ */
74
+ export declare function helmInputDigest(source: HelmInputDigestSource): string;
75
+ /**
76
+ * Normalize a `helm template` stream to its canonical byte form.
77
+ *
78
+ * Per document: the `# Source:` header (if any) becomes the single leading
79
+ * comment line, the YAML body is re-serialized with sorted mapping keys
80
+ * (sequences untouched), no line-width folding, and a trailing newline.
81
+ * Documents are emitted in render order, each introduced by a `---` line.
82
+ * CRLF endings, trailing whitespace, non-Source comments, and empty or
83
+ * comment-only documents are render noise and do not survive.
84
+ *
85
+ * A document that fails to parse as YAML is kept verbatim (trimmed) rather
86
+ * than dropped — the canonical form must never silently lose content, and a
87
+ * verbatim document still digests deterministically.
88
+ */
89
+ export declare function canonicalizeRender(rendered: string): string;
90
+ /**
91
+ * The content-side identity of a render: `sha256:` over the canonical bytes
92
+ * of the rendered stream (see `canonicalizeRender`). Unlike `inputDigest`,
93
+ * this changes whenever the bytes that would reach the cluster change — a
94
+ * chart upgrade with identical values, a helm version that renders
95
+ * differently, an unstable template.
96
+ */
97
+ export declare function helmContentDigest(rendered: string): string;
98
+ /** One inputDigest's renders and the distinct content identities they produced. */
99
+ export interface RenderStabilityGroup {
100
+ inputDigest: string;
101
+ /** Render names in this group, in record order. */
102
+ names: string[];
103
+ /** Distinct content digests observed, in first-seen order. */
104
+ contentDigests: string[];
105
+ }
106
+ export interface RenderStabilityReport {
107
+ /** Groups whose every render produced the same bytes. */
108
+ stable: RenderStabilityGroup[];
109
+ /**
110
+ * Groups where the same inputs produced different bytes: the render is
111
+ * not pinned down by its declared inputs — an unstable chart, or an input
112
+ * that escaped declaration. Every group here is a defect signal.
113
+ */
114
+ unstable: RenderStabilityGroup[];
115
+ /** Names of records carrying no digests (unpinned renders) — unassessable. */
116
+ unassessed: string[];
117
+ }
118
+ /**
119
+ * Group recorded renders by input identity and report whether the same
120
+ * inputs always produced the same bytes.
121
+ *
122
+ * Two renders with equal `inputDigest` and different `contentDigest` mean
123
+ * the render is not a function of its declared inputs — the chart is
124
+ * unstable (generated values, timestamps) or an input escaped declaration.
125
+ * That divergence is the signal this helper exists to name; a single render
126
+ * per input proves nothing and lands in `stable` by default.
127
+ *
128
+ * Grouping keys on `(inputDigest, name)` because the release name is a real
129
+ * render input baked into the bytes but deliberately absent from
130
+ * `inputDigest` (see `helmInputDigest`) — two differently named renders of
131
+ * the same chart legitimately differ in content and must not be read as
132
+ * instability.
133
+ */
134
+ export declare function renderStability(records: readonly HelmRenderRecord[]): RenderStabilityReport;
135
+ //# sourceMappingURL=render-digest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-digest.d.ts","sourceRoot":"","sources":["../src/render-digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAQH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,uFAAuF;IACvF,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAarE;AAKD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoB3D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,8DAA8D;IAC9D,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,8EAA8E;IAC9E,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,GAAG,qBAAqB,CAwB3F"}
@@ -0,0 +1,310 @@
1
+ /**
2
+ * RenderManifest + content-addressed render storage (#1238, epic #1228
3
+ * Phase 2).
4
+ *
5
+ * #1237 gave a pinned render its identities — `inputDigest` over the
6
+ * declared inputs, `contentDigest` over the canonical rendered bytes. This
7
+ * module makes the render durable: the canonical bytes land in a
8
+ * content-addressed store keyed by `contentDigest`, and a `RenderManifest`
9
+ * — modeled on core's `BuildArchiveManifest`
10
+ * (packages/core/src/components/verbs/build-archive.ts) — records what the
11
+ * bytes are, what produced them, and how to find each document inside them.
12
+ *
13
+ * Storage layout, under `~/.chant/helm-renders/` (override with
14
+ * `CHANT_HELM_RENDER_ROOT`):
15
+ *
16
+ * ```
17
+ * sha256-<64 hex>/ one per distinct contentDigest
18
+ * content.yaml the canonical rendered bytes (canonicalizeRender)
19
+ * manifest.json the RenderManifest
20
+ * inputs/<64 hex>.json inputs index: full-render-inputs key -> digests
21
+ * ```
22
+ *
23
+ * The `sha256-<hex>` entries are the new root the issue asks for: the
24
+ * pre-#1238 cache keyed entries by a *truncated, input-derived* hash
25
+ * (16 hex characters, no algorithm prefix), which is a cache key, not an
26
+ * artifact identity. Those legacy entries are left exactly where they are —
27
+ * unpinned renders keep using them — and pinned renders write here instead.
28
+ * No migration: a truncated key cannot be turned back into a digest.
29
+ *
30
+ * Two renders that produce the same bytes share one `sha256-<hex>` entry —
31
+ * the content file and manifest are written once and never rewritten
32
+ * (first writer wins; the store is immutable, like a build archive entry).
33
+ * Dedup falls out of content addressing rather than being a feature.
34
+ *
35
+ * The inputs index preserves cache-hit behavior: before shelling out to
36
+ * helm, `HelmRender` computes the full-inputs key and reads
37
+ * `inputs/<key>.json` to find the bytes a previous identical render stored.
38
+ * The index key deliberately differs from `inputDigest`: the release name
39
+ * and namespace are baked into the rendered bytes (`.Release.Name`,
40
+ * `--namespace`) but are excluded from `inputDigest` because the release
41
+ * ledger uses that digest as a cross-environment join key (see
42
+ * `helmInputDigest` in ./render-digest.ts). A cache must key on everything
43
+ * that changes the bytes, so the index key includes both.
44
+ *
45
+ * Retention: none, deliberately. The build archive this is modeled on has
46
+ * no garbage collection — an archive entry lives until someone deletes it —
47
+ * and the pre-#1238 render cache behaved the same way. This store follows
48
+ * suit: entries accumulate until removed by hand. If the archive ever grows
49
+ * a retention story, this store should adopt the same one.
50
+ */
51
+ import type { HelmCapabilityProfile } from "./config.js";
52
+ import type { ValueOrigin } from "./values-probe.js";
53
+ /**
54
+ * One document's entry in a render's document index: enough identity to ask
55
+ * "give me the ServiceAccount named X in namespace Y" and enough addressing
56
+ * to answer it without parsing the whole stream.
57
+ */
58
+ export interface RenderDocumentEntry {
59
+ /** Kubernetes kind, e.g. `Deployment`. */
60
+ kind: string;
61
+ /** apiVersion as rendered, e.g. `apps/v1`. */
62
+ apiVersion: string;
63
+ /** `metadata.name`. */
64
+ name: string;
65
+ /** `metadata.namespace`, or `null` for cluster-scoped / namespace-less documents. */
66
+ namespace: string | null;
67
+ /** The helm-inserted `# Source:` origin path, when the document carries one. */
68
+ source: string | null;
69
+ /**
70
+ * Byte offset of this document's first byte inside `content.yaml`
71
+ * (pointing just past the `---` separator line, at the `# Source:` header
72
+ * when there is one).
73
+ */
74
+ start: number;
75
+ /** Byte length of the document, up to the next separator (or end of file). */
76
+ length: number;
77
+ /** `sha256:` over exactly those bytes — lets a reader verify a slice without trusting offsets. */
78
+ digest: string;
79
+ }
80
+ /**
81
+ * The durable record of one pinned render — what `manifest.json` holds.
82
+ * Modeled on `BuildArchiveManifest`: versioned, content-addressed, and
83
+ * carrying both identity sides the epic's Decisions require — the
84
+ * input-side join key (`inputDigest`, with `valuesDigest` as its
85
+ * values-only component) for cross-environment questions, and
86
+ * `contentDigest` proving what this cluster's profile actually received.
87
+ */
88
+ export interface RenderManifest {
89
+ /** Manifest schema version, so an incompatible future shape is detected before being misread. */
90
+ version: 1;
91
+ /** Chart name or local chart path, as the render declared it. */
92
+ chart: string;
93
+ /** Pinned chart version, or `null` for a local chart rendered without one. */
94
+ chartVersion: string | null;
95
+ /** Chart repo URL, or `null` for a local chart. */
96
+ repo: string | null;
97
+ /** Helm release name baked into the bytes (`.Release.Name`). */
98
+ releaseName: string;
99
+ /** Namespace the render targeted (`--namespace`), or `null`. */
100
+ namespace: string | null;
101
+ /**
102
+ * `sha256:` over the canonical JSON of the resolved values alone — the
103
+ * input-side join key the epic's ledger queries use together with
104
+ * `(chart, chartVersion)`.
105
+ */
106
+ valuesDigest: string;
107
+ /**
108
+ * `sha256:` over the full declared-input set (chart reference, version,
109
+ * values, capability facts) — `helmInputDigest`, the same digest the
110
+ * release ledger records on deploy (#1243).
111
+ */
112
+ inputDigest: string;
113
+ /** The capability profile the render was pinned against. `cluster` is the profile's declared name — profiles are per cluster. */
114
+ capabilityProfile: {
115
+ cluster: string;
116
+ kubeVersion: string;
117
+ apiVersions: string[];
118
+ };
119
+ /** `sha256:` over the canonical rendered bytes — the artifact identity, and this entry's storage key. */
120
+ contentDigest: string;
121
+ /** Number of documents in the canonical stream (including any the index could not identify). */
122
+ docCount: number;
123
+ /** Index of identifiable documents: kind/namespace/name -> byte span + per-document digest. */
124
+ documents: RenderDocumentEntry[];
125
+ /** ISO-8601 timestamp this manifest was written. Not part of any digest. */
126
+ renderedAt: string;
127
+ /**
128
+ * Version of the helm binary that produced the bytes. Load-bearing: the
129
+ * default kube version is a property of the binary (epic finding 1), so
130
+ * this field is what explains a digest mismatch between two machines.
131
+ */
132
+ helmVersion: string;
133
+ /** chant version that wrote this manifest. */
134
+ chantVersion: string;
135
+ /** Source ref/commit the render was produced from, when the caller supplied one. */
136
+ sourceRef: string | null;
137
+ /**
138
+ * `sha256:` over the canonical JSON of the coalesced values the
139
+ * build-time probe (#1251) observed for every chart instance, keyed by
140
+ * scope path — `coalescedValuesDigest` from `./values-probe.ts`. `null`
141
+ * when the probe did not run for this render (a repo-fetched chart, whose
142
+ * source the probe needs on disk, or a probe failure — never fabricated).
143
+ */
144
+ coalescedValuesDigest: string | null;
145
+ /**
146
+ * Each coalesced value's winning layer (#1252), dot-joined root-coordinate
147
+ * path to `ValueOrigin` — `computeValueSources` from `./values-probe.ts`.
148
+ * `null` under the same conditions as `coalescedValuesDigest`.
149
+ */
150
+ valueSources: Record<string, ValueOrigin> | null;
151
+ }
152
+ /** What `inputs/<key>.json` holds: the digests a full-inputs cache key resolves to. */
153
+ export interface RenderInputsIndexEntry {
154
+ version: 1;
155
+ inputDigest: string;
156
+ contentDigest: string;
157
+ }
158
+ /**
159
+ * Root of the render store. `CHANT_HELM_RENDER_ROOT` overrides the default
160
+ * `~/.chant/helm-renders` — the same directory the legacy input-keyed cache
161
+ * lives in; the two coexist because legacy entries are bare 16-hex names
162
+ * and store entries are `sha256-` prefixed.
163
+ */
164
+ export declare function renderStoreRoot(): string;
165
+ /** The full set of inputs that determine a pinned render's bytes. */
166
+ export interface RenderCacheKeySource {
167
+ /** Chart reference — a local path, or `<repo-url>/<chart>` for repo-fetched charts (same convention `helmInputDigest` uses). */
168
+ chart: string;
169
+ chartVersion?: string;
170
+ /** Release name — baked into the bytes via `.Release.Name`, so a real cache input even though `inputDigest` excludes it. */
171
+ releaseName: string;
172
+ /** Namespace — baked in via `--namespace`, likewise excluded from `inputDigest`. */
173
+ namespace?: string;
174
+ values?: Record<string, unknown>;
175
+ capabilityProfile: HelmCapabilityProfile;
176
+ }
177
+ /**
178
+ * Cache key over *everything* that changes a pinned render's bytes — a
179
+ * strict superset of `helmInputDigest`'s inputs (adds release name,
180
+ * namespace, and the profile's declared name, mirroring the legacy cache
181
+ * key's fields). 64 hex characters, no prefix: this is a lookup key, not an
182
+ * artifact identity.
183
+ */
184
+ export declare function renderCacheKey(source: RenderCacheKeySource): string;
185
+ /**
186
+ * `sha256:` over the canonical JSON of the resolved values alone — the
187
+ * `valuesDigest` half of the ledger's input-side join key
188
+ * `(chart, chartVersion, valuesDigest)`. Absent values digest as `{}`,
189
+ * matching `helmInputDigest`'s treatment.
190
+ */
191
+ export declare function helmValuesDigest(values?: Record<string, unknown>): string;
192
+ /**
193
+ * Build the document index over a canonical stream: for every identifiable
194
+ * document (it parses and carries `kind` + `metadata.name`), its
195
+ * kind/namespace/name identity, byte span, and per-document digest.
196
+ * Returns the index and the total document count — the count includes
197
+ * documents the index could not identify, so `docCount` is always the
198
+ * number of documents the artifact carries.
199
+ */
200
+ export declare function indexRenderDocuments(canonical: string): {
201
+ documents: RenderDocumentEntry[];
202
+ docCount: number;
203
+ };
204
+ export interface PersistHelmRenderInput {
205
+ /** The `helm template` output — raw or already canonical; it is canonicalized before storage either way. */
206
+ rendered: string;
207
+ /** Release name the render was produced under (`HelmRenderProps.name`). */
208
+ releaseName: string;
209
+ /** Chart name or local chart path, as declared. */
210
+ chart: string;
211
+ /** Chart repo URL for repo-fetched charts. */
212
+ repo?: string;
213
+ chartVersion?: string;
214
+ namespace?: string;
215
+ values?: Record<string, unknown>;
216
+ /**
217
+ * The capability profile the render was pinned against. Absent means the
218
+ * render was unpinned — persistence is refused, because an unpinned
219
+ * render's bytes are a function of the local helm binary's defaults and
220
+ * have no identity worth storing.
221
+ */
222
+ capabilityProfile?: HelmCapabilityProfile;
223
+ /** Version of the helm binary that produced the bytes. Recorded as `"unknown"` when not supplied. */
224
+ helmVersion?: string;
225
+ /** Source ref/commit, when the caller has one. Never fabricated. */
226
+ sourceRef?: string;
227
+ /**
228
+ * The build-time coalesced-values probe's digest (#1251), when the caller
229
+ * ran one for this render. Absent (not merely `undefined`-passed) records
230
+ * `null` in the manifest — the probe needs the chart source on disk, so a
231
+ * repo-fetched render legitimately has none.
232
+ */
233
+ coalescedValuesDigest?: string;
234
+ /** The probe's value-source attribution (#1252), alongside `coalescedValuesDigest`. */
235
+ valueSources?: Record<string, ValueOrigin>;
236
+ /** Clock override for tests. */
237
+ now?: () => Date;
238
+ /** Store root override; defaults to `renderStoreRoot()`. */
239
+ root?: string;
240
+ }
241
+ export interface PersistedHelmRender {
242
+ /** The manifest now on disk — the existing one when the content was already stored. */
243
+ manifest: RenderManifest;
244
+ /** Directory the render lives in: `<root>/sha256-<hex>`. */
245
+ dir: string;
246
+ /**
247
+ * True when this contentDigest was already in the store — the bytes and
248
+ * manifest were left untouched (only the inputs index was updated).
249
+ */
250
+ deduplicated: boolean;
251
+ }
252
+ /**
253
+ * Persist one pinned render: canonical bytes under their `contentDigest`,
254
+ * the `RenderManifest` beside them, and an inputs-index entry so an
255
+ * identical future render is a cache hit.
256
+ *
257
+ * Content-addressed entries are immutable: when the digest directory
258
+ * already holds a manifest, both files are left as they are and the
259
+ * existing manifest is returned (`deduplicated: true`). The inputs index is
260
+ * still written — a new input combination can legitimately map to bytes the
261
+ * store already holds.
262
+ *
263
+ * Refuses an unpinned render (no capability profile) with the specific
264
+ * reason: no profile means the bytes depend on the local helm binary's
265
+ * defaulted capabilities, so they have no stable content identity to store
266
+ * under.
267
+ */
268
+ export declare function persistHelmRender(input: PersistHelmRenderInput): PersistedHelmRender;
269
+ /** Load the `RenderManifest` stored under a content digest, or `undefined` when the store has no such entry. */
270
+ export declare function loadRenderManifest(contentDigest: string, opts?: {
271
+ root?: string;
272
+ }): RenderManifest | undefined;
273
+ /** Load the canonical rendered bytes stored under a content digest, or `undefined` when absent. */
274
+ export declare function loadRenderContent(contentDigest: string, opts?: {
275
+ root?: string;
276
+ }): string | undefined;
277
+ /** Resolve a full-inputs cache key through the inputs index, or `undefined` on a miss. */
278
+ export declare function findRenderByCacheKey(cacheKey: string, opts?: {
279
+ root?: string;
280
+ }): RenderInputsIndexEntry | undefined;
281
+ /**
282
+ * Every manifest in the store, sorted by `renderedAt` then `contentDigest`
283
+ * for a stable listing. Entries whose manifest is missing or unreadable are
284
+ * skipped — a listing never fails on one corrupt entry. This is the query
285
+ * surface the diff issues (#1249/#1250) resolve digests against.
286
+ */
287
+ export declare function listRenderManifests(opts?: {
288
+ root?: string;
289
+ }): RenderManifest[];
290
+ /** How a caller names one document inside a stored render. */
291
+ export interface RenderDocumentRef {
292
+ kind: string;
293
+ name: string;
294
+ /** Omit (or pass `null`) to match a cluster-scoped / namespace-less document. */
295
+ namespace?: string | null;
296
+ }
297
+ /**
298
+ * Resolve one document by kind/namespace/name to its exact bytes inside a
299
+ * stored render, via the manifest's document index. The slice is verified
300
+ * against the entry's per-document digest before being returned — corrupt
301
+ * content is an error, never silently wrong bytes. `undefined` means the
302
+ * store has no such render or the index has no such document.
303
+ */
304
+ export declare function readRenderDocument(contentDigest: string, ref: RenderDocumentRef, opts?: {
305
+ root?: string;
306
+ }): {
307
+ entry: RenderDocumentEntry;
308
+ text: string;
309
+ } | undefined;
310
+ //# sourceMappingURL=render-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-store.d.ts","sourceRoot":"","sources":["../src/render-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Structure-preserving render wrapper (#1239, epic #1228 Phase 3).
3
+ *
4
+ * Turns a pinned render's document stream into chant-shaped routing groups
5
+ * WITHOUT restructuring the documents. Structure-preserving means the bytes
6
+ * that deploy are the bytes the render store recorded — this module only
7
+ * routes and labels; it never re-serializes, reorders lines, or edits a
8
+ * document. Each `RoutedDocument.text` is the exact document text from the
9
+ * input stream.
10
+ *
11
+ * Routing is by origin, not by kind. `helm template` stamps every document
12
+ * with `# Source: <chart>/<path>`, and the discriminator is whether that
13
+ * path contains a `crds/` **segment** (`(^|/)crds/` — `isCrdSource` from
14
+ * the #1234 classifier seeds):
15
+ *
16
+ * - A `crds/`-segment origin routes to the CRD group — the wrapper's
17
+ * `crds/`. Segment matching is load-bearing: a subchart's CRDs arrive as
18
+ * `charts/<child>/crds/<file>`, so a prefix rule catches none of them and
19
+ * would route every subchart CRD into `templates/`, making it deletable
20
+ * on uninstall (epic findings 4, 10 — the A/B test showed a flat wrap
21
+ * converts `helm uninstall` from safe to data-destroying).
22
+ * - A hook-annotated template document (`helm.sh/hook` in
23
+ * `metadata.annotations`) routes to its own group, annotations intact.
24
+ * Hooks survive pinning (epic finding 5); they are surfaced separately so
25
+ * the install path can account for them, never silently dropped.
26
+ * - Everything else routes to the main group — the wrapper's `templates/`.
27
+ * A template-rendered `CustomResourceDefinition` stays here, because the
28
+ * `crds/`-segment is the discriminator, not the kind: a chart that
29
+ * templates its CRDs opted into template lifecycle semantics (upgrades
30
+ * and deletes apply to them), and moving them to `crds/` would change
31
+ * that. The routing notes it with a warning so the choice is visible.
32
+ *
33
+ * Aliased dependencies emit duplicate CRDs (epic finding 11): the same
34
+ * dependency included twice under an alias renders its `crds/` once per
35
+ * instance — two documents, one distinct CRD. The stored artifact keeps
36
+ * both (canonicalization is order- and duplicate-preserving), but a wrapper
37
+ * chart's `crds/` holds each CRD once, so the routed CRD group deduplicates
38
+ * by `(group, kind)`: the first occurrence wins and a warning names both
39
+ * sources. A CRD document that cannot be identified (unparseable, or
40
+ * missing `spec.group` / `spec.names.kind`) is never deduplicated — the
41
+ * routing must not silently drop what it cannot identify.
42
+ *
43
+ * The wrapper inherits the source chart's name and version (epic
44
+ * Decisions), keeping `helm history` continuous across the pinned
45
+ * migration; `RoutedRender.chart` / `chartVersion` carry them.
46
+ *
47
+ * This is the seam the pinned-install path (#1242) consumes:
48
+ * `routeStoredRender(contentDigest)` loads a stored render's canonical
49
+ * bytes and manifest and routes them.
50
+ */
51
+ /** One routed document: exact bytes plus the labels routing derived from them. */
52
+ export interface RoutedDocument {
53
+ /**
54
+ * The document's exact text from the input stream (from just past the
55
+ * `---` separator, trimmed of surrounding blank lines — the same split
56
+ * `splitDocuments` performs). Never re-serialized: what deploys is what
57
+ * was recorded.
58
+ */
59
+ text: string;
60
+ /**
61
+ * Chart-relative `# Source:` origin path (e.g. `crds/a.yaml`,
62
+ * `charts/kid/crds/kidcrd.yaml`), or `null` when the document carries no
63
+ * source header.
64
+ */
65
+ source: string | null;
66
+ /** Kubernetes kind, or `null` when the document does not parse to a kinded object. */
67
+ kind: string | null;
68
+ /** apiVersion as rendered, or `null`. */
69
+ apiVersion: string | null;
70
+ /** `metadata.name`, or `null`. */
71
+ name: string | null;
72
+ }
73
+ /** Machine-readable warning categories the routing emits. */
74
+ export type RoutedRenderWarningCode = "duplicate-crd" | "template-crd";
75
+ export interface RoutedRenderWarning {
76
+ /**
77
+ * - `duplicate-crd` — an aliased dependency emitted the same CRD twice;
78
+ * the first occurrence was kept, the duplicate dropped. The message
79
+ * names both sources.
80
+ * - `template-crd` — a `CustomResourceDefinition` was rendered from
81
+ * `templates/` (no `crds/` segment in its origin). It stays in the main
82
+ * group per the segment rule; this note makes the lifecycle choice
83
+ * visible.
84
+ */
85
+ code: RoutedRenderWarningCode;
86
+ message: string;
87
+ }
88
+ /**
89
+ * A pinned render routed into the structure the wrapper chart preserves.
90
+ * The document groups partition the input stream (minus deduplicated CRD
91
+ * duplicates, each named in `warnings`); no document is ever silently
92
+ * dropped and no document text is ever altered.
93
+ */
94
+ export interface RoutedRender {
95
+ /**
96
+ * Wrapper chart name — inherited from the source chart, so `helm history`
97
+ * stays continuous across the pinned migration (epic Decisions).
98
+ */
99
+ chart: string;
100
+ /** Wrapper chart version — inherited from the source chart; `null` for a local chart rendered without one. */
101
+ chartVersion: string | null;
102
+ /**
103
+ * Documents whose origin has a `crds/` segment — the wrapper's `crds/`,
104
+ * which is what keeps `helm uninstall` from deleting them (epic finding
105
+ * 4). Deduplicated by `(group, kind)`, first occurrence winning.
106
+ */
107
+ crds: RoutedDocument[];
108
+ /**
109
+ * Hook-annotated template documents (`helm.sh/hook`), annotations intact.
110
+ * Routed as their own group so the install path can account for them —
111
+ * never silently dropped (epic finding 5).
112
+ */
113
+ hooks: RoutedDocument[];
114
+ /** Everything else — the wrapper's `templates/`. */
115
+ main: RoutedDocument[];
116
+ /** What routing had to decide beyond the mechanical rule: dropped duplicates, template-rendered CRDs. */
117
+ warnings: RoutedRenderWarning[];
118
+ }
119
+ export interface RouteRenderOptions {
120
+ /** Source chart name — becomes the wrapper's name. */
121
+ chart: string;
122
+ /** Source chart version — becomes the wrapper's version. */
123
+ chartVersion?: string | null;
124
+ }
125
+ /**
126
+ * Route a rendered stream (canonical or raw `helm template` output) into
127
+ * `RoutedRender` groups. Pure over the stream: no store access, no helm.
128
+ */
129
+ export declare function routeRender(rendered: string, opts: RouteRenderOptions): RoutedRender;
130
+ /**
131
+ * Route a stored pinned render by its `contentDigest`: loads the canonical
132
+ * bytes and the `RenderManifest` from the render store (#1238) and routes
133
+ * them, inheriting the manifest's chart name and version. This is the seam
134
+ * the pinned-install path (#1242) consumes. `undefined` when the store has
135
+ * no such entry.
136
+ */
137
+ export declare function routeStoredRender(contentDigest: string, opts?: {
138
+ root?: string;
139
+ }): RoutedRender | undefined;
140
+ //# sourceMappingURL=render-wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-wrapper.d.ts","sourceRoot":"","sources":["../src/render-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AASH,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,sFAAsF;IACtF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,yCAAyC;IACzC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kCAAkC;IAClC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,6DAA6D;AAC7D,MAAM,MAAM,uBAAuB,GAAG,eAAe,GAAG,cAAc,CAAC;AAEvE,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;OAQG;IACH,IAAI,EAAE,uBAAuB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,8GAA8G;IAC9G,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;OAIG;IACH,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB;;;;OAIG;IACH,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,oDAAoD;IACpD,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,yGAAyG;IACzG,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AA0DD,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,GAAG,YAAY,CA0DpF;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACvB,YAAY,GAAG,SAAS,CAM1B"}