@intentius/chant 0.20.0 → 0.21.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 (45) hide show
  1. package/dist/cli/commands/check-lexicon-intrinsics.d.ts +17 -0
  2. package/dist/cli/commands/check-lexicon-intrinsics.d.ts.map +1 -1
  3. package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
  4. package/dist/codegen/docs-types.d.ts +2 -0
  5. package/dist/codegen/docs-types.d.ts.map +1 -1
  6. package/dist/declarable.d.ts +16 -0
  7. package/dist/declarable.d.ts.map +1 -1
  8. package/dist/discovery/entity-wire-codec.d.ts.map +1 -1
  9. package/dist/discovery/fold-import.d.ts +30 -1
  10. package/dist/discovery/fold-import.d.ts.map +1 -1
  11. package/dist/discovery/index.d.ts.map +1 -1
  12. package/dist/fold/fold.d.ts +89 -16
  13. package/dist/fold/fold.d.ts.map +1 -1
  14. package/dist/fold/foldable-helpers.d.ts +121 -0
  15. package/dist/fold/foldable-helpers.d.ts.map +1 -0
  16. package/dist/fold/subset.d.ts +35 -3
  17. package/dist/fold/subset.d.ts.map +1 -1
  18. package/dist/lexicon-schema.d.ts +2 -0
  19. package/dist/lexicon-schema.d.ts.map +1 -1
  20. package/dist/lexicon.d.ts +73 -23
  21. package/dist/lexicon.d.ts.map +1 -1
  22. package/dist/runtime.d.ts +10 -1
  23. package/dist/runtime.d.ts.map +1 -1
  24. package/package.json +1 -1
  25. package/src/cli/commands/check-lexicon-intrinsics.test.ts +35 -1
  26. package/src/cli/commands/check-lexicon-intrinsics.ts +38 -2
  27. package/src/cli/commands/check-lexicon.ts +18 -0
  28. package/src/codegen/docs-sections.test.ts +7 -1
  29. package/src/codegen/docs-sections.ts +1 -1
  30. package/src/codegen/docs-types.ts +2 -0
  31. package/src/declarable.ts +20 -0
  32. package/src/discovery/entity-wire-codec.ts +9 -7
  33. package/src/discovery/fold-import.test.ts +572 -0
  34. package/src/discovery/fold-import.ts +229 -36
  35. package/src/discovery/index.ts +9 -0
  36. package/src/fold/fold.test.ts +277 -0
  37. package/src/fold/fold.ts +213 -56
  38. package/src/fold/foldable-helpers.ts +171 -0
  39. package/src/fold/subset-doc-parity.test.ts +27 -0
  40. package/src/fold/subset.test.ts +111 -0
  41. package/src/fold/subset.ts +109 -28
  42. package/src/lexicon-schema.test.ts +43 -0
  43. package/src/lexicon-schema.ts +5 -0
  44. package/src/lexicon.ts +74 -24
  45. package/src/runtime.ts +11 -2
@@ -24,11 +24,20 @@
24
24
  * tag (see ../../fold/fold.ts). Anything else (a plain function, a class,
25
25
  * a const object/proxy) cannot be invoked as `` Name`...` `` and must be
26
26
  * `isTag: false`.
27
+ *
28
+ * chant #1044 adds a third question, for the same reason the first two
29
+ * exist: `foldsAsCall` opts an intrinsic's PLAIN-CALL form into folding, so
30
+ * declaring it on something authored as a tagged template claims a form that
31
+ * cannot be called that way. The two flags are mutually exclusive, and a
32
+ * registration setting both is a failure here rather than a silently ignored
33
+ * field.
27
34
  */
28
35
  export interface IntrinsicAuditItem {
29
36
  name: string;
30
37
  /** The `isTag` value as registered in `src/plugin.ts`'s `intrinsics()`. */
31
38
  declaredIsTag: boolean | undefined;
39
+ /** The `foldsAsCall` opt-in as registered in `src/plugin.ts` (chant #1044); `undefined` when absent, which means "not opted in". */
40
+ declaredFoldsAsCall: boolean | undefined;
32
41
  /** Whether `name` resolves to a real export of `src/index.ts`. */
33
42
  exported: boolean;
34
43
  /**
@@ -43,6 +52,14 @@ export interface IntrinsicAuditItem {
43
52
  /** True only when exported AND the authored shape matches `declaredIsTag`. */
44
53
  ok: boolean;
45
54
  detail?: string;
55
+ /**
56
+ * chant #1044 — false only when `foldsAsCall: true` is registered on
57
+ * something authored as a tagged template. Tracked separately from
58
+ * {@link ok} so the two failures report as the two different registration
59
+ * mistakes they are, rather than one message covering both.
60
+ */
61
+ callFormOk: boolean;
62
+ callFormDetail?: string;
46
63
  }
