@intentius/chant 0.34.0 → 0.37.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 (41) hide show
  1. package/dist/cli/commands/check-lexicon-docs.d.ts +42 -0
  2. package/dist/cli/commands/check-lexicon-docs.d.ts.map +1 -0
  3. package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
  4. package/dist/cli/handlers/components.d.ts.map +1 -1
  5. package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
  6. package/dist/cli/main.d.ts.map +1 -1
  7. package/dist/cli/registry.d.ts +2 -0
  8. package/dist/cli/registry.d.ts.map +1 -1
  9. package/dist/codegen/docs.d.ts +16 -0
  10. package/dist/codegen/docs.d.ts.map +1 -1
  11. package/dist/codegen/fetch.d.ts +1 -1
  12. package/dist/codegen/fetch.d.ts.map +1 -1
  13. package/dist/deep-observation.d.ts +0 -10
  14. package/dist/deep-observation.d.ts.map +1 -1
  15. package/dist/lifecycle/rollback.d.ts +18 -0
  16. package/dist/lifecycle/rollback.d.ts.map +1 -1
  17. package/dist/lifecycle/status.d.ts +53 -0
  18. package/dist/lifecycle/status.d.ts.map +1 -1
  19. package/dist/yaml.d.ts.map +1 -1
  20. package/package.json +1 -1
  21. package/src/cli/commands/check-lexicon-docs.test.ts +90 -0
  22. package/src/cli/commands/check-lexicon-docs.ts +71 -0
  23. package/src/cli/commands/check-lexicon.ts +15 -0
  24. package/src/cli/handlers/components.ts +54 -3
  25. package/src/cli/handlers/graph.test.ts +61 -0
  26. package/src/cli/handlers/lifecycle.ts +8 -1
  27. package/src/cli/main.ts +2 -0
  28. package/src/cli/registry.ts +2 -0
  29. package/src/codegen/docs-sections.ts +1 -1
  30. package/src/codegen/docs.ts +122 -5
  31. package/src/codegen/fetch.test.ts +24 -5
  32. package/src/codegen/fetch.ts +19 -1
  33. package/src/codegen/publish-order.test.ts +133 -0
  34. package/src/deep-observation.test.ts +151 -0
  35. package/src/deep-observation.ts +66 -2
  36. package/src/lifecycle/rollback.test.ts +78 -1
  37. package/src/lifecycle/rollback.ts +41 -2
  38. package/src/lifecycle/status.test.ts +90 -5
  39. package/src/lifecycle/status.ts +85 -2
  40. package/src/yaml.test.ts +89 -0
  41. package/src/yaml.ts +66 -9
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Docs reachability audit for the lexicon completeness contract (#1312).
3
+ *
4
+ * The contract used to check documentation by counting files — "at least 1
5
+ * .mdx page" at tier 1, "at least 8" at tier 2 — and never opened one. That
6
+ * counts a page nothing links to exactly the same as a page a reader can
7
+ * actually find, so azure, temporal, helm and github each accumulated
8
+ * hand-added pages that appear in no sidebar and are reachable only by typing
9
+ * their URL. Azure's getting-started, resource reference and composites pages
10
+ * were all invisible while its ≥8-page check passed comfortably — the count
11
+ * check was, if anything, rewarded by the orphans.
12
+ *
13
+ * Starlight does not auto-discover pages (see docs/README.md), so sidebar
14
+ * membership is the whole of reachability for a lexicon site.
15
+ */
16
+ export interface DocsReachability {
17
+ /** Whether this lexicon ships a Starlight site at all. */
18
+ hasSite: boolean;
19
+ /** Every content page slug found on disk, `index` included. */
20
+ pages: string[];
21
+ /** Page slugs no sidebar entry points at, `index` excluded. */
22
+ unreachable: string[];
23
+ }
24
+ /**
25
+ * Slugs the sidebar reaches, including nested group `items`.
26
+ *
27
+ * Read textually rather than by importing the config: `astro.config.mjs` is an
28
+ * ESM module that imports `@astrojs/starlight`, which a lexicon under check is
29
+ * not required to have installed. The generator emits `JSON.stringify` output
30
+ * (double-quoted), but a hand-edited config may use single quotes or a bare
31
+ * key, so accept all three.
32
+ */
33
+ export declare function sidebarSlugs(configSource: string): Set<string>;
34
+ /**
35
+ * Audit one lexicon directory for doc pages nothing links to.
36
+ *
37
+ * A lexicon with no docs site is not a failure here — tier 1's "at least 1
38
+ * .mdx doc page" already covers that case, and reporting the same absence
39
+ * twice would just be noise.
40
+ */
41
+ export declare function auditDocsReachability(lexiconDir: string): DocsReachability;
42
+ //# sourceMappingURL=check-lexicon-docs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-lexicon-docs.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/check-lexicon-docs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAC;IACjB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAM9D;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,CAkB1E"}
@@ -1 +1 @@
1
- {"version":3,"file":"check-lexicon.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/check-lexicon.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AAiDD;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAuapE;AAqBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAmDzE"}
1
+ {"version":3,"file":"check-lexicon.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/check-lexicon.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AAiDD;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqbpE;AAqBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAmDzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/components.ts"],"names":[],"mappings":"AA8CA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,KAAK,EAAE,KAAK,EAAa,MAAM,4BAA4B,CAAC;AAEnE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ErF;AA4CD;;;;;;;;;;;;;;;GAeG;AACH;;;;;;;;6EAQ6E;AAC7E,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,CAiBzD;AAqDD,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAkP9E;AAED,kEAAkE;AAClE,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAM/E"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/components.ts"],"names":[],"mappings":"AA8CA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,KAAK,EAAE,KAAK,EAAa,MAAM,4BAA4B,CAAC;AAEnE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ErF;AA4DD;;;;;;;;;;;;;;;GAeG;AACH;;;;;;;;6EAQ6E;AAC7E,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,CAiBzD;AAqDD,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAqR9E;AAED,kEAAkE;AAClE,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAM/E"}
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/lifecycle.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAqDlD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAoH/E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA4C3E;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuB/E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuJ3E;AA0hBD;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA8I3E;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAiB1E;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAM9E;AAkBD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA+C/E"}
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/lifecycle.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAqDlD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAoH/E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA4C3E;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA8B/E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuJ3E;AA0hBD;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA8I3E;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAiB1E;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAM9E;AAkBD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA+C/E"}
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAMA,OAAO,EAAmC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AA0E9E;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA+QpD;AA8gBD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB5E"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAMA,OAAO,EAAmC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AA0E9E;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAiRpD;AA8gBD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB5E"}
@@ -62,6 +62,8 @@ export interface ParsedArgs {
62
62
  selectName?: string;
63
63
  /** `chant import --owned` — restrict live import to chant-owned resources */
64
64
  owned?: boolean;
65
+ /** `chant lifecycle rollback --dry-run` — compute the rollback delta and print it; open no PR, push nothing, leave no branch. */
66
+ dryRun?: boolean;
65
67
  /** `chant import --verbatim` — keep server-defaulted fields in live import */
66
68
  verbatim?: boolean;
67
69
  /** `chant lifecycle … --src <dir>` — build root override for lifecycle commands */
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/cli/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/cli/registry.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,22 @@ export type { DocsConfig, DocsResult } from "./docs-types.js";
13
13
  * Run the documentation pipeline with the supplied config.
14
14
  */
15
15
  export declare function docsPipeline(config: DocsConfig): DocsResult;
16
+ /**
17
+ * Marks a page as pipeline output. Used both to warn readers off editing the
18
+ * file and, in {@link writeDocsSite}, to tell a page this pipeline owns from a
19
+ * hand-written one when reaping pages it no longer emits.
20
+ */
21
+ export declare const GENERATED_MARKER_TAG = "GENERATED-BY-CHANT-DOCS";
22
+ /**
23
+ * Every slug a Starlight sidebar reaches, including nested group items.
24
+ */
25
+ export declare function collectSidebarSlugs(items: Array<Record<string, unknown>>): Set<string>;
26
+ /**
27
+ * Content pages that no sidebar entry points at.
28
+ *
29
+ * `index` is always the site root and never needs an entry of its own.
30
+ */
31
+ export declare function unreachablePages(contentDir: string, sidebar: Array<Record<string, unknown>>): string[];
16
32
  /**
17
33
  * Write generated docs pages to disk.
18
34
  */
@@ -1 +1 @@
1
- {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/codegen/docs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAA2B,MAAM,cAAc,CAAC;AAGpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI3D;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAuG3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAQvE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAoG1E"}
1
+ {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/codegen/docs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAA2B,MAAM,cAAc,CAAC;AAGpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI3D;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAiI3D;AAsBD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,4BAA4B,CAAC;AAE9D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAUtF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtC,MAAM,EAAE,CAQV;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAQvE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAmI1E"}
@@ -30,7 +30,7 @@ export interface FetchConfig {
30
30
  * On exhaustion a descriptive {@link TransientFetchError} is thrown rather
31
31
  * than the raw last error so the caller can surface a human-readable message.
32
32
  */
33
- export declare function fetchWithRetry(url: string, retries?: number, backoffMs?: number, init?: RequestInit): Promise<Response>;
33
+ export declare function fetchWithRetry(url: string, retries?: number, backoffMs?: number, init?: RequestInit, attemptTimeoutMs?: number): Promise<Response>;
34
34
  /**
35
35
  * Thrown when {@link fetchWithRetry} exhausts all retry attempts on a
36
36
  * transient failure (429 / 5xx / network error).
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/codegen/fetch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,WAAW,WAAW;IAC1B,oBAAoB;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA4CD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,OAAO,SAAkB,EACzB,SAAS,SAAqB,EAC9B,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,QAAQ,CAAC,CA0CnB;AAED;;;;;;;GAOG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,GAAG,EAAE,MAAM;aACX,OAAO,EAAE,MAAM;aACf,UAAU,EAAE,MAAM,GAAG,SAAS;aAC9B,KAAK,CAAC,EAAE,KAAK;gBAHb,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,KAAK,CAAC,EAAE,KAAK,YAAA;CAUhC;AAMD;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BxF;AAID;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACjC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAU9B;AAID;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,UAAU,EACnB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACjC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAyDrB;AAID,MAAM,WAAW,cAAc;IAC7B,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,EACjB,KAAK,UAAQ,GACZ,OAAO,CAAC,MAAM,CAAC,CAoDjB;AAID;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAMtD"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/codegen/fetch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,WAAW,WAAW;IAC1B,oBAAoB;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA0DD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,OAAO,SAAkB,EACzB,SAAS,SAAqB,EAC9B,IAAI,CAAC,EAAE,WAAW,EAClB,gBAAgB,SAA6B,GAC5C,OAAO,CAAC,QAAQ,CAAC,CA6CnB;AAED;;;;;;;GAOG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,GAAG,EAAE,MAAM;aACX,OAAO,EAAE,MAAM;aACf,UAAU,EAAE,MAAM,GAAG,SAAS;aAC9B,KAAK,CAAC,EAAE,KAAK;gBAHb,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,KAAK,CAAC,EAAE,KAAK,YAAA;CAUhC;AAMD;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BxF;AAID;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACjC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAU9B;AAID;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,UAAU,EACnB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACjC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAyDrB;AAID,MAAM,WAAW,cAAc;IAC7B,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,EACjB,KAAK,UAAQ,GACZ,OAAO,CAAC,MAAM,CAAC,CAoDjB;AAID;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAMtD"}
@@ -219,16 +219,6 @@ export interface NormalizeDeepOptions {
219
219
  * cannot depend on whether the pruning rules kept it.
220
220
  */
221
221
  export declare function deepPathSet(tree: Record<string, unknown>): Set<string>;
222
- /**
223
- * Normalize one property tree: prune by hook, mask secret-bearing leaves,
224
- * canonicalize key order, canonicalize array order where the hook knows how,
225
- * and collapse anything that isn't JSON data to {@link UNRESOLVED}.
226
- *
227
- * Pure and total. Key order is canonicalized unconditionally because JSON
228
- * object order is not semantic and a provider is free to return it differently
229
- * on every read; array order is canonicalized only where the lexicon says the
230
- * array is a set, because list order often *is* semantic.
231
- */
232
222
  export declare function normalizeDeepProperties(tree: Record<string, unknown>, options: NormalizeDeepOptions): Record<string, unknown>;
233
223
  /** Context {@link flattenDeepProperties} needs to address set-like arrays by key. */
234
224
  export interface FlattenDeepOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"deep-observation.d.ts","sourceRoot":"","sources":["../src/deep-observation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deep-observation.d.ts","sourceRoot":"","sources":["../src/deep-observation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,8FAA8F;IAC9F,IAAI,EAAE,MAAM,CAAC;IACb,4GAA4G;IAC5G,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,qBAAqB;IACpC,mCAAmC;IACnC,QAAQ,CAAC,eAAe,EAAE,IAAI,CAAC;IAC/B,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IACnD;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC/C;AAED,2EAA2E;AAC3E,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IACnD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC9C;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAMtF;AAED,6GAA6G;AAC7G,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,EAClD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC5C,qBAAqB,CAMvB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,qBAAqB,GAAG,SAAS,GACvC,yBAAyB,CAG3B;AAID;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,uBAAuB,CAAC;AAE/C,0FAA0F;AAC1F,eAAO,MAAM,MAAM,eAAe,CAAC;AAEnC;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAOnD,CAAC;AAEF,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,6CAA6C;AAC7C,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;AAE3C,sFAAsF;AACtF,MAAM,WAAW,QAAQ;IACvB,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,oDAAoD;IACpD,KAAK,EAAE,OAAO,CAAC;IACf,sCAAsC;IACtC,IAAI,EAAE,QAAQ,CAAC;IACf;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC/C;AAED,kGAAkG;AAClG,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;;;OAQG;IACH,KAAK,CAAC,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IAChC;;;;;;;;OAQG;IACH,QAAQ,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAAC;CAC1D;AAED,yDAAyD;AACzD,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACxC;AA+BD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAiBtE;AA0CD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,oBAAoB,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6GzB;AAKD,qFAAqF;AACrF,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,sBAAsB,CAAC;CAChC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CA8CtB;AAED,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAK9D"}
@@ -9,15 +9,33 @@ export interface RollbackResult {
9
9
  noop: boolean;
10
10
  branch?: string;
11
11
  prUrl?: string;
12
+ /**
13
+ * The rollback delta as a unified diff — present only for a `dryRun`, where
14
+ * it is the whole point: the PR body's diff is what a reviewer would act on,
15
+ * so producing it without a PR is what makes the delta inspectable offline.
16
+ */
17
+ diff?: string;
12
18
  }
13
19
  /**
14
20
  * Open a rollback PR restoring `sourceDir` to `ref`. Isolated worktree; the
15
21
  * caller's branch is untouched. Throws on an unknown ref or a git/gh failure.
22
+ *
23
+ * `dryRun` computes the same delta and returns it as a diff without pushing a
24
+ * branch or opening a PR, leaving the repository exactly as it found it.
25
+ *
26
+ * That mode exists because the PR path needs a GitHub remote and an
27
+ * authenticated `gh` — reasonable for the operator flow this was built for
28
+ * (#873), and impossible for a hermetic acceptance run. chant#1208's CC
29
+ * round-trip has to demonstrate rollback offline, on an emulator, with no
30
+ * remote in the picture; without this it could only assert the `noop` case,
31
+ * which exercises none of the interesting work.
16
32
  */
17
33
  export declare function rollbackToRevision(opts: {
18
34
  ref: string;
19
35
  env: string | undefined;
20
36
  sourceDir: string;
21
37
  cwd: string;
38
+ /** Compute and return the delta; open no PR, push nothing, leave no branch. */
39
+ dryRun?: boolean;
22
40
  }): Promise<RollbackResult>;
23
41
  //# sourceMappingURL=rollback.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rollback.d.ts","sourceRoot":"","sources":["../../src/lifecycle/rollback.ts"],"names":[],"mappings":"AAiBA,2CAA2C;AAC3C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED,qCAAqC;AACrC,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAO5F;AAED,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,cAAc,CAAC,CA6B1B"}
1
+ {"version":3,"file":"rollback.d.ts","sourceRoot":"","sources":["../../src/lifecycle/rollback.ts"],"names":[],"mappings":"AAiBA,2CAA2C;AAC3C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED,qCAAqC;AACrC,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAO5F;AAED,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,+EAA+E;IAC/E,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,OAAO,CAAC,cAAc,CAAC,CAkD1B"}
@@ -87,6 +87,19 @@ export interface ComponentStatusRow {
87
87
  * present-but-not-healthy amber (mid-deploy) / red (rollback/failed).
88
88
  */
89
89
  stack?: LiveStackInfo;
90
+ /**
91
+ * How this component's own resources answered (behold#98). Present whenever
92
+ * `--live` gathered evidence across a live-name mapping.
93
+ *
94
+ * `stack` above only exists where the substrate has a deploy object to read,
95
+ * which is AWS and nowhere else — floci-az and floci-gcp have none, so a
96
+ * consumer painting component status off `stack` has nothing to paint from
97
+ * there. These counts are the substrate-neutral source for the same job:
98
+ * they aggregate observations, which every lexicon produces, rather than a
99
+ * provider-specific grouping object. `stack` stays as the richer enrichment
100
+ * where it exists.
101
+ */
102
+ resources?: ComponentResourceRollup;
90
103
  }
91
104
  /** A component's owning deploy unit and its provider-native status. */
92
105
  export interface LiveStackInfo {
@@ -130,6 +143,14 @@ export interface LiveComponentEvidence {
130
143
  /** The owning deploy unit's raw status, when observed (AWS: the component's own
131
144
  * CFN stack). Surfaced onto `ComponentStatusRow.stack` for a richer palette. */
132
145
  stack?: LiveStackInfo;
146
+ /**
147
+ * How the component's own resources answered, before any merge collapsed
148
+ * them (behold#98). Always present when evidence exists — a component that
149
+ * maps to a single entity by identity gets a rollup of one, so a consumer
150
+ * never has to branch on whether a live-name mapping happened to be
151
+ * configured.
152
+ */
153
+ rollup?: ComponentResourceRollup;
133
154
  }
134
155
  /**
135
156
  * Overlay per-component stack-presence evidence onto change-set evidence.
@@ -141,6 +162,16 @@ export interface LiveComponentEvidence {
141
162
  * is authoritative for **presence** (`live`) and **ownership**; the change-set's
142
163
  * `action` is kept, since drift is still assessed from the diff. A component in
143
164
  * only one map passes through unchanged.
165
+ *
166
+ * The change-set's `rollup` is kept too (behold#100). This merge rebuilds the
167
+ * evidence object field by field, so anything not named here is dropped — and
168
+ * `describeStackStatus` reports a stack, never per-resource counts, so the
169
+ * supplement has no rollup to contribute. Before this, every component on a
170
+ * lexicon that implements `describeStackStatus` lost the counts #1300 had just
171
+ * computed. That is AWS and only AWS, which made the rollup absent on exactly
172
+ * the substrate it was meant to be verified against: behold#98 shipped its
173
+ * consumer against floci-az/floci-gcp rows, where no stack observer runs and
174
+ * the field survived.
144
175
  */
145
176
  export declare function mergeLiveEvidence(base: Map<string, LiveComponentEvidence> | undefined, supplement: Map<string, LiveComponentEvidence>): Map<string, LiveComponentEvidence>;
146
177
  /**
@@ -155,6 +186,28 @@ export declare function mergeLiveEvidence(base: Map<string, LiveComponentEvidenc
155
186
  export type LiveNameMapping = Map<string, string[] | undefined>;
156
187
  /** Resolve the live entity/resource name(s) a component owns: its explicit mapping, or `[component]` when none is given. */
157
188
  export declare function resolveLiveNames(component: string, mapping?: LiveNameMapping): string[];
189
+ /**
190
+ * How a component's own resources answered, one count per tri-state verdict.
191
+ *
192
+ * The merged verdict above is deliberately lossy — it answers "is this
193
+ * component deployed" and nothing else. A consumer painting component status
194
+ * without a deploy object to read (behold#98: floci-az and floci-gcp have no
195
+ * CloudFormation stack, so `stack` below is absent and there is nothing to
196
+ * colour from) needs the shape underneath: how many of the component's
197
+ * resources were seen, how many were confirmed gone, how many nobody could
198
+ * look at. Substrate-neutral by construction — it counts observations, not
199
+ * provider objects.
200
+ */
201
+ export interface ComponentResourceRollup {
202
+ /** Resources this component owns, per the live-name mapping. */
203
+ total: number;
204
+ /** Observed present. */
205
+ present: number;
206
+ /** Looked for, reported missing. Never includes a resource nobody could read. */
207
+ absent: number;
208
+ /** NOT-OBSERVED (#1089) — a hole, never counted as absence. */
209
+ unobserved: number;
210
+ }
158
211
  /**
159
212
  * Build a `component -> live evidence` map from a `ChangeSet`. Components and
160
213
  * chant entities are different namespaces (a component's `name` need not
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA2G/D;AAMD,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASlE;AAiFD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,WAAW,CA8Eb;AA+DD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,WAAW,CAyEb;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAelD"}
1
+ {"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA2G/D;AAMD,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASlE;AAiFD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,WAAW,CA8Eb;AA0GD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,WAAW,CAuFb;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAelD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant",
3
- "version": "0.34.0",
3
+ "version": "0.37.0",
4
4
  "description": "Declarative infrastructure-as-code toolkit — TypeScript on Node.js",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The docs-reachability half of the lexicon completeness contract (#1312).
3
+ *
4
+ * The contract previously judged documentation by counting `.mdx` files, which
5
+ * treats a page nothing links to the same as one a reader can find. These
6
+ * tests pin the behaviour that replaced it.
7
+ */
8
+
9
+ import { describe, test, expect, beforeEach, afterEach } from "vitest";
10
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "fs";
11
+ import { tmpdir } from "os";
12
+ import { join } from "path";
13
+ import { auditDocsReachability, sidebarSlugs } from "./check-lexicon-docs";
14
+
15
+ let dir: string;
16
+
17
+ function lexicon(pages: string[], configSource: string): string {
18
+ const contentDir = join(dir, "docs", "src", "content", "docs");
19
+ mkdirSync(contentDir, { recursive: true });
20
+ for (const page of pages) writeFileSync(join(contentDir, `${page}.mdx`), "body\n");
21
+ writeFileSync(join(dir, "docs", "astro.config.mjs"), configSource);
22
+ return dir;
23
+ }
24
+
25
+ beforeEach(() => {
26
+ dir = mkdtempSync(join(tmpdir(), "chant-docs-check-"));
27
+ });
28
+
29
+ afterEach(() => {
30
+ rmSync(dir, { recursive: true, force: true });
31
+ });
32
+
33
+ describe("sidebarSlugs", () => {
34
+ test("reads the generator's own double-quoted JSON output", () => {
35
+ expect(sidebarSlugs('{ "label": "A", "slug": "getting-started" }')).toEqual(
36
+ new Set(["getting-started"]),
37
+ );
38
+ });
39
+
40
+ test("reads a hand-edited config's single quotes and bare keys", () => {
41
+ // A config may be edited by hand between regens; missing those entries
42
+ // would report a reachable page as unreachable.
43
+ expect(sidebarSlugs("{ slug: 'resources' }, { 'slug': \"skills\" }")).toEqual(
44
+ new Set(["resources", "skills"]),
45
+ );
46
+ });
47
+
48
+ test("descends into nested sidebar groups", () => {
49
+ const cfg = `[
50
+ { "label": "Live Cluster", "items": [
51
+ { "label": "The API Client", "slug": "api-client" },
52
+ { "label": "chant kube", "slug": "kube" }
53
+ ]}
54
+ ]`;
55
+ expect(sidebarSlugs(cfg)).toEqual(new Set(["api-client", "kube"]));
56
+ });
57
+ });
58
+
59
+ describe("auditDocsReachability", () => {
60
+ test("a page in no sidebar entry is unreachable", () => {
61
+ const d = lexicon(["index", "getting-started", "skills"], '[{ "slug": "getting-started" }]');
62
+ expect(auditDocsReachability(d).unreachable).toEqual(["skills"]);
63
+ });
64
+
65
+ test("index needs no entry — it is the site root", () => {
66
+ const d = lexicon(["index"], "[]");
67
+ expect(auditDocsReachability(d).unreachable).toEqual([]);
68
+ });
69
+
70
+ test("a page reached only through a nested group still counts as reachable", () => {
71
+ const d = lexicon(
72
+ ["index", "api-client"],
73
+ '[{ "label": "Live Cluster", "items": [{ "slug": "api-client" }] }]',
74
+ );
75
+ expect(auditDocsReachability(d).unreachable).toEqual([]);
76
+ });
77
+
78
+ test("a lexicon with no docs site is not a failure here", () => {
79
+ // Tier 1's "at least 1 .mdx doc page" already covers a missing site;
80
+ // reporting the same absence twice would be noise.
81
+ const audit = auditDocsReachability(dir);
82
+ expect(audit.hasSite).toBe(false);
83
+ expect(audit.unreachable).toEqual([]);
84
+ });
85
+
86
+ test("reports every unreachable page, not just the first", () => {
87
+ const d = lexicon(["index", "a", "b", "c"], '[{ "slug": "b" }]');
88
+ expect(auditDocsReachability(d).unreachable).toEqual(["a", "c"]);
89
+ });
90
+ });
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Docs reachability audit for the lexicon completeness contract (#1312).
3
+ *
4
+ * The contract used to check documentation by counting files — "at least 1
5
+ * .mdx page" at tier 1, "at least 8" at tier 2 — and never opened one. That
6
+ * counts a page nothing links to exactly the same as a page a reader can
7
+ * actually find, so azure, temporal, helm and github each accumulated
8
+ * hand-added pages that appear in no sidebar and are reachable only by typing
9
+ * their URL. Azure's getting-started, resource reference and composites pages
10
+ * were all invisible while its ≥8-page check passed comfortably — the count
11
+ * check was, if anything, rewarded by the orphans.
12
+ *
13
+ * Starlight does not auto-discover pages (see docs/README.md), so sidebar
14
+ * membership is the whole of reachability for a lexicon site.
15
+ */
16
+
17
+ import { existsSync, readdirSync, readFileSync } from "fs";
18
+ import { join } from "path";
19
+
20
+ export interface DocsReachability {
21
+ /** Whether this lexicon ships a Starlight site at all. */
22
+ hasSite: boolean;
23
+ /** Every content page slug found on disk, `index` included. */
24
+ pages: string[];
25
+ /** Page slugs no sidebar entry points at, `index` excluded. */
26
+ unreachable: string[];
27
+ }
28
+
29
+ /**
30
+ * Slugs the sidebar reaches, including nested group `items`.
31
+ *
32
+ * Read textually rather than by importing the config: `astro.config.mjs` is an
33
+ * ESM module that imports `@astrojs/starlight`, which a lexicon under check is
34
+ * not required to have installed. The generator emits `JSON.stringify` output
35
+ * (double-quoted), but a hand-edited config may use single quotes or a bare
36
+ * key, so accept all three.
37
+ */
38
+ export function sidebarSlugs(configSource: string): Set<string> {
39
+ const slugs = new Set<string>();
40
+ for (const match of configSource.matchAll(/["']?slug["']?\s*:\s*["']([^"']+)["']/g)) {
41
+ slugs.add(match[1]);
42
+ }
43
+ return slugs;
44
+ }
45
+
46
+ /**
47
+ * Audit one lexicon directory for doc pages nothing links to.
48
+ *
49
+ * A lexicon with no docs site is not a failure here — tier 1's "at least 1
50
+ * .mdx doc page" already covers that case, and reporting the same absence
51
+ * twice would just be noise.
52
+ */
53
+ export function auditDocsReachability(lexiconDir: string): DocsReachability {
54
+ const contentDir = join(lexiconDir, "docs", "src", "content", "docs");
55
+ const configPath = join(lexiconDir, "docs", "astro.config.mjs");
56
+
57
+ if (!existsSync(contentDir) || !existsSync(configPath)) {
58
+ return { hasSite: false, pages: [], unreachable: [] };
59
+ }
60
+
61
+ const slugs = sidebarSlugs(readFileSync(configPath, "utf-8"));
62
+ const pages = readdirSync(contentDir)
63
+ .filter((f) => f.endsWith(".mdx") || f.endsWith(".md"))
64
+ .map((f) => f.replace(/\.mdx?$/, ""))
65
+ .sort();
66
+
67
+ // `index` is the site root; Starlight reaches it without a sidebar entry.
68
+ const unreachable = pages.filter((slug) => slug !== "index" && !slugs.has(slug));
69
+
70
+ return { hasSite: true, pages, unreachable };
71
+ }
@@ -2,6 +2,7 @@ import { existsSync, readdirSync, readFileSync } from "fs";
2
2
  import { join, basename } from "path";
3
3
  import { auditIntrinsics } from "./check-lexicon-intrinsics";
4
4
  import { checkExamplesBuild } from "./check-lexicon-examples";
5
+ import { auditDocsReachability } from "./check-lexicon-docs";
5
6
 
6
7
  // ── Types ────────────────────────────────────────────────────────────
7
8
 
@@ -283,6 +284,20 @@ export async function checkLexicon(dir: string): Promise<CheckResult> {
283
284
  detail: mdxFiles.length > 0 ? `${mdxFiles.length} page(s)` : undefined,
284
285
  });
285
286
 
287
+ // Counting pages says nothing about whether a reader can find them.
288
+ // Starlight has no auto-discovery, so a page missing from the sidebar is
289
+ // reachable only by direct URL (#1312).
290
+ const docsReach = auditDocsReachability(dir);
291
+ items.push({
292
+ name: "Every doc page is reachable from the sidebar",
293
+ tier: 1,
294
+ pass: !docsReach.hasSite || docsReach.unreachable.length === 0,
295
+ detail:
296
+ docsReach.unreachable.length > 0
297
+ ? `${docsReach.unreachable.length} unreachable: ${docsReach.unreachable.join(", ")}`
298
+ : undefined,
299
+ });
300
+
286
301
  // ── Tier 2: Recommended ────────────────────────────────────────
287
302
 
288
303
  const pluginContent = readOr(join(dir, "src/plugin.ts"));
@@ -46,7 +46,7 @@ import { discoverComponents } from "../../components/discover";
46
46
  import { formatError, formatWarning, formatSuccess, formatBold } from "../format";
47
47
  import type { CommandContext } from "../registry";
48
48
  import type { LexiconPlugin } from "../../lexicon";
49
- import { normalizeObservation, unobservedAll, type NormalizedObservation } from "../../observation";
49
+ import { normalizeObservation, mergeObservations, unobservedAll, type NormalizedObservation } from "../../observation";
50
50
  import type { Phase, Component } from "../../components/component";
51
51
 
52
52
  /**
@@ -184,6 +184,22 @@ interface StatusJsonRow {
184
184
  /** Why live state could not be read for this component (#1089). Mutually exclusive with `live`. */
185
185
  unobserved?: { reason: string; detail?: string };
186
186
  stack?: { name: string; status?: string; healthy?: boolean };
187
+ /**
188
+ * How this component's own resources answered (behold#98, chant#1300).
189
+ *
190
+ * `stack` above exists only where the substrate has a deploy object to read,
191
+ * which is AWS; these counts are the substrate-neutral answer to the same
192
+ * question, and finer-grained than a single stack verdict wherever both are
193
+ * present. #1300 added the field to `ComponentStatusRow` but not to this
194
+ * projection, which is the only surface a consumer sees — so until behold#100
195
+ * it never left the CLI.
196
+ *
197
+ * On AWS the counts inherit `describe-stack-resources`, so they report
198
+ * CloudFormation's per-resource inventory rather than independently observed
199
+ * existence; the per-type reader registry (#1269/#1271) applied to this thin
200
+ * path is what would make them a live check.
201
+ */
202
+ resources?: { total: number; present: number; absent: number; unobserved: number };
187
203
  }
188
204
 
189
205
  /**
@@ -340,6 +356,28 @@ export async function runComponentsStatus(ctx: CommandContext): Promise<number>
340
356
  try {
341
357
  const targetSerializers = serializers;
342
358
  const buildResult = await build(resolve(args.src ?? config.sourceDir ?? "."), targetSerializers);
359
+ // Which deployed stack(s) to read the change set from (behold#100).
360
+ //
361
+ // `describeResources` defaults to the single-stack convention — the
362
+ // stack named after the environment — which is wrong for exactly the
363
+ // projects this command exists for: a component project deploys the
364
+ // stack its own `cfn-deploy` names, and that is almost never the env
365
+ // name. Every declared resource then came back absent, so the rollup
366
+ // #1300 computes read `present: 0` over a healthy estate. That was
367
+ // invisible while nothing consumed the rollup; behold#100 paints from
368
+ // it, so it has to be right.
369
+ //
370
+ // The components' own `cfn-deploy` stacks are the authority (the same
371
+ // ones `observeComponentStacks` reads below), with `config.stacks` as
372
+ // the declared override for a project whose stacks aren't derivable
373
+ // from a deploy step. `[undefined]` keeps the old single-read
374
+ // behaviour for a project with neither.
375
+ const componentStackNames = new Set<string>();
376
+ for (const { component } of discovery.components.values()) {
377
+ for (const stack of cfnDeployStacks(component.deploy)) componentStackNames.add(stack);
378
+ }
379
+ for (const stack of config.stacks ?? []) componentStackNames.add(stack.name);
380
+ const readTargets: Array<string | undefined> = componentStackNames.size ? [...componentStackNames] : [undefined];
343
381
  const merged: { env: string; entries: import("../../lifecycle/change-set").ChangeSetEntry[] } = { env: environment, entries: [] };
344
382
  for (const plugin of plugins) {
345
383
  if (!plugin.describeResources) continue;
@@ -356,8 +394,20 @@ export async function runComponentsStatus(ctx: CommandContext): Promise<number>
356
394
  }
357
395
  let observed: NormalizedObservation;
358
396
  try {
359
- observed = normalizeObservation(
360
- await plugin.describeResources({ environment, buildOutput: "", entityNames: Array.from(declared), entities }),
397
+ observed = mergeObservations(
398
+ await Promise.all(
399
+ readTargets.map(async (stack) =>
400
+ normalizeObservation(
401
+ await plugin.describeResources!({
402
+ environment,
403
+ buildOutput: "",
404
+ entityNames: Array.from(declared),
405
+ entities,
406
+ ...(stack ? { stack } : {}),
407
+ }),
408
+ ),
409
+ ),
410
+ ),
361
411
  );
362
412
  } catch (err) {
363
413
  // A failed read is not an empty environment (#1089): mark every
@@ -464,6 +514,7 @@ export async function runComponentsStatus(ctx: CommandContext): Promise<number>
464
514
  ...(row.live !== undefined ? { live: row.live } : {}),
465
515
  ...(row.unobserved ? { unobserved: row.unobserved } : {}),
466
516
  ...(row.stack ? { stack: row.stack } : {}),
517
+ ...(row.resources ? { resources: row.resources } : {}),
467
518
  });
468
519
  }
469
520
  }