@rasensio/aidlc 1.16.0 → 1.18.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 (235) hide show
  1. package/README.md +9 -1
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +4 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/compliance.d.ts +36 -0
  6. package/dist/commands/compliance.d.ts.map +1 -0
  7. package/dist/commands/compliance.js +275 -0
  8. package/dist/commands/compliance.js.map +1 -0
  9. package/dist/commands/constitution.d.ts +26 -0
  10. package/dist/commands/constitution.d.ts.map +1 -0
  11. package/dist/commands/constitution.js +145 -0
  12. package/dist/commands/constitution.js.map +1 -0
  13. package/dist/commands/cost.d.ts.map +1 -1
  14. package/dist/commands/cost.js +54 -35
  15. package/dist/commands/cost.js.map +1 -1
  16. package/dist/commands/doctor.js +7 -0
  17. package/dist/commands/doctor.js.map +1 -1
  18. package/dist/commands/gate.d.ts.map +1 -1
  19. package/dist/commands/gate.js +13 -0
  20. package/dist/commands/gate.js.map +1 -1
  21. package/dist/commands/init.d.ts +14 -0
  22. package/dist/commands/init.d.ts.map +1 -1
  23. package/dist/commands/init.js +140 -17
  24. package/dist/commands/init.js.map +1 -1
  25. package/dist/commands/metrics.d.ts.map +1 -1
  26. package/dist/commands/metrics.js +6 -1
  27. package/dist/commands/metrics.js.map +1 -1
  28. package/dist/commands/review.d.ts +2 -27
  29. package/dist/commands/review.d.ts.map +1 -1
  30. package/dist/commands/review.js +10 -166
  31. package/dist/commands/review.js.map +1 -1
  32. package/dist/commands/status.d.ts.map +1 -1
  33. package/dist/commands/status.js +7 -0
  34. package/dist/commands/status.js.map +1 -1
  35. package/dist/commands/transition.d.ts.map +1 -1
  36. package/dist/commands/transition.js +24 -1
  37. package/dist/commands/transition.js.map +1 -1
  38. package/dist/compile/adapters/claude-code.d.ts.map +1 -1
  39. package/dist/compile/adapters/claude-code.js +5 -69
  40. package/dist/compile/adapters/claude-code.js.map +1 -1
  41. package/dist/compile/adapters/codex.d.ts +22 -1
  42. package/dist/compile/adapters/codex.d.ts.map +1 -1
  43. package/dist/compile/adapters/codex.js +61 -27
  44. package/dist/compile/adapters/codex.js.map +1 -1
  45. package/dist/compile/adapters/copilot.d.ts +64 -0
  46. package/dist/compile/adapters/copilot.d.ts.map +1 -0
  47. package/dist/compile/adapters/copilot.js +272 -0
  48. package/dist/compile/adapters/copilot.js.map +1 -0
  49. package/dist/compile/adapters/cursor.d.ts.map +1 -1
  50. package/dist/compile/adapters/cursor.js +2 -19
  51. package/dist/compile/adapters/cursor.js.map +1 -1
  52. package/dist/compile/adapters/index.d.ts.map +1 -1
  53. package/dist/compile/adapters/index.js +2 -0
  54. package/dist/compile/adapters/index.js.map +1 -1
  55. package/dist/compile/adapters/kiro.d.ts.map +1 -1
  56. package/dist/compile/adapters/kiro.js +1 -19
  57. package/dist/compile/adapters/kiro.js.map +1 -1
  58. package/dist/compile/adapters/windsurf.d.ts.map +1 -1
  59. package/dist/compile/adapters/windsurf.js +2 -1
  60. package/dist/compile/adapters/windsurf.js.map +1 -1
  61. package/dist/compile/capability-resolve.d.ts +34 -0
  62. package/dist/compile/capability-resolve.d.ts.map +1 -0
  63. package/dist/compile/capability-resolve.js +85 -0
  64. package/dist/compile/capability-resolve.js.map +1 -0
  65. package/dist/compile/guidance-install.d.ts +16 -19
  66. package/dist/compile/guidance-install.d.ts.map +1 -1
  67. package/dist/compile/guidance-install.js +26 -111
  68. package/dist/compile/guidance-install.js.map +1 -1
  69. package/dist/compile/layer-install.d.ts +122 -0
  70. package/dist/compile/layer-install.d.ts.map +1 -0
  71. package/dist/compile/layer-install.js +195 -0
  72. package/dist/compile/layer-install.js.map +1 -0
  73. package/dist/compile/limits.d.ts +10 -0
  74. package/dist/compile/limits.d.ts.map +1 -1
  75. package/dist/compile/limits.js +10 -0
  76. package/dist/compile/limits.js.map +1 -1
  77. package/dist/compile/loaders.d.ts +14 -0
  78. package/dist/compile/loaders.d.ts.map +1 -1
  79. package/dist/compile/loaders.js +23 -18
  80. package/dist/compile/loaders.js.map +1 -1
  81. package/dist/compile/naming.d.ts +23 -0
  82. package/dist/compile/naming.d.ts.map +1 -1
  83. package/dist/compile/naming.js +19 -1
  84. package/dist/compile/naming.js.map +1 -1
  85. package/dist/compile/skill-format.d.ts +39 -0
  86. package/dist/compile/skill-format.d.ts.map +1 -0
  87. package/dist/compile/skill-format.js +50 -0
  88. package/dist/compile/skill-format.js.map +1 -0
  89. package/dist/compliance/check.d.ts +79 -0
  90. package/dist/compliance/check.d.ts.map +1 -0
  91. package/dist/compliance/check.js +224 -0
  92. package/dist/compliance/check.js.map +1 -0
  93. package/dist/compliance/config.d.ts +91 -0
  94. package/dist/compliance/config.d.ts.map +1 -0
  95. package/dist/compliance/config.js +173 -0
  96. package/dist/compliance/config.js.map +1 -0
  97. package/dist/compliance/findings.d.ts +70 -0
  98. package/dist/compliance/findings.d.ts.map +1 -0
  99. package/dist/compliance/findings.js +132 -0
  100. package/dist/compliance/findings.js.map +1 -0
  101. package/dist/compliance/gate-criterion.d.ts +87 -0
  102. package/dist/compliance/gate-criterion.d.ts.map +1 -0
  103. package/dist/compliance/gate-criterion.js +168 -0
  104. package/dist/compliance/gate-criterion.js.map +1 -0
  105. package/dist/compliance/install.d.ts +135 -0
  106. package/dist/compliance/install.d.ts.map +1 -0
  107. package/dist/compliance/install.js +291 -0
  108. package/dist/compliance/install.js.map +1 -0
  109. package/dist/compliance/report.d.ts +144 -0
  110. package/dist/compliance/report.d.ts.map +1 -0
  111. package/dist/compliance/report.js +347 -0
  112. package/dist/compliance/report.js.map +1 -0
  113. package/dist/compliance/resolver.d.ts +65 -0
  114. package/dist/compliance/resolver.d.ts.map +1 -0
  115. package/dist/compliance/resolver.js +176 -0
  116. package/dist/compliance/resolver.js.map +1 -0
  117. package/dist/compliance/schema.d.ts +74 -0
  118. package/dist/compliance/schema.d.ts.map +1 -0
  119. package/dist/compliance/schema.js +474 -0
  120. package/dist/compliance/schema.js.map +1 -0
  121. package/dist/compliance/types.d.ts +140 -0
  122. package/dist/compliance/types.d.ts.map +1 -0
  123. package/dist/compliance/types.js +29 -0
  124. package/dist/compliance/types.js.map +1 -0
  125. package/dist/constitution/check.d.ts +22 -0
  126. package/dist/constitution/check.d.ts.map +1 -0
  127. package/dist/constitution/check.js +89 -0
  128. package/dist/constitution/check.js.map +1 -0
  129. package/dist/constitution/docx.d.ts +51 -0
  130. package/dist/constitution/docx.d.ts.map +1 -0
  131. package/dist/constitution/docx.js +157 -0
  132. package/dist/constitution/docx.js.map +1 -0
  133. package/dist/constitution/entries.d.ts +27 -0
  134. package/dist/constitution/entries.d.ts.map +1 -0
  135. package/dist/constitution/entries.js +65 -0
  136. package/dist/constitution/entries.js.map +1 -0
  137. package/dist/constitution/extract.d.ts +34 -0
  138. package/dist/constitution/extract.d.ts.map +1 -0
  139. package/dist/constitution/extract.js +117 -0
  140. package/dist/constitution/extract.js.map +1 -0
  141. package/dist/constitution/snapshot.d.ts +47 -0
  142. package/dist/constitution/snapshot.d.ts.map +1 -0
  143. package/dist/constitution/snapshot.js +159 -0
  144. package/dist/constitution/snapshot.js.map +1 -0
  145. package/dist/constitution/statements.d.ts +37 -0
  146. package/dist/constitution/statements.d.ts.map +1 -0
  147. package/dist/constitution/statements.js +64 -0
  148. package/dist/constitution/statements.js.map +1 -0
  149. package/dist/constitution/types.d.ts +80 -0
  150. package/dist/constitution/types.d.ts.map +1 -0
  151. package/dist/constitution/types.js +9 -0
  152. package/dist/constitution/types.js.map +1 -0
  153. package/dist/core/gate.d.ts +10 -0
  154. package/dist/core/gate.d.ts.map +1 -1
  155. package/dist/core/gate.js.map +1 -1
  156. package/dist/core/paths.d.ts +48 -0
  157. package/dist/core/paths.d.ts.map +1 -0
  158. package/dist/core/paths.js +57 -0
  159. package/dist/core/paths.js.map +1 -0
  160. package/dist/core/types.d.ts +13 -2
  161. package/dist/core/types.d.ts.map +1 -1
  162. package/dist/cost/hooks/registry.d.ts +44 -0
  163. package/dist/cost/hooks/registry.d.ts.map +1 -0
  164. package/dist/cost/hooks/registry.js +66 -0
  165. package/dist/cost/hooks/registry.js.map +1 -0
  166. package/dist/cost/pin.d.ts +63 -0
  167. package/dist/cost/pin.d.ts.map +1 -0
  168. package/dist/cost/pin.js +95 -0
  169. package/dist/cost/pin.js.map +1 -0
  170. package/dist/cost/providers/claude-code.d.ts +9 -2
  171. package/dist/cost/providers/claude-code.d.ts.map +1 -1
  172. package/dist/cost/providers/claude-code.js +10 -5
  173. package/dist/cost/providers/claude-code.js.map +1 -1
  174. package/dist/cost/providers/codex.d.ts +107 -0
  175. package/dist/cost/providers/codex.d.ts.map +1 -0
  176. package/dist/cost/providers/codex.js +283 -0
  177. package/dist/cost/providers/codex.js.map +1 -0
  178. package/dist/cost/providers/index.d.ts.map +1 -1
  179. package/dist/cost/providers/index.js +6 -0
  180. package/dist/cost/providers/index.js.map +1 -1
  181. package/dist/cost/rates.d.ts.map +1 -1
  182. package/dist/cost/rates.js +14 -0
  183. package/dist/cost/rates.js.map +1 -1
  184. package/dist/cost/report.d.ts +23 -1
  185. package/dist/cost/report.d.ts.map +1 -1
  186. package/dist/cost/report.js +26 -5
  187. package/dist/cost/report.js.map +1 -1
  188. package/dist/cost/sessions.d.ts +10 -1
  189. package/dist/cost/sessions.d.ts.map +1 -1
  190. package/dist/cost/sessions.js +10 -2
  191. package/dist/cost/sessions.js.map +1 -1
  192. package/dist/cost/sync.d.ts.map +1 -1
  193. package/dist/cost/sync.js +190 -5
  194. package/dist/cost/sync.js.map +1 -1
  195. package/dist/doctor/migrations/compliance-pack-drift.d.ts +62 -0
  196. package/dist/doctor/migrations/compliance-pack-drift.d.ts.map +1 -0
  197. package/dist/doctor/migrations/compliance-pack-drift.js +255 -0
  198. package/dist/doctor/migrations/compliance-pack-drift.js.map +1 -0
  199. package/dist/doctor/migrations/index.d.ts.map +1 -1
  200. package/dist/doctor/migrations/index.js +11 -0
  201. package/dist/doctor/migrations/index.js.map +1 -1
  202. package/dist/doctor/migrations/legacy-cost-hooks.d.ts.map +1 -1
  203. package/dist/doctor/migrations/legacy-cost-hooks.js +7 -4
  204. package/dist/doctor/migrations/legacy-cost-hooks.js.map +1 -1
  205. package/dist/doctor/migrations/missing-cost-shim.d.ts.map +1 -1
  206. package/dist/doctor/migrations/missing-cost-shim.js +5 -4
  207. package/dist/doctor/migrations/missing-cost-shim.js.map +1 -1
  208. package/dist/doctor/migrations/outdated-cost-hooks.d.ts.map +1 -1
  209. package/dist/doctor/migrations/outdated-cost-hooks.js +7 -4
  210. package/dist/doctor/migrations/outdated-cost-hooks.js.map +1 -1
  211. package/dist/doctor/migrations/stale-idea-skill.d.ts.map +1 -1
  212. package/dist/doctor/migrations/stale-idea-skill.js +2 -1
  213. package/dist/doctor/migrations/stale-idea-skill.js.map +1 -1
  214. package/dist/doctor/runner.js +14 -0
  215. package/dist/doctor/runner.js.map +1 -1
  216. package/dist/doctor/types.d.ts +35 -3
  217. package/dist/doctor/types.d.ts.map +1 -1
  218. package/dist/menu/roster.d.ts.map +1 -1
  219. package/dist/menu/roster.js +5 -0
  220. package/dist/menu/roster.js.map +1 -1
  221. package/dist/metrics/report.d.ts.map +1 -1
  222. package/dist/metrics/report.js +11 -2
  223. package/dist/metrics/report.js.map +1 -1
  224. package/dist/operational/packagers.d.ts.map +1 -1
  225. package/dist/operational/packagers.js +32 -0
  226. package/dist/operational/packagers.js.map +1 -1
  227. package/dist/review/findings-parser.d.ts +92 -0
  228. package/dist/review/findings-parser.d.ts.map +1 -0
  229. package/dist/review/findings-parser.js +196 -0
  230. package/dist/review/findings-parser.js.map +1 -0
  231. package/dist/setup/setup-compute.d.ts +10 -15
  232. package/dist/setup/setup-compute.d.ts.map +1 -1
  233. package/dist/setup/setup-compute.js +39 -0
  234. package/dist/setup/setup-compute.js.map +1 -1
  235. package/package.json +2 -2
