@intentius/chant 0.124.14 → 0.124.15

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 (110) hide show
  1. package/dist/build.d.ts +6 -0
  2. package/dist/build.d.ts.map +1 -1
  3. package/dist/build.js +1 -0
  4. package/dist/change-set.d.ts +24 -2
  5. package/dist/change-set.d.ts.map +1 -1
  6. package/dist/change-set.js +50 -1
  7. package/dist/ci-jobs.d.ts +227 -0
  8. package/dist/ci-jobs.d.ts.map +1 -0
  9. package/dist/ci-jobs.js +448 -0
  10. package/dist/components/pr-pipeline.d.ts.map +1 -1
  11. package/dist/components/pr-pipeline.js +3 -2
  12. package/dist/composite.d.ts +10 -2
  13. package/dist/composite.d.ts.map +1 -1
  14. package/dist/composite.js +8 -0
  15. package/dist/discovery/collect.d.ts +2 -1
  16. package/dist/discovery/collect.d.ts.map +1 -1
  17. package/dist/discovery/collect.js +16 -1
  18. package/dist/discovery/fold-import.d.ts.map +1 -1
  19. package/dist/discovery/fold-import.js +2 -107
  20. package/dist/discovery/host-composite.d.ts +35 -0
  21. package/dist/discovery/host-composite.d.ts.map +1 -0
  22. package/dist/discovery/host-composite.js +93 -0
  23. package/dist/discovery/index.d.ts +9 -0
  24. package/dist/discovery/index.d.ts.map +1 -1
  25. package/dist/discovery/index.js +1 -1
  26. package/dist/gate-decision.d.ts +20 -9
  27. package/dist/gate-decision.d.ts.map +1 -1
  28. package/dist/gate-decision.js +72 -19
  29. package/dist/lifecycle/gate-audit.d.ts +69 -2
  30. package/dist/lifecycle/gate-audit.d.ts.map +1 -1
  31. package/dist/lifecycle/gate-audit.js +76 -2
  32. package/dist/lifecycle/gate-ledger.d.ts +24 -0
  33. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  34. package/dist/lifecycle/gate-ledger.js +9 -1
  35. package/dist/op/activities/activity-contracts.d.ts +1 -1
  36. package/dist/op/activities/activity-contracts.js +1 -1
  37. package/dist/op/activities/change-set.d.ts +8 -3
  38. package/dist/op/activities/change-set.d.ts.map +1 -1
  39. package/dist/op/activities/change-set.js +5 -2
  40. package/dist/op/activities/reconcile.d.ts +28 -16
  41. package/dist/op/activities/reconcile.d.ts.map +1 -1
  42. package/dist/op/activities/reconcile.js +34 -20
  43. package/dist/op/builders.d.ts +1 -1
  44. package/dist/op/builders.d.ts.map +1 -1
  45. package/dist/op/builders.js +1 -1
  46. package/dist/op/op-waves-run.d.ts +1 -1
  47. package/dist/op/op-waves-run.d.ts.map +1 -1
  48. package/dist/op/op-waves-run.js +3 -3
  49. package/dist/workspace/__fixtures__/contract-repo.d.ts +7 -0
  50. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
  51. package/dist/workspace/__fixtures__/contract-repo.js +17 -1
  52. package/dist/workspace/__fixtures__/sessions.d.ts +1 -1
  53. package/dist/workspace/__fixtures__/sessions.d.ts.map +1 -1
  54. package/dist/workspace/__fixtures__/sessions.js +3 -3
  55. package/dist/workspace/change-set.schema.json +5 -3
  56. package/dist/workspace/ci-green-workflow.d.ts +3 -1
  57. package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
  58. package/dist/workspace/ci-green-workflow.js +5 -2
  59. package/dist/workspace/class-data.d.ts +84 -0
  60. package/dist/workspace/class-data.d.ts.map +1 -0
  61. package/dist/workspace/class-data.js +238 -0
  62. package/dist/workspace/kinds.d.ts +3 -7
  63. package/dist/workspace/kinds.d.ts.map +1 -1
  64. package/dist/workspace/kinds.js +6 -40
  65. package/dist/workspace/principal-classes.d.ts +4 -11
  66. package/dist/workspace/principal-classes.d.ts.map +1 -1
  67. package/dist/workspace/principal-classes.js +11 -94
  68. package/package.json +1 -1
  69. package/src/build.ts +8 -0
  70. package/src/change-set.test.ts +48 -0
  71. package/src/change-set.ts +52 -2
  72. package/src/ci-jobs.test.ts +49 -0
  73. package/src/ci-jobs.ts +515 -0
  74. package/src/components/pr-pipeline.ts +3 -2
  75. package/src/composite.ts +15 -3
  76. package/src/discovery/collect.ts +15 -1
  77. package/src/discovery/fold-build-parity.test.ts +71 -0
  78. package/src/discovery/fold-import.ts +2 -113
  79. package/src/discovery/fold-project-provenance.test.ts +21 -4
  80. package/src/discovery/host-composite.ts +101 -0
  81. package/src/discovery/index.ts +11 -1
  82. package/src/gate-decision-bundle.test.ts +5 -4
  83. package/src/gate-decision-identity.test.ts +59 -6
  84. package/src/gate-decision.ts +81 -21
  85. package/src/lifecycle/gate-audit.test.ts +55 -1
  86. package/src/lifecycle/gate-audit.ts +116 -3
  87. package/src/lifecycle/gate-ledger.test.ts +20 -1
  88. package/src/lifecycle/gate-ledger.ts +33 -1
  89. package/src/op/activities/activity-contracts.ts +1 -1
  90. package/src/op/activities/change-set.ts +11 -3
  91. package/src/op/activities/lexicon-upgrade.test.ts +2 -0
  92. package/src/op/activities/reconcile.test.ts +62 -2
  93. package/src/op/activities/reconcile.ts +46 -22
  94. package/src/op/builders.ts +1 -1
  95. package/src/op/op-waves-run.ts +4 -3
  96. package/src/op/op-waves.test.ts +2 -0
  97. package/src/op/work-lease-run.test.ts +12 -4
  98. package/src/workspace/__fixtures__/contract-repo.ts +17 -1
  99. package/src/workspace/__fixtures__/sessions.ts +3 -3
  100. package/src/workspace/change-set.schema.json +5 -3
  101. package/src/workspace/ci-green-workflow.test.ts +4 -4
  102. package/src/workspace/ci-green-workflow.ts +5 -2
  103. package/src/workspace/class-data.test.ts +64 -0
  104. package/src/workspace/class-data.ts +236 -0
  105. package/src/workspace/kinds.ts +6 -35
  106. package/src/workspace/principal-classes.ts +11 -94
  107. package/src/workspace/records-formats.test.ts +7 -2
  108. package/src/workspace/records-sessions-write.test.ts +3 -3
  109. package/src/workspace/status-contract.e2e.test.ts +37 -0
  110. package/src/workspace/status-contract.test.ts +23 -21