47
64
  /**
48
65
  * Audit every intrinsic a lexicon registers in `src/plugin.ts` against
@@ -1 +1 @@
1
- {"version":3,"file":"check-lexicon-intrinsics.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/check-lexicon-intrinsics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAQH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,kEAAkE;IAClE,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;OAOG;IACH,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,8EAA8E;IAC9E,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAsMD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAuDxE"}
1
+ {"version":3,"file":"check-lexicon-intrinsics.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/check-lexicon-intrinsics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAQH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,oIAAoI;IACpI,mBAAmB,EAAE,OAAO,GAAG,SAAS,CAAC;IACzC,kEAAkE;IAClE,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;OAOG;IACH,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,8EAA8E;IAC9E,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA2MD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAqExE"}
@@ -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,CAqZpE;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":"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"}
@@ -61,6 +61,8 @@ export interface ManifestJSON {
61
61
  description?: string;
62
62
  outputKey?: string;
63
63
  isTag?: boolean;
64
+ /** chant #1044 — the call-form fold opt-in, as published in the lexicon's manifest. Absent in any manifest built before #1044, which reads the same as "not opted in". */
65
+ foldsAsCall?: boolean;
64
66
  }>;
65
67
  pseudoParameters?: Record<string, string>;
66
68
  }
@@ -1 +1 @@
1
- {"version":3,"file":"docs-types.d.ts","sourceRoot":"","sources":["../../src/codegen/docs-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"docs-types.d.ts","sourceRoot":"","sources":["../../src/codegen/docs-types.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,22 @@ export interface Declarable {
11
11
  readonly kind?: "resource" | "property" | "output";
12
12
  readonly [DECLARABLE_MARKER]: true;
13
13
  }
14
+ /**
15
+ * A `Declarable` that carries a resource payload — the `props`/`attributes`
16
+ * fields that most lexicon serializers read to produce output. Not every
17
+ * `Declarable` has one (outputs and parameters genuinely don't), so this is
18
+ * kept as a sub-interface rather than widening the base type. See chant #1049.
19
+ */
20
+ export interface ResourceDeclarable extends Declarable {
21
+ readonly props: unknown;
22
+ readonly attributes?: unknown;
23
+ }
24
+ /**
25
+ * Type guard for `ResourceDeclarable` — replaces the ad-hoc `"props" in x`
26
+ * checks that were previously repeated (with an `as unknown as` cast) at every
27
+ * call site that reads `props`/`attributes` off a `Declarable`.
28
+ */
29
+ export declare function isResourceDeclarable(value: Declarable): value is ResourceDeclarable;
14
30
  /**
15
31
  * Core parameter type for lexicon-agnostic parameters
16
32
  */
@@ -1 +1 @@
1
- {"version":3,"file":"declarable.d.ts","sourceRoot":"","sources":["../src/declarable.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,iBAAiB,eAAiC,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;IACnD,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAOhE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAE/D"}
1
+ {"version":3,"file":"declarable.d.ts","sourceRoot":"","sources":["../src/declarable.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,iBAAiB,eAAiC,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;IACnD,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC;CACpC;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAmB,SAAQ,UAAU;IACpD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,KAAK,IAAI,kBAAkB,CAEnF;AAED;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAOhE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAE/D"}
@@ -1 +1 @@
1
- {"version":3,"file":"entity-wire-codec.d.ts","sourceRoot":"","sources":["../../src/discovery/entity-wire-codec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAOnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,MAAM,SAAS,GACjB,IAAI,GACJ,MAAM,GACN,MAAM,GACN,OAAO,GACP,SAAS,EAAE,GACX;IAAE,SAAS,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACpD;IAAE,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACnC;IAAE,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,SAAS,CAAA;KAAE,CAAA;CAAE,GAC1E;IAAE,WAAW,EAAE;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,IAAI,CAAC,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,SAAS,EAAE,CAAA;KAAE,CAAA;CAAE,GAC1E;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjC,kIAAkI;AAClI,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC1C,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC;AAED,iKAAiK;AACjK,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,+HAA+H;IAC/H,GAAG,EAAE,SAAS,CAAC;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,oBAAoB,GAAG,uBAAuB,CAAC;AAExE,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAiKD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,aAAa,CAoBhF;AAuGD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAwC5E"}
1
+ {"version":3,"file":"entity-wire-codec.d.ts","sourceRoot":"","sources":["../../src/discovery/entity-wire-codec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,EAA2C,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAOzF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,MAAM,SAAS,GACjB,IAAI,GACJ,MAAM,GACN,MAAM,GACN,OAAO,GACP,SAAS,EAAE,GACX;IAAE,SAAS,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACpD;IAAE,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACnC;IAAE,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,SAAS,CAAA;KAAE,CAAA;CAAE,GAC1E;IAAE,WAAW,EAAE;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,IAAI,CAAC,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,SAAS,EAAE,CAAA;KAAE,CAAA;CAAE,GAC1E;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjC,kIAAkI;AAClI,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC1C,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC;AAED,iKAAiK;AACjK,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,+HAA+H;IAC/H,GAAG,EAAE,SAAS,CAAC;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,oBAAoB,GAAG,uBAAuB,CAAC;AAExE,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAmKD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,aAAa,CAoBhF;AAuGD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAwC5E"}
@@ -59,6 +59,20 @@ export type FoldFileResult = {
59
59
  * exact same object every referencing file sees.
60
60
  */
61
61
  exportedValues: Map<string, unknown>;
62
+ /**
63
+ * chant #1044 — the OTHER project files whose exported OBJECTS this
64
+ * fold consumed (a cross-file `Declarable`, composite instance, or any
65
+ * other non-primitive reached through `buildExternals`/a re-export).
66
+ *
67
+ * Object identity is the thing that cannot survive one side of the
68
+ * build folding while the other runs, so `planFoldTaint` needs to know
69
+ * who consumed whose objects: if a file here is forced back to run, the
70
+ * instance THIS file already captured is not the instance discovery
71
+ * will collect, and serialization fails on an entity with no logical
72
+ * name. A primitive (string, number, boolean, null) is never recorded —
73
+ * it has no identity to disagree about.
74
+ */
75
+ liveSources: ReadonlySet<string>;
62
76
  } | {
63
77
  ok: false;
64
78
  reason: string;
@@ -194,6 +208,21 @@ export declare function tryFoldFile(file: string, intrinsics?: readonly Intrinsi
194
208
  * the discovered files' relative-import graph, seeded from every file that
195
209
  * doesn't fold on its own.
196
210
  *
211
+ * chant #1044 adds the OTHER half of the same hazard, in the opposite
212
+ * direction along the same edges. Forward taint covers "a run file imports a
213
+ * folded file"; it does not cover "a FOLDED file consumed the objects of a
214
+ * file that later got forced to run". Once a plain-call intrinsic can fold,
215
+ * that second case is easy to reach: in `lexicons/aws/examples/lambda-api`,
216
+ * `health-api.ts` folds and captures `params.ts`'s real `Parameter` instance
217
+ * through `Ref(environment)`, while `params.ts` itself is forced to run
218
+ * because a DIFFERENT sibling (`data-bucket.ts`) imports it and falls back.
219
+ * Discovery then collects the run instance and serializes the folded one —
220
+ * the same "Logical name not set" crash described above, arriving from the
221
+ * other side. So `liveSources` (see {@link FoldFileResult}) contributes
222
+ * reverse edges here: a tainted file taints every folded file that captured
223
+ * one of its objects. Only object identity propagates — a file that imported
224
+ * a plain string from a tainted file has nothing to disagree about.
225
+ *
197
226
  * chant #1020 changes the calculus but not this function: `alb.ts` can now
198
227
  * often fold `network.vpc.VpcId` too (see `buildExternals`/`foldFileMemoized`
199
228
  * above), by reusing THE EXACT SAME `tryFoldFile("network.ts")` call (memoized
@@ -206,5 +235,5 @@ export declare function tryFoldFile(file: string, intrinsics?: readonly Intrinsi
206
235
  * so the exact same forced-taint safety net still applies to that remaining
207
236
  * boundary, unchanged.
208
237
  */
209
- export declare function planFoldTaint(files: readonly string[], wouldFold: ReadonlyMap<string, boolean>): Promise<Set<string>>;
238
+ export declare function planFoldTaint(files: readonly string[], wouldFold: ReadonlyMap<string, boolean>, liveSources?: ReadonlyMap<string, ReadonlySet<string>>): Promise<Set<string>>;
210
239
  //# sourceMappingURL=fold-import.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fold-import.d.ts","sourceRoot":"","sources":["../../src/discovery/fold-import.ts"],"names":[],"mappings":"AAMA,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAc3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,mGAAmG;AACnG,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,iBAAiB,CAAC,CAAC;AAElF,MAAM,MAAM,cAAc,GACtB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB;;;;;;;;;OASG;IACH,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,SAAS,YAAY,EAAE,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACpE;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;CAClE;AAED,iDAAiD;AACjD,wBAAgB,iBAAiB,CAC/B,UAAU,GAAE,SAAS,YAAY,EAAO,EACxC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,GACtD,WAAW,CAEb;AAq9CD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,SAAS,YAAY,EAAO,EACxC,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,cAAc,CAAC,CAEzB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GACtC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CA8DtB"}
1
+ {"version":3,"file":"fold-import.d.ts","sourceRoot":"","sources":["../../src/discovery/fold-import.ts"],"names":[],"mappings":"AAMA,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAgB3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,mGAAmG;AACnG,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,iBAAiB,CAAC,CAAC;AAElF,MAAM,MAAM,cAAc,GACtB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB;;;;;;;;;OASG;IACH,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC;;;;;;;;;;;;OAYG;IACH,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAClC,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,SAAS,YAAY,EAAE,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACpE;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;CAClE;AAED,iDAAiD;AACjD,wBAAgB,iBAAiB,CAC/B,UAAU,GAAE,SAAS,YAAY,EAAO,EACxC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,GACtD,WAAW,CAEb;AAsmDD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,SAAS,YAAY,EAAO,EACxC,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,cAAc,CAAC,CAEzB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,GACrD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CA8EtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQ/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAI1D;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,gGAAgG;IAChG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAE5B;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClC,8DAA8D;IAC9D,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACvC,qDAAqD;IACrD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,mDAAmD;IACnD,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB;;;OAGG;IACH,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CA2PjG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQ/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAI1D;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,gGAAgG;IAChG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAE5B;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClC,8DAA8D;IAC9D,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACvC,qDAAqD;IACrD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,mDAAmD;IACnD,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB;;;OAGG;IACH,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAoQjG"}
@@ -17,9 +17,22 @@ import { type SubsetRuleId } from "./subset.js";
17
17
  * ({@link "../lint/rules/evl001-non-literal-expression"}), so the linted
18
18
  * subset and the folded subset can never drift apart (#1024).
19
19
  *
20
- * A `CallExpression` has no case — a function call as a value is
20
+ * A `CallExpression` has almost no case — a function call as a value is
21
21
  * structurally unrepresentable, not merely linted against. Composite
22
- * factory calls are out of scope here (epic Phase 5, #1023).
22
+ * factory calls are out of scope here (epic Phase 5, #1023). There are
23
+ * exactly two exceptions, both closed allowlists of names declared
24
+ * somewhere a human had to write them down, and both reducing to a symbolic
25
+ * envelope that executes nothing here:
26
+ *
27
+ * - a call to a REGISTERED chant authoring helper
28
+ * ({@link "./foldable-helpers"}, chant #1082) → {@link FoldedHelperCall};
29
+ * - a call to a lexicon intrinsic whose lexicon registered it AND opted
30
+ * its call form in ({@link intrinsicCallFolds}, ../lexicon.ts, chant
31
+ * #1044) → {@link FoldedIntrinsicCall}, the same `{__intrinsic}` family
32
+ * the tagged-template form already reduces to.
33
+ *
34
+ * Everything else — a user's function, a method call, an array `.map`, a
35
+ * registered name shadowed by a local binding — still throws.
23
36
  *
24
37
  * Cross-file identifier resolution (chant #1020): `consts` alone is always
25
38
  * this file's own top-level bindings — that part stays single-file, and
@@ -45,7 +58,7 @@ import { type SubsetRuleId } from "./subset.js";
45
58
  */
46
59
  export type FoldedValue = string | number | boolean | null | undefined | FoldedValue[] | {
47
60
  [key: string]: FoldedValue;
48
- } | AttrRefValue | FoldedIntrinsic | SymbolicValue | FoldedResource;
61
+ } | AttrRefValue | FoldedIntrinsic | FoldedHelperCall | SymbolicValue | FoldedResource;
49
62
  /**
50
63
  * Symbolic reference produced when a property/element access resolves to an
51
64
  * attribute of another `const`-declared resource in the same file, e.g.
@@ -72,11 +85,46 @@ export interface AttrRefValue {
72
85
  * Mirrors the runtime call shape `Tag(strings, ...values)` so a later
73
86
  * build path can replay it into the real intrinsic object (#1022).
74
87
  */
75
- export interface FoldedIntrinsic {
88
+ export type FoldedIntrinsic = FoldedIntrinsicTag | FoldedIntrinsicCall;
89
+ /** The tagged-template form: `Sub\`${x}-y\`` — see {@link FoldedIntrinsic}. */
90
+ export interface FoldedIntrinsicTag {
76
91
  __intrinsic: string;
77
92
  strings: string[];
78
93
  values: FoldedValue[];
79
94
  }
95
+ /**
96
+ * The plain-call form of a registered, opted-in lexicon intrinsic
97
+ * (chant #1044) — `Ref(bucket)`, `Concat("a", b)`, `GetAtt("Fn", "Arn")`.
98
+ * Same `__intrinsic` key as the tagged-template form, so the same revival
99
+ * branch handles both and nothing downstream learns a new envelope; the
100
+ * payload differs because the call shape does — positional `args` mirroring
101
+ * `Name(...args)`, where the tag form mirrors `Name(strings, ...values)`.
102
+ *
103
+ * Symbolic, exactly like the tag form: `fold()` executes nothing, it only
104
+ * records that a registered intrinsic was called and with what. The real
105
+ * function is resolved through the folding file's own imports and invoked by
106
+ * `../discovery/fold-import.ts`'s `reviveFoldedValue`.
107
+ */
108
+ export interface FoldedIntrinsicCall {
109
+ __intrinsic: string;
110
+ args: FoldedValue[];
111
+ }
112
+ /**
113
+ * The result of folding a call to a registered chant authoring helper
114
+ * (chant #1082) — e.g. `phase("Apply", [...])`, `output(ref, "oX")`. Holds
115
+ * the helper's name and its folded arguments, in source order.
116
+ *
117
+ * Symbolic, exactly like {@link FoldedIntrinsic}: `fold()` executes nothing,
118
+ * it only records that a registered helper was called and with what. The real
119
+ * function is resolved through the folding file's own imports and invoked by
120
+ * `../discovery/fold-import.ts`'s `reviveFoldedValue`, which is also where
121
+ * the "is this name actually bound to chant's own helper" check lives. See
122
+ * {@link "./foldable-helpers"} for the allowlist and why it is closed.
123
+ */
124
+ export interface FoldedHelperCall {
125
+ __helper: string;
126
+ args: FoldedValue[];
127
+ }
80
128
  /**
81
129
  * A sub-expression inside a folded intrinsic that fold could not reduce to
82
130
  * a value without resolving an identifier from outside this file — e.g. an
@@ -107,6 +155,18 @@ export interface FoldedResource {
107
155
  attributes?: {
108
156
  [key: string]: FoldedValue;
109
157
  };
158
+ /**
159
+ * chant #1082 — every constructor argument, folded, in source order. Present
160
+ * only when the argument list is NOT the classic `(props)` / `(props,
161
+ * attributes)` shape — most often because the props object isn't first
162
+ * (`new Parameter("String", {...})`, whose signature is `(type, props)`).
163
+ *
164
+ * When present this is authoritative: the entity is constructed by spreading
165
+ * it, so the constructor receives exactly what the source wrote. `props`
166
+ * alongside it is the first object-literal argument, reported for readers,
167
+ * never re-passed (which would double-count it).
168
+ */
169
+ args?: FoldedValue[];
110
170
  }
111
171
  /**
112
172
  * One entry per exported `const` resource declaration in {@link foldModule}'s
@@ -188,13 +248,15 @@ export declare function collectConsts(sourceFile: ts.SourceFile): Map<string, ts
188
248
  /**
189
249
  * Fold a single expression node to a value. Throws {@link FoldError} for
190
250
  * anything outside the supported subset — including any `CallExpression`
191
- * that isn't a registered intrinsic tagged template.
251
+ * that is neither a registered chant authoring helper nor a registered,
252
+ * call-form-opted-in lexicon intrinsic (see the module doc).
192
253
  *
193
- * @param intrinsics - Lexicon-registered intrinsics that fold
194
- * ({@link intrinsicFolds}, e.g. `Sub`). A tagged template whose tag isn't
195
- * in this list, or is registered but not foldable, is rejected. Defaults
196
- * to none pass the target lexicon's manifest `intrinsics` to recognize
197
- * its tags.
254
+ * @param intrinsics - The active lexicons' registered intrinsics. A tagged
255
+ * template whose tag isn't in this list, or is in it without
256
+ * {@link intrinsicTagFolds}, is rejected; a plain call is rejected unless
257
+ * its callee is in this list with {@link intrinsicCallFolds} (chant
258
+ * #1044). Defaults to none — pass the target lexicon's manifest
259
+ * `intrinsics` to recognize either form.
198
260
  * @param externals - chant #1020: pre-resolved imported bindings, consulted
199
261
  * only when an identifier isn't in `consts`. See the module doc above.
200
262
  * `undefined` (the default) preserves the exact pre-#1020 single-file
@@ -202,12 +264,23 @@ export declare function collectConsts(sourceFile: ts.SourceFile): Map<string, ts
202
264
  */
203
265
  export declare function fold(node: ts.Expression, consts: Map<string, ts.Expression>, intrinsics?: readonly IntrinsicDef[], externals?: ReadonlyMap<string, unknown>): FoldedValue;
204
266
  /**
205
- * Fold a resource constructor call `new Type({ ...props }, { ...attributes
206
- * })` — to its spec. Each argument present must be an object literal
207
- * (anything else is not statically evaluable and throws a located
208
- * {@link FoldError}). The second argument (CFN-style resource attributes —
209
- * `DependsOn`, `Condition`, `DeletionPolicy`, …) is optional, matching
210
- * `createResource`'s runtime constructor signature (../runtime.ts).
267
+ * Fold a resource constructor call to its spec.
268
+ *
269
+ * The common `createResource` shape (../runtime.ts) is `new Type({ ...props
270
+ * })` or `new Type({ ...props }, { ...attributes })` CFN-style resource
271
+ * attributes (`DependsOn`, `Condition`, `DeletionPolicy`, …) second and
272
+ * that shape reduces to `props` (+ `attributes`) exactly as before.
273
+ *
274
+ * chant #1082 — but that is a convention, not a rule every lexicon class
275
+ * follows. AWS's deploy-time `Parameter` is `(type, props)`
276
+ * (lexicons/aws/src/parameter.ts): the props object is the SECOND argument
277
+ * and the first is a plain string. `foldResource` used to require argument 0
278
+ * to be an object literal, so no `new Parameter(...)` anywhere could ever
279
+ * fold, whatever surrounded it. The general case now folds every argument in
280
+ * source order into {@link FoldedResource.args}, which the caller constructs
281
+ * the entity from verbatim — no positional assumption at all. `props` is
282
+ * still reported (the first object-literal argument, for callers that read
283
+ * it) but is a VIEW onto `args`, not the thing constructed from.
211
284
  */
212
285
  export declare function foldResource(node: ts.NewExpression, consts: Map<string, ts.Expression>, intrinsics?: readonly IntrinsicDef[], externals?: ReadonlyMap<string, unknown>): FoldedResource;
213
286
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../../src/fold/fold.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../../src/fold/fold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * foldable-helpers — the closed, declared allowlist of chant's OWN authoring
3
+ * helpers that a call expression may fold through (chant #1082, epic #1019).
4
+ *
5
+ * ## Why this exists
6
+ *
7
+ * `fold()` has no general case for a `CallExpression`: a function call as a
8
+ * value is structurally unrepresentable there, because folding it would mean
9
+ * executing code, which is the one thing the fold path exists to avoid. That
10
+ * rule is right for user code and stays right — a user's own function, an
11
+ * arrow function, a method call (`naming.name(...)`) all keep failing exactly
12
+ * as before.
13
+ *
14
+ * But it also blocks chant's own documented authoring API. `phase("Apply",
15
+ * [...])` is how the component contract says to write a component; `output(ref,
16
+ * "oX")` is how a lexicon output is authored. An application cannot avoid them
17
+ * and still use components or outputs, so every file that uses one falls back
18
+ * to run no matter how statically evaluable the rest of it is.
19
+ *
20
+ * #1044 already settled the shape of the answer one level down, for lexicon
21
+ * intrinsics: a call-shaped thing may fold ONLY when it is registered, opt-in,
22
+ * per-helper — never because it merely looks like a call. This module is the
23
+ * same decision applied one level up, to chant's own helpers, with the
24
+ * registration written here by hand instead of coming from a lexicon manifest.
25
+ *
26
+ * ## What "registered" buys, and what still has to be true
27
+ *
28
+ * A name in this list is NOT permission to invoke whatever it happens to be
29
+ * bound to. Folding a helper call is a two-key operation:
30
+ *
31
+ * 1. **Shape + name** (here, and in `fold()`/`findSubsetViolation`): the
32
+ * callee is a bare identifier whose text is in {@link
33
+ * FOLDABLE_AUTHORING_HELPERS} and which is not shadowed by a local
34
+ * `const`. `fold()` reduces the call to a symbolic
35
+ * `{ __helper, args }` envelope — it still executes nothing.
36
+ * 2. **Provenance + invocation** (`../discovery/fold-import.ts`): the
37
+ * envelope is revived by resolving that name through the folding FILE'S
38
+ * OWN `import` bindings and checking the import actually comes from chant
39
+ * ({@link isChantOwnedSpecifier}, or a path inside chant-core's own tree
40
+ * for in-repo/absolute-specifier callers). Only then is the real function
41
+ * invoked, with the real folded arguments. A same-named helper imported
42
+ * from somewhere else, or declared in the file itself, resolves to
43
+ * nothing chant owns and the whole file falls back to run.
44
+ *
45
+ * So the function that runs is always the same function the run path would
46
+ * have called, from the same module the source itself imported — fold does not
47
+ * substitute its own reimplementation, which is why this list cannot drift
48
+ * from the helpers' real behavior.
49
+ *
50
+ * ## Admission criteria
51
+ *
52
+ * A helper belongs here only if all of these hold:
53
+ *
54
+ * - chant owns and documents it as authoring surface;
55
+ * - it is a pure function of its arguments — no I/O, no `process.env`, no
56
+ * module-level mutable state, no observable side effect;
57
+ * - calling it early (at fold time) is indistinguishable from calling it
58
+ * during a real run of the file.
59
+ *
60
+ * Deliberately NOT admitted — see this module's tests and the #1082 PR body:
61
+ *
62
+ * - `env()` (`../env.ts`) reads `process.env`. Folding it would bake one
63
+ * run's environment into a statically-derived value. It is exactly the
64
+ * kind of call fold must keep rejecting.
65
+ * - `Op()` (`../op/builders.ts`) constructs an `OpResource` — a `Declarable`.
66
+ * `fold()` already rejects a nested `new Type(...)` used as a value for a
67
+ * real, differential-caught reason (the envelope leaks into
68
+ * serialization); a factory that returns one is the same hazard wearing a
69
+ * call.
70
+ * - `propagate()`, `withDefaults()`, `resource()`, `mergeDefaults()`
71
+ * (`../composite.ts`) are composite *definition* helpers, not value-position
72
+ * helpers. `propagate()` in particular mutates its argument in place, and
73
+ * the composite spine in fold-import.ts already resolves it live.
74
+ * - `createResource()`/`createProperty()` (`../runtime.ts`) are used at a
75
+ * lexicon module's top level to build classes, never as a value inside a
76
+ * project file.
77
+ * - Lexicon intrinsics in CALL form (`Ref(...)`, `Join(...)`) are lexicon
78
+ * surface, not chant's own, and are #1044's registry (`IntrinsicDef`,
79
+ * `../lexicon.ts`) to admit — not this one. Only their tagged-template
80
+ * form folds today.
81
+ */
82
+ /**
83
+ * One registered helper. `module` and `note` carry no runtime behavior — they
84
+ * are the audit trail for why this entry passed the admission criteria above,
85
+ * kept next to the name it justifies rather than in a comment that can drift
86
+ * away from the list.
87
+ */
88
+ export interface FoldableHelperDef {
89
+ /** The exported name, matched against the callee identifier's text. */
90
+ readonly name: string;
91
+ /** Where chant defines it (a path under `packages/core/src`, for the audit trail). */
92
+ readonly module: string;
93
+ /** Why it qualifies — what it returns and why calling it at fold time is safe. */
94
+ readonly note: string;
95
+ }
96
+ /**
97
+ * The allowlist. Adding an entry is a deliberate act: it must satisfy every
98
+ * admission criterion in this module's doc, and it widens what `fold()` and
99
+ * `findSubsetViolation` accept for EVERY project, so it belongs in a PR that
100
+ * says so.
101
+ *
102
+ * Two names below are defined TWICE in chant, by different modules, with
103
+ * different return types (`phase`/`gate` by both the component contract and
104
+ * the Op builders; `stackOutput` by both the component contract and the
105
+ * cross-stack output primitive). That is fine and needs no disambiguation
106
+ * here: registration is by name, but the function actually invoked is the one
107
+ * the folding file itself imported (see step 2 in the module doc), so each
108
+ * file gets its own. Both definitions of each name independently satisfy the
109
+ * criteria, which is what makes registering the shared name safe.
110
+ */
111
+ export declare const FOLDABLE_AUTHORING_HELPERS: readonly FoldableHelperDef[];
112
+ /**
113
+ * True when `name` is a registered foldable authoring helper. Name-only — this
114
+ * is the shape-level half of the check (step 1 in the module doc). It says
115
+ * nothing about where the name is bound; `../discovery/fold-import.ts` decides
116
+ * that before anything is invoked.
117
+ */
118
+ export declare function isFoldableHelperName(name: string): boolean;
119
+ /** True for a bare specifier that names a chant-published package (or one of its subpaths). */
120
+ export declare function isChantOwnedSpecifier(specifier: string): boolean;
121
+ //# sourceMappingURL=foldable-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foldable-helpers.d.ts","sourceRoot":"","sources":["../../src/fold/foldable-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AAEH;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,iBAAiB,EA0BlE,CAAC;AAIF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAeD,+FAA+F;AAC/F,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAIhE"}
@@ -1,4 +1,5 @@
1
1
  import * as ts from "typescript";
2
+ import { type IntrinsicDef } from "../lexicon.js";
2
3
  /**
3
4
  * subset — the single canonical definition of chant's statically-foldable
4
5
  * expression subset (chant #1024, epic #1019).
@@ -36,6 +37,38 @@ import * as ts from "typescript";
36
37
  * manifest, which isn't available to a syntax-only lint rule. `fold()`
37
38
  * alone checks it; this module treats any tag name as shape-valid and
38
39
  * only classifies the interpolated values.
40
+ * 2b. Authoring-helper *provenance* (chant #1082) — a call to a registered
41
+ * chant helper (`phase(...)`, `output(...)`; ./foldable-helpers.ts)
42
+ * folds, but only when the name is genuinely bound to an import of
43
+ * chant's own. That needs the module graph, which a syntax-only lint
44
+ * rule doesn't have. This module checks the NAME only and stays
45
+ * permissive; `fold()`'s bridge does the provenance check and falls the
46
+ * file back to run when it fails. Same direction as every other item
47
+ * here — a false negative for EVL, never a false positive.
48
+ * 2c. Intrinsic *call-form* registration (chant #1044) — a plain call to a
49
+ * lexicon intrinsic the lexicon opted in (`Ref(bucket)`,
50
+ * `Concat(a, b)`; `IntrinsicDef.foldsAsCall`, ../lexicon.ts) folds.
51
+ * Whether a given name is such an intrinsic is not knowable from shape,
52
+ * so {@link findSubsetViolation} takes the registry as an OPTIONAL
53
+ * parameter instead of guessing: supply it and the answer for a call is
54
+ * exact (fold()'s own), omit it and every call is a violation, the
55
+ * pre-#1044 answer.
56
+ *
57
+ * That parameter is the whole reason the call case lives here rather
58
+ * than only in `fold()`. This module is a shared predicate, and the
59
+ * point of a shared predicate is that a consumer can ask "will this
60
+ * fold?" without running fold — a control plane deciding whether a
61
+ * repository needs a sandboxed child process at all, for instance.
62
+ * Keeping the case out of here would make the predicate answer "no" for
63
+ * idiomatic `Ref(...)` source that `fold()` reduces cleanly: not a
64
+ * permissive gap but a systematically WRONG answer in the expensive
65
+ * direction, and the one direction this module is not allowed to be
66
+ * wrong in (see the false-negative/false-positive rule in point 1, and
67
+ * the flow-sensitivity note below — the single divergence in the other
68
+ * direction, and the one this module treats as a wart). A caller with
69
+ * no registry degrades to "assume it runs", which is safe and cheap to
70
+ * reason about; EVL is exactly such a caller and its behavior on calls
71
+ * is unchanged by #1044.
39
72
  * 3. Runtime *type* of a folded value — e.g. spreading `const n = 5`
40
73
  * (`{...n}`) is shape-valid (`n` is a plain identifier) but `fold()`
41
74
  * rejects it once it discovers `n` folds to a number, not an object.
@@ -79,7 +112,6 @@ export declare const UNSUPPORTED_UNARY_MESSAGE = "unsupported unary";
79
112
  export declare function unsupportedBinaryMessage(opKind: ts.SyntaxKind): string;
80
113
  export declare function callExpressionMessage(node: ts.CallExpression): string;
81
114
  export declare function unsupportedExpressionMessage(node: ts.Node): string;
82
- export declare function resourceCtorArgMessage(typeName: string): string;
83
115
  /**
84
116
  * Classify one object-literal member (`{ a: 1 }`'s `a: 1`, `{ ...x }`'s
85
117
  * `...x`, or a shorthand `{ a }`). Checks the key's shape before the
@@ -87,7 +119,7 @@ export declare function resourceCtorArgMessage(typeName: string): string;
87
119
  * the value. Returns the first violation within this member, or
88
120
  * `undefined` when it's fully in the subset.
89
121
  */
90
- export declare function checkObjectMember(prop: ts.ObjectLiteralElementLike): SubsetViolation | undefined;
122
+ export declare function checkObjectMember(prop: ts.ObjectLiteralElementLike, intrinsics?: readonly IntrinsicDef[]): SubsetViolation | undefined;
91
123
  /**
92
124
  * The canonical recursive shape classifier: is `node`'s expression *shape*
93
125
  * within the subset `fold()` can reduce? Mirrors `fold()`'s own dispatch
@@ -98,5 +130,5 @@ export declare function checkObjectMember(prop: ts.ObjectLiteralElementLike): Su
98
130
  * `fold()`-evaluation-order) unsupported node, or `undefined` when `node`'s
99
131
  * whole shape is foldable.
100
132
  */
101
- export declare function findSubsetViolation(node: ts.Node): SubsetViolation | undefined;
133
+ export declare function findSubsetViolation(node: ts.Node, intrinsics?: readonly IntrinsicDef[]): SubsetViolation | undefined;
102
134
  //# sourceMappingURL=subset.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"subset.d.ts","sourceRoot":"","sources":["../../src/fold/subset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH,mEAAmE;AACnE,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE/C,uGAAuG;AACvG,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,0FAA0F;AAC1F,eAAO,MAAM,0BAA0B,EAAE,WAAW,CAAC,EAAE,CAAC,UAAU,CAchE,CAAC;AAEH,oFAAoF;AACpF,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,EAAE,CAAC,UAAU,CAG/D,CAAC;AAEH,gHAAgH;AAChH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,EAAE,CAAC,YAAY,GACpB,IAAI,IAAI,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,cAAc,CAE9D;AAED,6GAA6G;AAC7G,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,cAAc,CAErG;AAQD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,GAAG,MAAM,CAEzE;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,GAAG,MAAM,CAE1E;AAED,eAAO,MAAM,iCAAiC,8BAA8B,CAAC;AAE7E,eAAO,MAAM,yBAAyB,sBAAsB,CAAC;AAE7D,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,GAAG,MAAM,CAEtE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,GAAG,MAAM,CAErE;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,MAAM,CAElE;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,wBAAwB,GAAG,eAAe,GAAG,SAAS,CAchG;AAQD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,eAAe,GAAG,SAAS,CAuH9E"}
1
+ {"version":3,"file":"subset.d.ts","sourceRoot":"","sources":["../../src/fold/subset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AAEH,mEAAmE;AACnE,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE/C,uGAAuG;AACvG,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,0FAA0F;AAC1F,eAAO,MAAM,0BAA0B,EAAE,WAAW,CAAC,EAAE,CAAC,UAAU,CAchE,CAAC;AAEH,oFAAoF;AACpF,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,EAAE,CAAC,UAAU,CAG/D,CAAC;AAEH,gHAAgH;AAChH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,EAAE,CAAC,YAAY,GACpB,IAAI,IAAI,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,cAAc,CAE9D;AAED,6GAA6G;AAC7G,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,cAAc,CAErG;AAQD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,GAAG,MAAM,CAEzE;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,GAAG,MAAM,CAE1E;AAED,eAAO,MAAM,iCAAiC,8BAA8B,CAAC;AAE7E,eAAO,MAAM,yBAAyB,sBAAsB,CAAC;AAE7D,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,GAAG,MAAM,CAEtE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,GAAG,MAAM,CAErE;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,MAAM,CAElE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,EAAE,CAAC,wBAAwB,EACjC,UAAU,CAAC,EAAE,SAAS,YAAY,EAAE,GACnC,eAAe,GAAG,SAAS,CAc7B;AAWD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,UAAU,CAAC,EAAE,SAAS,YAAY,EAAE,GACnC,eAAe,GAAG,SAAS,CAiK7B"}
@@ -8,6 +8,7 @@ export declare const IntrinsicDefSchema: z.ZodObject<{
8
8
  description: z.ZodOptional<z.ZodString>;
9
9
  outputKey: z.ZodOptional<z.ZodString>;
10
10
  isTag: z.ZodBoolean;
11
+ foldsAsCall: z.ZodOptional<z.ZodBoolean>;
11
12
  }, z.core.$strip>;
12
13
  export declare const LexiconManifestSchema: z.ZodObject<{
13
14
  name: z.ZodString;
@@ -19,6 +20,7 @@ export declare const LexiconManifestSchema: z.ZodObject<{
19
20
  description: z.ZodOptional<z.ZodString>;
20
21
  outputKey: z.ZodOptional<z.ZodString>;
21
22
  isTag: z.ZodBoolean;
23
+ foldsAsCall: z.ZodOptional<z.ZodBoolean>;
22
24
  }, z.core.$strip>>>;
23
25
  pseudoParameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
24
26
  }, z.core.$strip>;
@@ -1 +1 @@
1
- {"version":3,"file":"lexicon-schema.d.ts","sourceRoot":"","sources":["../src/lexicon-schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAM/D,eAAO,MAAM,kBAAkB;;;;;iBAO7B,CAAC;AAQH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;iBAOhC,CAAC;AAiCH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmB7B,CAAC;AAMH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAMpE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,eAAe,CA2B/D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAmBjF"}
1
+ {"version":3,"file":"lexicon-schema.d.ts","sourceRoot":"","sources":["../src/lexicon-schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAM/D,eAAO,MAAM,kBAAkB;;;;;;iBAY7B,CAAC;AAQH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;iBAOhC,CAAC;AAiCH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmB7B,CAAC;AAMH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAMpE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,eAAe,CA2B/D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAmBjF"}