@@ -0,0 +1,132 @@
1
+ /**
2
+ * The compliance findings stream: `<artifact>.compliance.md`.
3
+ *
4
+ * Deliberately a different filename from `<artifact>.review.md`. Findings files are
5
+ * discovered in exactly one place — `loadFindings` in `commands/transition.ts`,
6
+ * which filters on `f.endsWith('.review.md')` — so a compliance file cannot reach
7
+ * `checkReviewGate`. That is what buys advisory-by-default for nothing:
8
+ * `checkReviewGate` blocks on *any* critical open finding, pooled across artifacts,
9
+ * and `Finding` has no control field, so a critical control finding living in a
10
+ * review file would block a transition regardless of `compliance.enforce`.
11
+ *
12
+ * The grammar is the shared one in `../review/findings-parser.ts`, plus two
13
+ * additions:
14
+ *
15
+ * - a `Control` bullet on a finding block, naming the control id;
16
+ * - a `## Controls Checked` section whose lines record controls examined with no
17
+ * issue found.
18
+ *
19
+ * The cleared list is a separate production because coverage is satisfiable two
20
+ * ways: a finding carrying a control id, **or** an explicit no-issues line naming
21
+ * it. A no-issues line is not a finding — it has no severity, status or suggestion —
22
+ * so folding it into the finding grammar would mean inventing values for all three.
23
+ * Without it, a phase where every control passes would write a file the parser reads
24
+ * as empty, and the criterion would block on the whole applicable set.
25
+ *
26
+ * Requirements: compliance-packs/AC-62, AC-81
27
+ */
28
+ import { extractBulletField, parseFrontmatter, parseSingleFinding, splitBlocks, stripFrontmatter, } from '../review/findings-parser.js';
29
+ /** The heading that introduces the cleared list. */
30
+ export const CLEARED_HEADING = 'Controls Checked';
31
+ /** The suffix that marks a cleared line. Matched case-insensitively. */
32
+ const CLEARED_SUFFIX_RE = /—\s*no issues\s*$|-\s*no issues\s*$/i;
33
+ /** `<artifact>.compliance.md` for an artifact name. */
34
+ export function complianceFindingsFilename(artifact) {
35
+ return `${artifact}.compliance.md`;
36
+ }
37
+ /**
38
+ * Parse a compliance findings file.
39
+ *
40
+ * Never throws. A malformed section becomes a warning, because a compliance file
41
+ * that fails to parse must degrade to "nothing is covered" — the conservative
42
+ * direction — rather than break an unrelated transition.
43
+ */
44
+ export function parseComplianceFindings(content) {
45
+ const meta = parseFrontmatter(content);
46
+ const findings = [];
47
+ const cleared = [];
48
+ const warnings = [];
49
+ for (const block of splitBlocks(stripFrontmatter(content))) {
50
+ const heading = block.split('\n')[0]?.trim() ?? '';
51
+ if (heading.toLowerCase() === CLEARED_HEADING.toLowerCase()) {
52
+ for (const line of block.split('\n').slice(1)) {
53
+ const trimmed = line.trim();
54
+ if (trimmed === '')
55
+ continue;
56
+ const control = extractBulletField(line, 'Control');
57
+ if (control === undefined) {
58
+ if (trimmed.startsWith('-')) {
59
+ warnings.push(`unparseable line in ${CLEARED_HEADING}: ${trimmed}`);
60
+ }
61
+ continue;
62
+ }
63
+ // `- **Control:** CC6.1 — no issues` → the id, with the suffix stripped.
64
+ const id = control.replace(CLEARED_SUFFIX_RE, '').trim();
65
+ if (id === '') {
66
+ warnings.push(`${CLEARED_HEADING} line names no control: ${trimmed}`);
67
+ continue;
68
+ }
69
+ if (!CLEARED_SUFFIX_RE.test(control)) {
70
+ // A control listed without the no-issues marker is ambiguous: it might mean
71
+ // "checked, fine" or "checked, and I never finished writing it up". Neither
72
+ // reading is safe to assume, so it is not counted as cleared.
73
+ warnings.push(`${CLEARED_HEADING} line for ${id} does not say "no issues" — not counted as covered`);
74
+ continue;
75
+ }
76
+ cleared.push(id);
77
+ }
78
+ continue;
79
+ }
80
+ const finding = parseSingleFinding(block, findings.length + 1);
81
+ if (!finding)
82
+ continue;
83
+ const control = extractBulletField(block, 'Control');
84
+ findings.push({ ...finding, ...(control !== undefined && { control: control.trim() }) });
85
+ }
86
+ const withoutControl = findings.filter((f) => f.control === undefined);
87
+ if (withoutControl.length > 0) {
88
+ // A control finding with no control id cannot satisfy coverage for anything, and
89
+ // an author who wrote it believes they covered something. Say so.
90
+ warnings.push(`${withoutControl.length} finding(s) in the compliance stream carry no Control field`);
91
+ }
92
+ return { meta, findings, cleared, warnings };
93
+ }
94
+ /** Ids a compliance file accounts for: raised against, or explicitly cleared. */
95
+ export function accountedControls(file) {
96
+ const ids = new Set(file.cleared);
97
+ for (const finding of file.findings) {
98
+ if (finding.control !== undefined)
99
+ ids.add(finding.control);
100
+ }
101
+ return ids;
102
+ }
103
+ /**
104
+ * Render the scaffold of a compliance findings file.
105
+ *
106
+ * Lists every applicable control so the reviewing agent cannot forget one, and marks
107
+ * each as pending rather than cleared — an unwritten file must never read as covered.
108
+ */
109
+ export function renderComplianceScaffold(artifact, reviewer, controls, now = new Date()) {
110
+ const lines = [
111
+ '---',
112
+ `artifact: ${artifact}`,
113
+ `reviewed_at: ${now.toISOString().replace(/\.\d{3}Z$/, 'Z')}`,
114
+ `reviewer: ${reviewer}`,
115
+ '---',
116
+ '',
117
+ '<!--',
118
+ 'For each control below: either write a finding block carrying its Control id, or',
119
+ `move it to the ${CLEARED_HEADING} section with "— no issues".`,
120
+ 'A control left in neither place counts as uncovered.',
121
+ '-->',
122
+ '',
123
+ `## ${CLEARED_HEADING}`,
124
+ '',
125
+ ];
126
+ for (const control of controls) {
127
+ lines.push(`- **Control:** ${control.id} — PENDING: ${control.fails_when}`);
128
+ }
129
+ lines.push('');
130
+ return lines.join('\n');
131
+ }
132
+ //# sourceMappingURL=findings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findings.js","sourceRoot":"","sources":["../../src/compliance/findings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Compliance gate criterion, computed at the command layer after `evaluateGate`.
3
+ *
4
+ * Follows the convention `knowledge/`, `traceability/` and `tasks/` established: a
5
+ * `gate-criterion.ts` per concern, exporting an evaluator plus message helpers, and
6
+ * registered at both wiring sites. `core/gate.ts` and `core/lifecycle.ts` are not
7
+ * modified at all.
8
+ *
9
+ * Two properties matter more than the coverage arithmetic:
10
+ *
11
+ * **A project with no pack installed sees nothing.** The evaluator returns `null`,
12
+ * the command layer assigns no field, and behaviour is what it was before this
13
+ * feature existed. That is the constraint the whole design is organised around, and
14
+ * `null` is the mechanism.
15
+ *
16
+ * **Advisory is the default.** Findings are computed and reported whether or not
17
+ * enforcement is on; only `compliance.enforce: true` turns them into gate failures.
18
+ * Because control findings live in their own stream, the pre-existing review gate
19
+ * never sees them, so advisory costs no change to gate logic.
20
+ *
21
+ * Coverage is measured over the **effective** required artifacts, not the template's
22
+ * raw list. The repo is already inconsistent here — `checkRequiredArtifacts` applies
23
+ * the legacy `tasks.md` filter and `checkReviewGate` does not — and using the raw
24
+ * list would block a pre-existing design-phase instance from transitioning under
25
+ * enforcement until someone wrote a compliance file for an artifact the
26
+ * required-artifacts gate agrees is optional.
27
+ *
28
+ * Requirements: compliance-packs/AC-25, AC-26, AC-55, AC-56, AC-62, AC-82
29
+ */
30
+ import type { WorkflowTemplate } from '../core/types.js';
31
+ import type { Control } from './types.js';
32
+ /** One control that applies to the phase under evaluation. */
33
+ export interface ApplicableControl {
34
+ packId: string;
35
+ control: Control;
36
+ }
37
+ /** A control that no artifact accounted for. */
38
+ export interface UncoveredControl {
39
+ controlId: string;
40
+ artifact: string;
41
+ }
42
+ /** A critical control finding left open. */
43
+ export interface OpenCriticalControl {
44
+ controlId: string;
45
+ findingId: string;
46
+ artifact: string;
47
+ }
48
+ /** Outcome of the compliance criterion for one phase. */
49
+ export interface ComplianceResult {
50
+ /** Packs consulted, by id. */
51
+ packs: string[];
52
+ /** Whether `compliance.enforce` is on. Drives failure, never computation. */
53
+ enforce: boolean;
54
+ /** Controls applying to this phase. */
55
+ applicable: string[];
56
+ /** Artifacts whose coverage was measured. */
57
+ artifacts: string[];
58
+ /** Control/artifact pairs with neither a finding nor a cleared line. */
59
+ uncovered: UncoveredControl[];
60
+ /** Critical control findings still open. */
61
+ openCritical: OpenCriticalControl[];
62
+ /** Non-fatal problems: unparseable lines, packs that no longer resolve. */
63
+ warnings: string[];
64
+ }
65
+ /** Message for a control no artifact accounted for. */
66
+ export declare function uncoveredControlMessage(controlId: string, artifact: string): string;
67
+ /** Message for an open critical control finding. */
68
+ export declare function criticalControlMessage(controlId: string, findingId: string): string;
69
+ /** Message for an installed pack that will not load. */
70
+ export declare function packLoadErrorMessage(packId: string, detail: string): string;
71
+ /**
72
+ * Evaluate the compliance criterion for one phase.
73
+ *
74
+ * @returns `null` when the criterion does not apply — no pack installed, or no
75
+ * control applies to this phase. Never an empty result standing in for "off":
76
+ * the command layer distinguishes the two by the null.
77
+ */
78
+ export declare function evaluateComplianceCriterion(projectRoot: string, instanceName: string, phaseName: string, template: WorkflowTemplate | null): ComplianceResult | null;
79
+ /**
80
+ * The gate failures a result implies.
81
+ *
82
+ * Empty unless `enforce` is on. Advisory mode still produces the result — the
83
+ * findings are recorded and reported — it simply produces no failures, which is the
84
+ * whole meaning of advisory.
85
+ */
86
+ export declare function complianceFailures(result: ComplianceResult): string[];
87
+ //# sourceMappingURL=gate-criterion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-criterion.d.ts","sourceRoot":"","sources":["../../src/compliance/gate-criterion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAOH,OAAO,KAAK,EAAc,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAQrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,8DAA8D;AAC9D,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,4CAA4C;AAC5C,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,8BAA8B;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,6EAA6E;IAC7E,OAAO,EAAE,OAAO,CAAC;IACjB,uCAAuC;IACvC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,wEAAwE;IACxE,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,4CAA4C;IAC5C,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,uDAAuD;AACvD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED,oDAAoD;AACpD,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED,wDAAwD;AACxD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3E;AAaD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAChC,gBAAgB,GAAG,IAAI,CAiGzB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAMrE"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Compliance gate criterion, computed at the command layer after `evaluateGate`.
3
+ *
4
+ * Follows the convention `knowledge/`, `traceability/` and `tasks/` established: a
5
+ * `gate-criterion.ts` per concern, exporting an evaluator plus message helpers, and
6
+ * registered at both wiring sites. `core/gate.ts` and `core/lifecycle.ts` are not
7
+ * modified at all.
8
+ *
9
+ * Two properties matter more than the coverage arithmetic:
10
+ *
11
+ * **A project with no pack installed sees nothing.** The evaluator returns `null`,
12
+ * the command layer assigns no field, and behaviour is what it was before this
13
+ * feature existed. That is the constraint the whole design is organised around, and
14
+ * `null` is the mechanism.
15
+ *
16
+ * **Advisory is the default.** Findings are computed and reported whether or not
17
+ * enforcement is on; only `compliance.enforce: true` turns them into gate failures.
18
+ * Because control findings live in their own stream, the pre-existing review gate
19
+ * never sees them, so advisory costs no change to gate logic.
20
+ *
21
+ * Coverage is measured over the **effective** required artifacts, not the template's
22
+ * raw list. The repo is already inconsistent here — `checkRequiredArtifacts` applies
23
+ * the legacy `tasks.md` filter and `checkReviewGate` does not — and using the raw
24
+ * list would block a pre-existing design-phase instance from transitioning under
25
+ * enforcement until someone wrote a compliance file for an artifact the
26
+ * required-artifacts gate agrees is optional.
27
+ *
28
+ * Requirements: compliance-packs/AC-25, AC-26, AC-55, AC-56, AC-62, AC-82
29
+ */
30
+ import { existsSync, readFileSync } from 'node:fs';
31
+ import { join } from 'node:path';
32
+ import { parse as parseYaml } from 'yaml';
33
+ import { effectiveRequiredArtifacts } from '../core/gate.js';
34
+ import { readComplianceConfig } from './config.js';
35
+ import { accountedControls, complianceFindingsFilename, parseComplianceFindings, } from './findings.js';
36
+ import { controlsForPhase, resolvePack } from './resolver.js';
37
+ /** Message for a control no artifact accounted for. */
38
+ export function uncoveredControlMessage(controlId, artifact) {
39
+ return `control ${controlId} is not accounted for in "${artifact}" (compliance)`;
40
+ }
41
+ /** Message for an open critical control finding. */
42
+ export function criticalControlMessage(controlId, findingId) {
43
+ return `control ${controlId} has an open critical finding "${findingId}" (compliance)`;
44
+ }
45
+ /** Message for an installed pack that will not load. */
46
+ export function packLoadErrorMessage(packId, detail) {
47
+ return `installed pack '${packId}' did not load: ${detail} (compliance)`;
48
+ }
49
+ /** Read one phase state file, or undefined. */
50
+ function loadPhaseState(instanceDir, phase) {
51
+ const path = join(instanceDir, `phase-${phase}.yaml`);
52
+ if (!existsSync(path))
53
+ return undefined;
54
+ try {
55
+ return parseYaml(readFileSync(path, 'utf8'));
56
+ }
57
+ catch {
58
+ return undefined;
59
+ }
60
+ }
61
+ /**
62
+ * Evaluate the compliance criterion for one phase.
63
+ *
64
+ * @returns `null` when the criterion does not apply — no pack installed, or no
65
+ * control applies to this phase. Never an empty result standing in for "off":
66
+ * the command layer distinguishes the two by the null.
67
+ */
68
+ export function evaluateComplianceCriterion(projectRoot, instanceName, phaseName, template) {
69
+ const config = readComplianceConfig(projectRoot);
70
+ if (config.packs.length === 0)
71
+ return null;
72
+ const warnings = [];
73
+ const applicable = [];
74
+ for (const record of config.packs) {
75
+ const resolved = resolvePack(record.id);
76
+ if (!resolved.ok) {
77
+ // An installed pack that will not load is loud, never an empty result — the
78
+ // silent-no-op shape this project has already been burned by.
79
+ warnings.push(packLoadErrorMessage(record.id, resolved.error.errors.join('; ')));
80
+ continue;
81
+ }
82
+ for (const control of controlsForPhase(resolved.pack, phaseName)) {
83
+ applicable.push({ packId: record.id, control });
84
+ }
85
+ }
86
+ if (applicable.length === 0) {
87
+ // Packs are installed but none of their controls touch this phase. Not a
88
+ // failure, and not nothing: reported with an empty applicable set so the caller
89
+ // can say "no applicable controls" rather than staying silent.
90
+ return {
91
+ packs: config.packs.map((p) => p.id),
92
+ enforce: config.enforce,
93
+ applicable: [],
94
+ artifacts: [],
95
+ uncovered: [],
96
+ openCritical: [],
97
+ warnings,
98
+ };
99
+ }
100
+ const instanceDir = join(projectRoot, '.aidlc', 'state', instanceName);
101
+ const templatePhase = template?.phases.find((p) => p.name === phaseName);
102
+ const phaseState = loadPhaseState(instanceDir, phaseName);
103
+ const artifacts = templatePhase
104
+ ? effectiveRequiredArtifacts(templatePhase, phaseState).map((a) => a.name)
105
+ : [];
106
+ const uncovered = [];
107
+ const openCritical = [];
108
+ for (const artifact of artifacts) {
109
+ const path = join(instanceDir, complianceFindingsFilename(artifact));
110
+ if (!existsSync(path)) {
111
+ for (const { control } of applicable) {
112
+ uncovered.push({ controlId: control.id, artifact });
113
+ }
114
+ continue;
115
+ }
116
+ let file;
117
+ try {
118
+ file = parseComplianceFindings(readFileSync(path, 'utf8'));
119
+ }
120
+ catch (err) {
121
+ warnings.push(`compliance findings for "${artifact}" are unreadable (${err.message}) — treated as uncovered`);
122
+ for (const { control } of applicable) {
123
+ uncovered.push({ controlId: control.id, artifact });
124
+ }
125
+ continue;
126
+ }
127
+ warnings.push(...file.warnings.map((w) => `${artifact}: ${w}`));
128
+ const accounted = accountedControls(file);
129
+ for (const { control } of applicable) {
130
+ if (!accounted.has(control.id)) {
131
+ uncovered.push({ controlId: control.id, artifact });
132
+ }
133
+ }
134
+ for (const finding of file.findings) {
135
+ if (finding.control !== undefined &&
136
+ finding.severity === 'critical' &&
137
+ finding.status === 'open' &&
138
+ finding.placeholder !== true) {
139
+ openCritical.push({ controlId: finding.control, findingId: finding.id, artifact });
140
+ }
141
+ }
142
+ }
143
+ return {
144
+ packs: config.packs.map((p) => p.id),
145
+ enforce: config.enforce,
146
+ applicable: applicable.map((a) => a.control.id),
147
+ artifacts,
148
+ uncovered,
149
+ openCritical,
150
+ warnings,
151
+ };
152
+ }
153
+ /**
154
+ * The gate failures a result implies.
155
+ *
156
+ * Empty unless `enforce` is on. Advisory mode still produces the result — the
157
+ * findings are recorded and reported — it simply produces no failures, which is the
158
+ * whole meaning of advisory.
159
+ */
160
+ export function complianceFailures(result) {
161
+ if (!result.enforce)
162
+ return [];
163
+ return [
164
+ ...result.uncovered.map((u) => uncoveredControlMessage(u.controlId, u.artifact)),
165
+ ...result.openCritical.map((c) => criticalControlMessage(c.controlId, c.findingId)),
166
+ ];
167
+ }
168
+ //# sourceMappingURL=gate-criterion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-criterion.js","sourceRoot":"","sources":["../../src/compliance/gate-criterion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Pack install, remove and upgrade.
3
+ *
4
+ * Uses the layer-install primitive with the **recorded-hash** detector, never the
5
+ * bundled-body one. That choice is the whole reason the primitive takes a detector:
6
+ * comparing a pack layer against the currently bundled body conflates "the user
7
+ * edited this" with "we published a new version", which would make every layer read
8
+ * as edited after any content update — so `remove` would refuse to delete anything
9
+ * and corrected control text would never land.
10
+ *
11
+ * Three rules govern what happens to files:
12
+ *
13
+ * - **Install never overwrites.** A layer already on disk is left alone and
14
+ * classified, exactly as framework install does.
15
+ * - **Remove deletes only what it can prove it wrote.** Unmodified means the disk
16
+ * hash matches the hash recorded at install. Anything else is the project's file
17
+ * now, and stays.
18
+ * - **A left-behind file loses its registration.** Keeping bytes is respect for the
19
+ * user's edit; keeping the registration would keep feeding an uninstalled pack's
20
+ * constraints to every agent.
21
+ *
22
+ * Requirements: compliance-packs/AC-9, AC-10, AC-11, AC-12, AC-13, AC-16, AC-54,
23
+ * AC-68, AC-69, AC-70, AC-71, AC-72
24
+ */
25
+ import type { PackError } from './types.js';
26
+ /** Outcome of an install attempt. */
27
+ export type InstallResult = {
28
+ ok: true;
29
+ /** Layer names newly written. */
30
+ installed: string[];
31
+ /** Layer names already present and matching what we recorded. */
32
+ alreadyCurrent: string[];
33
+ /** Layer names present but changed since install — left untouched. */
34
+ locallyModified: string[];
35
+ /** True when this was a no-op because the pack was already installed. */
36
+ unchanged: boolean;
37
+ warnings: string[];
38
+ } | {
39
+ ok: false;
40
+ error: PackError;
41
+ };
42
+ /**
43
+ * Install a pack into a project.
44
+ *
45
+ * Idempotent: a second run writes nothing new and reports `unchanged`. Validation
46
+ * happens first and covers the whole pack, so a pack with one malformed control
47
+ * installs nothing at all.
48
+ */
49
+ export declare function installPack(projectRoot: string, id: string, opts?: {
50
+ dryRun?: boolean;
51
+ now?: Date;
52
+ }): InstallResult;
53
+ /** Outcome of a remove attempt. */
54
+ export type RemoveResult = {
55
+ ok: true;
56
+ /** Files deleted, repo-relative. */
57
+ deleted: string[];
58
+ /**
59
+ * Files left on disk because they no longer match what we wrote, repo-relative.
60
+ * Their registrations were still dropped, so they no longer reach any agent.
61
+ */
62
+ keptPaths: string[];
63
+ /** Layer registrations dropped from the index. */
64
+ unregistered: string[];
65
+ warnings: string[];
66
+ } | {
67
+ ok: false;
68
+ error: PackError;
69
+ };
70
+ /**
71
+ * Remove an installed pack.
72
+ *
73
+ * Deletes only layers whose on-disk hash matches the hash recorded at install.
74
+ * Every registration is dropped either way, so nothing an uninstalled pack owns
75
+ * keeps influencing an agent.
76
+ *
77
+ * Resolution of the pack is **not** required: a pack must remain removable after the
78
+ * content package stops shipping it, which is precisely when a user most wants it
79
+ * gone. The config record alone is enough.
80
+ */
81
+ export declare function removePack(projectRoot: string, id: string, opts?: {
82
+ dryRun?: boolean;
83
+ }): RemoveResult;
84
+ /** What `aidlc compliance list` needs to say about one pack. */
85
+ export interface PackStatus {
86
+ id: string;
87
+ regime: string;
88
+ /** Version available in the content package, or null when it no longer ships. */
89
+ available: string | null;
90
+ /** Version recorded at install, or null when not installed. */
91
+ installed: string | null;
92
+ /** Recorded version differs from the available one. */
93
+ stale: boolean;
94
+ /** Whether the pack's control text has been reviewed by a practitioner. */
95
+ reviewed: boolean;
96
+ /**
97
+ * Installed layer files whose on-disk hash no longer matches the recorded one.
98
+ *
99
+ * Reported for every installed pack, not only when a notice is missing: in a cloned
100
+ * repository an installed layer is content the repo author could have changed, and a
101
+ * locally edited layer is preserved forever by design.
102
+ */
103
+ drifted: string[];
104
+ }
105
+ /** Status of every available pack, plus any installed pack that no longer ships. */
106
+ export declare function packStatuses(projectRoot: string): {
107
+ statuses: PackStatus[];
108
+ errors: PackError[];
109
+ };
110
+ /** Outcome of an upgrade attempt. */
111
+ export type UpgradeResult = {
112
+ ok: true;
113
+ from: string;
114
+ to: string;
115
+ replaced: string[];
116
+ keptPaths: string[];
117
+ warnings: string[];
118
+ } | {
119
+ ok: false;
120
+ error: PackError;
121
+ };
122
+ /**
123
+ * Upgrade an installed pack to the version the content package ships.
124
+ *
125
+ * Deliberately its own command. Neither `aidlc update` nor `aidlc doctor` may do
126
+ * this: pack content is what a buyer is told they are being governed by, and
127
+ * changing it under them without a word is not an upgrade, it is a substitution.
128
+ *
129
+ * A locally edited layer is never overwritten. It is left in place and reported, so
130
+ * the user decides whether to discard their edit.
131
+ */
132
+ export declare function upgradePack(projectRoot: string, id: string, opts?: {
133
+ dryRun?: boolean;
134
+ }): UpgradeResult;
135
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/compliance/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAiBH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAO5C,qCAAqC;AACrC,MAAM,MAAM,aAAa,GACrB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,iCAAiC;IACjC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,iEAAiE;IACjE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,sEAAsE;IACtE,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAEpC;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GAC1C,aAAa,CA6Ef;AAED,mCAAmC;AACnC,MAAM,MAAM,YAAY,GACpB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,oCAAoC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;OAGG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kDAAkD;IAClD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAEpC;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CACxB,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9B,YAAY,CAyEd;AAeD,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,uDAAuD;IACvD,KAAK,EAAE,OAAO,CAAC;IACf,2EAA2E;IAC3E,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IAAC,MAAM,EAAE,SAAS,EAAE,CAAA;CAAE,CA0CjG;AAWD,qCAAqC;AACrC,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GACnG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAEpC;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9B,aAAa,CAqCf"}