@@ -1 +1 @@
1
- {"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../../src/workspace/kinds.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../../src/workspace/kinds.ts"],"names":[],"mappings":"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"}
@@ -16,12 +16,13 @@
16
16
  * kinds claim one directory, the highest precedence decides, and a tie
17
17
  * fails ({@link resolveKind}).
18
18
  */
19
- import { existsSync, readFileSync, statSync } from "node:fs";
19
+ import { readFileSync } from "node:fs";
20
20
  import { createRequire } from "node:module";
21
- import { dirname, isAbsolute, join, relative, resolve } from "node:path";
21
+ import { isAbsolute, join, relative, resolve } from "node:path";
22
22
  import schema from "./workspace-kinds.schema.json" with { type: "json" };
23
23
  import { joinPath, skippedDir } from "./tree.js";
24
24
  import { checkPinIntegrity } from "./pin-integrity.js";
25
+ import { dataExportTarget, findInstalledPackage } from "./class-data.js";
25
26
  export const KINDS_SCHEMA_ID = schema.$id;
26
27
  /** The subpath a package publishes its kinds at. */
27
28
  export const KINDS_SUBPATH = "./workspace-kinds";
@@ -289,24 +290,7 @@ export function parseKindData(text, source) {
289
290
  * subpath to code, which chant never runs for plugin data.
290
291
  */
291
292
  export function kindsExportTarget(pkg, subpath = KINDS_SUBPATH) {
292
- const exports = pkg.exports;
293
- if (!exports || typeof exports !== "object" || Array.isArray(exports))
294
- return undefined;
295
- const entry = exports[subpath];
296
- if (entry === undefined)
297
- return undefined;
298
- let target = entry;
299
- if (target && typeof target === "object" && !Array.isArray(target)) {
300
- const conditions = target;
301
- target = conditions.default ?? conditions.import ?? conditions.require;
302
- }
303
- if (typeof target !== "string") {
304
- return { problem: `exports["${subpath}"] must name one file, as a string or a "default" condition` };
305
- }
306
- if (!target.startsWith("./") || !target.endsWith(".json")) {
307
- return { problem: `exports["${subpath}"] is ${target}; it must name a .json file inside the package, since chant reads plugin data as data and never runs a package's code` };
308
- }
309
- return target;
293
+ return dataExportTarget(pkg, subpath);
310
294
  }
311
295
  /** Read the kinds a package directory publishes. Reads files only; imports nothing. */
312
296
  export function readPackageKinds(packageDir, source) {
@@ -369,26 +353,8 @@ export function substituteGraphConfig(config, at) {
369
353
  };
370
354
  return walk(config);
371
355
  }
372
- /**
373
- * The directory of an installed package `name`, found the way Node finds a
374
- * bare import: `node_modules/<name>` in `fromDir` and each directory above it.
375
- * It looks for the directory, not for an entry point, so it works for a
376
- * package whose `exports` don't expose `package.json`.
377
- */
378
- export function findInstalledPackage(name, fromDir) {
379
- for (let dir = resolve(fromDir);; dir = dirname(dir)) {
380
- const candidate = join(dir, "node_modules", ...name.split("/"));
381
- try {
382
- if (statSync(candidate).isDirectory() && existsSync(join(candidate, "package.json")))
383
- return candidate;
384
- }
385
- catch {
386
- // Not here; keep walking.
387
- }
388
- if (dirname(dir) === dir)
389
- return undefined;
390
- }
391
- }
356
+ /** Where an installed package is, as Node finds a bare import (`./class-data.ts`, so the gate-decision bundle shares it). */
357
+ export { findInstalledPackage };
392
358
  /**
393
359
  * The directory a pin's plugin data is read from: an installed package at
394
360
  * the pinned version, looked up from `workspaceRoot`, or a path pin's
@@ -21,13 +21,13 @@
21
21
  * editing its own copy of the plugin. A package pin is read from the
22
22
  * installed package, which must be at the version the base pins.
23
23
  */
24
+ import { type ClassData, type PackageFiles } from "./class-data.js";
24
25
  import { type KindLoadProblem, type PinLike } from "./kinds.js";
25
26
  import type { TrustPolicy } from "./trust/policy.js";
26
27
  import { type WorkspaceTree } from "./tree.js";
27
28
  import { type PrincipalClass } from "./identity-gate-rule.js";
28
29
  export declare const PRINCIPALS_SCHEMA_ID: string;
29
- /** The subpath a package publishes its principal classes at. */
30
- export declare const PRINCIPALS_SUBPATH = "./workspace-principals";
30
+ export { PRINCIPALS_SUBPATH } from "./class-data.js";
31
31
  export { CORE_CLASSES, CORE_PRINCIPAL_CLASSES, type CorePrincipalClass, type PrincipalClass } from "./identity-gate-rule.js";
32
32
  /** A class name: a core class, or a domain class a pinned package supplies. */
33
33
  export type PrincipalClassName = string;
@@ -57,11 +57,8 @@ export declare function roleGrants(policy: TrustPolicy): Record<string, string[]
57
57
  export declare function classesOf(classes: ClassRegistry, policy: TrustPolicy, principal: string | null): string[];
58
58
  /** The class write scope judges `principal` as: the first class its grants put it in, or `human`. */
59
59
  export declare function principalClass(policy: TrustPolicy, principal: string | null, classes?: ClassRegistry): string;
60
- export interface ClassData {
61
- classes: PrincipalClass[];
62
- /** Why some of the data can't be used, one line each. Empty when all of it can. */
63
- problems: string[];
64
- }
60
+ export type { ClassData, PackageFiles } from "./class-data.js";
61
+ export { diskFiles } from "./class-data.js";
65
62
  /**
66
63
  * Check the text of a principals file against
67
64
  * `workspace-principals.schema.json` and the rules the schema can't say: no
@@ -69,10 +66,6 @@ export interface ClassData {
69
66
  * in the classes and in the messages.
70
67
  */
71
68
  export declare function parseClassData(text: string, source: string): ClassData;
72
- /** A package's files, by a `/`-separated path inside it, or undefined when one is not there. */
73
- export type PackageFiles = (path: string) => string | undefined;
74
- /** A package directory on disk. */
75
- export declare function diskFiles(dir: string): PackageFiles;
76
69
  /** A package directory at `dir` in `tree`, such as the workspace at the base revision. */
77
70
  export declare function treeFiles(tree: WorkspaceTree, dir: string): PackageFiles;
78
71
  /** Read the classes a package publishes at `./workspace-principals`. Reads files only; imports nothing. A package that publishes none supplies none. */
@@ -1 +1 @@
1
- {"version":3,"file":"principal-classes.d.ts","sourceRoot":"","sources":["../../src/workspace/principal-classes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"principal-classes.d.ts","sourceRoot":"","sources":["../../src/workspace/principal-classes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAA8D,KAAK,SAAS,EAAE,KAAK,YAAY,EAAqB,MAAM,cAAc,CAAC;AAChJ,OAAO,EAAoB,KAAK,eAAe,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAE/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAwD,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEjH,eAAO,MAAM,oBAAoB,QAAa,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,KAAK,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1H,+EAA+E;AAC/E,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAExC,uHAAuH;AACvH,eAAO,MAAM,UAAU,QAAiC,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAC9C,kEAAkE;IAClE,KAAK,IAAI,MAAM,EAAE,CAAC;IAClB,oFAAoF;IACpF,GAAG,IAAI,SAAS,cAAc,EAAE,CAAC;CAClC;AAED,wBAAgB,mBAAmB,CAAC,KAAK,GAAE,SAAS,cAAc,EAAO,GAAG,aAAa,CAQxF;AAED,+FAA+F;AAC/F,wBAAgB,iBAAiB,IAAI,aAAa,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAExE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAEzG;AAED,qGAAqG;AACrG,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,GAAE,aAAmC,GAAG,MAAM,CAElI;AAqBD,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAatE;AAED,0FAA0F;AAC1F,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CAUxE;AAED,wJAAwJ;AACxJ,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAEjF;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,aAAa,CAAA;CAAO,GAAG,aAAa,CAuBrI;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,EAAE,CAEhH"}
@@ -21,20 +21,17 @@
21
21
  * editing its own copy of the plugin. A package pin is read from the
22
22
  * installed package, which must be at the version the base pins.
23
23
  */
24
- import { readFileSync } from "node:fs";
25
24
  import { createRequire } from "node:module";
26
- import { join, posix } from "node:path";
27
- import { kindsExportTarget, pinnedPackageDir } from "./kinds.js";
25
+ import { checkClassData, diskFiles, mergePinClasses, readClassFiles } from "./class-data.js";
26
+ import { pinnedPackageDir } from "./kinds.js";
28
27
  import schema from "./workspace-principals.schema.json" with { type: "json" };
29
28
  import { joinPath } from "./tree.js";
30
- import { CORE_CLASSES, CORE_PRINCIPAL_CLASSES, grantedClasses } from "./identity-gate-rule.js";
29
+ import { CORE_CLASSES, grantedClasses } from "./identity-gate-rule.js";
31
30
  export const PRINCIPALS_SCHEMA_ID = schema.$id;
32
- /** The subpath a package publishes its principal classes at. */
33
- export const PRINCIPALS_SUBPATH = "./workspace-principals";
31
+ export { PRINCIPALS_SUBPATH } from "./class-data.js";
34
32
  export { CORE_CLASSES, CORE_PRINCIPAL_CLASSES } from "./identity-gate-rule.js";
35
33
  /** The grammar of a class name, as `workspace-principals.schema.json` and the declaration's writeScope keys say it. */
36
34
  export const CLASS_NAME = /^(?!x-)[a-z][a-z0-9-]{0,39}$/;
37
- const CORE_ROLES = new Set(CORE_CLASSES.map((c) => c.role).filter((r) => r !== null));
38
35
  export function createClassRegistry(extra = []) {
39
36
  const all = [...CORE_CLASSES, ...extra];
40
37
  const byName = new Map(all.map((c) => [c.name, c]));
@@ -79,6 +76,7 @@ function validator() {
79
76
  compiled = new Ajv({ allErrors: true, strict: true }).compile(schema);
80
77
  return compiled;
81
78
  }
79
+ export { diskFiles } from "./class-data.js";
82
80
  /**
83
81
  * Check the text of a principals file against
84
82
  * `workspace-principals.schema.json` and the rules the schema can't say: no
@@ -98,43 +96,7 @@ export function parseClassData(text, source) {
98
96
  const problems = (validate.errors ?? []).map((e) => `${source}: ${e.instancePath || "the principals file"} ${e.message ?? "is invalid"}`);
99
97
  return { classes: [], problems: [...new Set(problems)] };
100
98
  }
101
- const problems = [];
102
- const classes = [];
103
- const names = new Set();
104
- const roles = new Set();
105
- for (const c of raw.classes) {
106
- if (CORE_PRINCIPAL_CLASSES.includes(c.name)) {
107
- problems.push(`${source}: class ${c.name} is a core class and can't be supplied by a package`);
108
- continue;
109
- }
110
- if (CORE_ROLES.has(c.role)) {
111
- problems.push(`${source}: class ${c.name} names the role ${c.role}, which puts a principal in the core ${c.role} class`);
112
- continue;
113
- }
114
- if (names.has(c.name)) {
115
- problems.push(`${source}: class ${c.name} is listed twice`);
116
- continue;
117
- }
118
- if (roles.has(c.role)) {
119
- problems.push(`${source}: class ${c.name} names the role ${c.role}, which another class in the file names; a role puts a principal in one class`);
120
- continue;
121
- }
122
- names.add(c.name);
123
- roles.add(c.role);
124
- classes.push({ name: c.name, description: c.description, role: c.role, source });
125
- }
126
- return { classes, problems };
127
- }
128
- /** A package directory on disk. */
129
- export function diskFiles(dir) {
130
- return (path) => {
131
- try {
132
- return readFileSync(join(dir, ...path.split("/")), "utf-8");
133
- }
134
- catch {
135
- return undefined;
136
- }
137
- };
99
+ return checkClassData(raw, source);
138
100
  }
139
101
  /** A package directory at `dir` in `tree`, such as the workspace at the base revision. */
140
102
  export function treeFiles(tree, dir) {
@@ -152,28 +114,7 @@ export function treeFiles(tree, dir) {
152
114
  }
153
115
  /** Read the classes a package publishes at `./workspace-principals`. Reads files only; imports nothing. A package that publishes none supplies none. */
154
116
  export function readPackageClasses(files, source) {
155
- const manifest = files("package.json");
156
- if (manifest === undefined)
157
- return { classes: [], problems: [`${source}: no readable package.json`] };
158
- let pkg;
159
- try {
160
- pkg = JSON.parse(manifest);
161
- }
162
- catch {
163
- return { classes: [], problems: [`${source}: package.json is not JSON`] };
164
- }
165
- const target = kindsExportTarget(pkg, PRINCIPALS_SUBPATH);
166
- if (target === undefined)
167
- return { classes: [], problems: [] };
168
- if (typeof target !== "string")
169
- return { classes: [], problems: [`${source}: ${target.problem}`] };
170
- const inside = posix.normalize(target.slice(2));
171
- if (inside.startsWith("../") || inside === "..")
172
- return { classes: [], problems: [`${source}: exports["${PRINCIPALS_SUBPATH}"] points outside the package`] };
173
- const text = files(inside);
174
- if (text === undefined)
175
- return { classes: [], problems: [`${source}: exports["${PRINCIPALS_SUBPATH}"] names ${target}, which does not exist`] };
176
- return parseClassData(text, source);
117
+ return readClassFiles(files, source, parseClassData);
177
118
  }
178
119
  /**
179
120
  * The classes a workspace knows: the core four plus every class its pins
@@ -187,10 +128,7 @@ export function readPackageClasses(files, source) {
187
128
  */
188
129
  export function loadClassRegistry(pins, workspaceRoot, opts = {}) {
189
130
  const problems = [];
190
- const extra = [];
191
- const byName = new Map();
192
- const byRole = new Map();
193
- const clashing = new Set();
131
+ const reads = [];
194
132
  pins.forEach((pin, i) => {
195
133
  let files;
196
134
  let source;
@@ -209,31 +147,10 @@ export function loadClassRegistry(pins, workspaceRoot, opts = {}) {
209
147
  files = diskFiles(found.dir);
210
148
  source = found.source;
211
149
  }
212
- const read = readPackageClasses(files, source);
213
- for (const p of read.problems)
214
- problems.push({ pin: i, message: p });
215
- for (const c of read.classes) {
216
- const named = byName.get(c.name);
217
- const roled = byRole.get(c.role);
218
- if (named !== undefined || roled !== undefined) {
219
- clashing.add(c.name);
220
- if (named !== undefined) {
221
- problems.push({ pin: i, message: `class ${c.name} is supplied by both ${named} and ${source}; a class name has one source` });
222
- }
223
- else {
224
- const other = extra.find((e) => e.role === c.role);
225
- clashing.add(other.name);
226
- problems.push({ pin: i, message: `class ${c.name} (${source}) names the role ${c.role}, which class ${other.name} (${roled}) names; a role puts a principal in one class` });
227
- }
228
- continue;
229
- }
230
- byName.set(c.name, source);
231
- byRole.set(c.role, source);
232
- extra.push(c);
233
- }
150
+ reads.push({ pin: i, source, read: readPackageClasses(files, source) });
234
151
  });
235
- // A name or role two pins both supply is left out altogether: neither reading is safe.
236
- return { registry: createClassRegistry(extra.filter((c) => !clashing.has(c.name))), problems };
152
+ const merged = mergePinClasses(reads);
153
+ return { registry: createClassRegistry(merged.classes), problems: [...problems, ...merged.problems].sort((a, b) => a.pin - b.pin) };
237
154
  }
238
155
  /**
239
156
  * The writeScope keys no class in `classes` has, in file order. A writer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant",
3
- "version": "0.124.14",
3
+ "version": "0.124.15",
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",
package/src/build.ts CHANGED
@@ -232,6 +232,13 @@ export interface BuildOptions {
232
232
  */
233
233
  lexicons?: readonly string[];
234
234
 
235
+ /**
236
+ * chant#3612 — host package specifiers to follow a bare import into. Passed
237
+ * straight through to {@link DiscoveryOptions.lexiconPackages}; ignored
238
+ * unless {@link fold} is set. Never needed for a chant project.
239
+ */
240
+ lexiconPackages?: readonly string[];
241
+
235
242
  /**
236
243
  * chant #1442 — lexicon name → the version of the plugin that served it.
237
244
  * Recorded on {@link BuildResult.lexiconVersions} so a build digest can say
@@ -723,6 +730,7 @@ export async function build(
723
730
  fold: options?.fold,
724
731
  intrinsics: options?.intrinsics,
725
732
  lexicons: options?.lexicons,
733
+ lexiconPackages: options?.lexiconPackages,
726
734
  sandbox: options?.sandbox,
727
735
  executing: options?.executing,
728
736
  buildParams: options?.buildParams,
@@ -23,11 +23,13 @@ import { readdirSync, readFileSync, writeFileSync } from "node:fs";
23
23
  import { join } from "node:path";
24
24
  import { describe, expect, test } from "vitest";
25
25
  import {
26
+ CHANGE_SET_PLANNERS,
26
27
  CHANGE_SET_SCHEMA_ID,
27
28
  changeSetDigest,
28
29
  changeSetDocumentDigest,
29
30
  composeChangeSet,
30
31
  lifecyclePlanPart,
32
+ readChangeSetPartFile,
31
33
  reconcilePlanPart,
32
34
  verifyChangeSetDigest,
33
35
  type ChangeSetPart,
@@ -243,3 +245,49 @@ describe("the digest", () => {
243
245
  expect(doc.summary.replacements.map((d) => `${d.member}:${d.address}`)).toEqual(["estate:terraform_data.worker"]);
244
246
  });
245
247
  });
248
+
249
+ describe("readChangeSetPartFile (#3767)", () => {
250
+ /** A part as the sql lexicon's adapter writes it; `lexicons/sql/src/change-set.test.ts` pins the adapter itself. */
251
+ const sqlPart = (): ChangeSetPart => ({
252
+ member: { member: "written-as", lexicon: "sql", planner: "sql", scope: "prod", status: "planned", planDigest: computePlanDigest("sql-versioned-plan", { id: "0002" }), holes: [] },
253
+ entries: [
254
+ { member: "written-as", lexicon: "sql", planner: "sql", address: "analytics.events", type: "ClickHouse::Table", action: "update", disruption: "rolling", scope: "prod", attributes: [{ path: "sql", after: ["ALTER TABLE analytics.events ADD COLUMN region String"] }] },
255
+ ],
256
+ });
257
+
258
+ test("the schema lists every planner, sql included", () => {
259
+ const planners = (schema as { $defs: { member: { properties: { planner: { enum: string[] } } }; entry: { properties: { planner: { enum: string[] } } } } }).$defs;
260
+ expect(planners.member.properties.planner.enum).toEqual([...CHANGE_SET_PLANNERS]);
261
+ expect(planners.entry.properties.planner.enum).toEqual([...CHANGE_SET_PLANNERS]);
262
+ });
263
+
264
+ test("reads a written part back as the run's member, through JSON, and composes it", () => {
265
+ const part = readChangeSetPartFile(JSON.parse(JSON.stringify(sqlPart())), "sql", "warehouse");
266
+ expect(part.member.member).toBe("warehouse");
267
+ expect(part.entries.map((e) => e.member)).toEqual(["warehouse"]);
268
+ expect(part.member.planDigest).toBe(sqlPart().member.planDigest);
269
+ expect(readChangeSetPartFile(sqlPart(), "sql", "warehouse", "clickhouse").entries[0].lexicon).toBe("clickhouse");
270
+ const doc = composeChangeSet([part, reconcilePlanPart({ member: "warden", plan: wardenPlan() })]);
271
+ expectValid(doc);
272
+ expect(doc.summary.byMember.warehouse).toEqual({ update: 1 });
273
+ // The name the run gives it is what the set digest pairs with the writer's plan digest.
274
+ expect(composeChangeSet([readChangeSetPartFile(sqlPart(), "sql", "other")]).digest).not.toBe(composeChangeSet([part]).digest);
275
+ });
276
+
277
+ test("refuses what is not a part of that planner", () => {
278
+ const p = sqlPart();
279
+ expect(() => readChangeSetPartFile([], "sql", "w")).toThrow(/not a change-set part/);
280
+ expect(() => readChangeSetPartFile({ ...p, member: { ...p.member, planner: "chant" } }, "sql", "w")).toThrow(/names planner chant, not sql/);
281
+ expect(() => readChangeSetPartFile({ ...p, member: { ...p.member, planDigest: null } }, "sql", "w")).toThrow(/planned but has no planDigest/);
282
+ expect(() => readChangeSetPartFile({ ...p, member: { ...p.member, holes: undefined } }, "sql", "w")).toThrow(/no holes array/);
283
+ expect(() => readChangeSetPartFile({ ...p, entries: [{ ...p.entries[0], planner: "terraform" }] }, "sql", "w")).toThrow(/entries\[0\] names planner terraform/);
284
+ expect(() => readChangeSetPartFile({ ...p, entries: [{ ...p.entries[0], action: "upsert" }] }, "sql", "w")).toThrow(/entries\[0\] has action upsert/);
285
+ expect(() => readChangeSetPartFile({ ...p, entries: [{ address: "x" }] }, "sql", "w")).toThrow(/entries\[0\] needs address/);
286
+ });
287
+
288
+ test("a failed member keeps a null digest", () => {
289
+ const p = sqlPart();
290
+ const failed = readChangeSetPartFile({ ...p, member: { ...p.member, status: "failed", error: "out of order", planDigest: null } }, "sql", "w");
291
+ expect(failed.member).toMatchObject({ status: "failed", error: "out of order", planDigest: null });
292
+ });
293
+ });
package/src/change-set.ts CHANGED
@@ -11,7 +11,9 @@
11
11
  * Each planner reaches it through an adapter that returns a
12
12
  * {@link ChangeSetPart}: one member and its entries. The lifecycle and
13
13
  * reconcile adapters are here; the terraform-family ones live in the
14
- * terraform lexicon's `change-set` subpath. {@link composeChangeSet} joins
14
+ * terraform lexicon's `change-set` subpath and the SQL ones in the sql
15
+ * lexicon's. A part another process wrote to a file reads back through
16
+ * {@link readChangeSetPartFile}. {@link composeChangeSet} joins
15
17
  * the parts.
16
18
  *
17
19
  * ## The digest
@@ -60,7 +62,15 @@ export const CHANGE_SET_ACTIONS: readonly ChangeSetAction[] = ["create", "update
60
62
  export type ChangeSetDisruption = "in-place" | "rolling" | "replace" | "destroy" | "unknown";
61
63
 
62
64
  /** Which tool produced a member's plan. */
63
- export type ChangeSetPlanner = "terraform" | "tofu" | "choudoufu" | "chant" | "warden";
65
+ /**
66
+ * Which tool produced a member's plan. `sql` is a SQL schema change: a
67
+ * versioned plan (a product's migrations) or one of the sql lexicon's
68
+ * migration Ops' plans, through `@intentius/chant-lexicon-sql/change-set`.
69
+ */
70
+ export type ChangeSetPlanner = "terraform" | "tofu" | "choudoufu" | "chant" | "warden" | "sql";
71
+
72
+ /** Every planner, in the order the schema lists them. */
73
+ export const CHANGE_SET_PLANNERS: readonly ChangeSetPlanner[] = ["terraform", "tofu", "choudoufu", "chant", "warden", "sql"];
64
74
 
65
75
  /** One attribute a change writes, at top-level granularity. */
66
76
  export interface ChangeSetAttribute {
@@ -482,3 +492,43 @@ export function reconcilePlanPart(input: ReconcilePlanPartInput): ChangeSetPart
482
492
  entries,
483
493
  };
484
494
  }
495
+
496
+ // ── a part written to a file ───────────────────────────────────────────────────
497
+
498
+ const isRecord = (v: unknown): v is Record<string, unknown> => typeof v === "object" && v !== null && !Array.isArray(v);
499
+
500
+ /**
501
+ * A part an adapter in another process wrote as JSON, read back as `member`'s
502
+ * part. The `sql` planner's plans arrive this way: the sql lexicon's
503
+ * `change-set` adapters, or a product that fills them, write the part, and
504
+ * `readChangeSetPart` with `planner: "sql"` reads it.
505
+ *
506
+ * The part must name `planner` on its member and on every entry, and say
507
+ * `status`, `planDigest` and `holes`. Its member and entries are renamed to
508
+ * `member`, so the file need not know the name the run gives it; a `lexicon`
509
+ * given here replaces the part's. Nothing is recomputed: the plan digest is
510
+ * the one the writer took, over a plan this process never sees.
511
+ */
512
+ export function readChangeSetPartFile(part: unknown, planner: ChangeSetPlanner, member: string, lexicon?: string): ChangeSetPart {
513
+ const where = `the ${planner} part for ${member}`;
514
+ if (!isRecord(part) || !isRecord(part.member) || !Array.isArray(part.entries)) throw new Error(`${where} is not a change-set part: it needs member and entries`);
515
+ const m = part.member;
516
+ if (m.planner !== planner) throw new Error(`${where} names planner ${String(m.planner)}, not ${planner}`);
517
+ if (m.status !== "planned" && m.status !== "failed") throw new Error(`${where} has no status`);
518
+ if (m.planDigest !== null && typeof m.planDigest !== "string") throw new Error(`${where} has no planDigest`);
519
+ if (m.status === "planned" && m.planDigest === null) throw new Error(`${where} planned but has no planDigest`);
520
+ if (!Array.isArray(m.holes)) throw new Error(`${where} has no holes array`);
521
+ const entries = part.entries.map((e, i) => {
522
+ if (!isRecord(e) || typeof e.address !== "string" || typeof e.type !== "string" || typeof e.action !== "string" || !Array.isArray(e.attributes)) {
523
+ throw new Error(`${where}: entries[${i}] needs address, type, action and attributes`);
524
+ }
525
+ if (!(CHANGE_SET_ACTIONS as readonly string[]).includes(e.action)) throw new Error(`${where}: entries[${i}] has action ${e.action}`);
526
+ if (e.planner !== planner) throw new Error(`${where}: entries[${i}] names planner ${String(e.planner)}, not ${planner}`);
527
+ return { ...(e as unknown as ChangeSetEntry), member, ...(lexicon !== undefined ? { lexicon } : {}) };
528
+ });
529
+ return {
530
+ member: { ...(m as unknown as ChangeSetMember), member, ...(lexicon !== undefined ? { lexicon } : {}) },
531
+ entries,
532
+ ...(Array.isArray(part.sideEffects) ? { sideEffects: part.sideEffects as ChangeSetPart["sideEffects"] } : {}),
533
+ };
534
+ }
@@ -0,0 +1,49 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import {
3
+ assertGitlabBranch,
4
+ CI_IMAGE,
5
+ gitlabRules,
6
+ githubSecret,
7
+ githubSecretEnv,
8
+ githubSecretOrJobToken,
9
+ pushBranches,
10
+ triggerBranches,
11
+ } from "./ci-jobs";
12
+ import { PR_LOOP_IMAGE } from "./components/pr-pipeline";
13
+
14
+ describe("the job primitives the CI generators share (#3765)", () => {
15
+ test("one default image, which the pull-request pipeline uses too", () => {
16
+ expect(CI_IMAGE).toBe("node:22");
17
+ expect(PR_LOOP_IMAGE).toBe(CI_IMAGE);
18
+ });
19
+
20
+ test("a push trigger with no branches, or an empty list, filters on main; a pull_request trigger then takes every branch", () => {
21
+ expect(pushBranches(undefined)).toEqual(["main"]);
22
+ expect(pushBranches([])).toEqual(["main"]);
23
+ expect(pushBranches(["trunk"])).toEqual(["trunk"]);
24
+ expect(triggerBranches({ kind: "push", branches: [] })).toEqual(["main"]);
25
+ expect(triggerBranches({ kind: "pull_request", branches: [] })).toBeUndefined();
26
+ expect(triggerBranches({ kind: "pull_request", branches: ["main"] })).toEqual(["main"]);
27
+ expect(triggerBranches({ kind: "cron", schedule: "0 * * * *" })).toBeUndefined();
28
+ });
29
+
30
+ test("a secret, and a secret that falls back to the job token when unset (#3624)", () => {
31
+ expect(githubSecret("T")).toBe("${{ secrets.T }}");
32
+ expect(githubSecretOrJobToken("T")).toBe("${{ secrets.T || github.token }}");
33
+ expect(githubSecretEnv(["A", "B"])).toEqual({ A: "${{ secrets.A }}", B: "${{ secrets.B }}" });
34
+ });
35
+
36
+ test("GitLab rules: one entry per branch, and a branch that would break the expression is refused", () => {
37
+ const selector = { variable: "CHANT_SCHEDULED_OP", value: "watch" };
38
+ expect(gitlabRules("Scheduled Op \"apply\"", { kind: "push", branches: ["main", "prod"] }, selector)).toEqual([
39
+ { if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"' },
40
+ { if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "prod"' },
41
+ ]);
42
+ expect(gitlabRules("x", { kind: "pull_request", branches: [] }, selector)).toEqual([{ if: '$CI_PIPELINE_SOURCE == "merge_request_event"' }]);
43
+ expect(gitlabRules("x", { kind: "cron", schedule: "0 * * * *" }, selector)).toEqual([
44
+ { if: '$CI_PIPELINE_SOURCE == "schedule" && $CHANT_SCHEDULED_OP == "watch"' },
45
+ ]);
46
+ expect(() => assertGitlabBranch("Op waves \"w\"", "a$b")).toThrow(/Op waves "w" filters on branch "a\$b"/);
47
+ expect(() => assertGitlabBranch("Op waves \"w\"", " ")).toThrow(/empty branch filter/);
48
+ });
49
+ });