@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.
- package/README.md +9 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/compliance.d.ts +36 -0
- package/dist/commands/compliance.d.ts.map +1 -0
- package/dist/commands/compliance.js +275 -0
- package/dist/commands/compliance.js.map +1 -0
- package/dist/commands/constitution.d.ts +26 -0
- package/dist/commands/constitution.d.ts.map +1 -0
- package/dist/commands/constitution.js +145 -0
- package/dist/commands/constitution.js.map +1 -0
- package/dist/commands/cost.d.ts.map +1 -1
- package/dist/commands/cost.js +54 -35
- package/dist/commands/cost.js.map +1 -1
- package/dist/commands/doctor.js +7 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/gate.d.ts.map +1 -1
- package/dist/commands/gate.js +13 -0
- package/dist/commands/gate.js.map +1 -1
- package/dist/commands/init.d.ts +14 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +140 -17
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/metrics.d.ts.map +1 -1
- package/dist/commands/metrics.js +6 -1
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/review.d.ts +2 -27
- package/dist/commands/review.d.ts.map +1 -1
- package/dist/commands/review.js +10 -166
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +7 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/transition.d.ts.map +1 -1
- package/dist/commands/transition.js +24 -1
- package/dist/commands/transition.js.map +1 -1
- package/dist/compile/adapters/claude-code.d.ts.map +1 -1
- package/dist/compile/adapters/claude-code.js +5 -69
- package/dist/compile/adapters/claude-code.js.map +1 -1
- package/dist/compile/adapters/codex.d.ts +22 -1
- package/dist/compile/adapters/codex.d.ts.map +1 -1
- package/dist/compile/adapters/codex.js +61 -27
- package/dist/compile/adapters/codex.js.map +1 -1
- package/dist/compile/adapters/copilot.d.ts +64 -0
- package/dist/compile/adapters/copilot.d.ts.map +1 -0
- package/dist/compile/adapters/copilot.js +272 -0
- package/dist/compile/adapters/copilot.js.map +1 -0
- package/dist/compile/adapters/cursor.d.ts.map +1 -1
- package/dist/compile/adapters/cursor.js +2 -19
- package/dist/compile/adapters/cursor.js.map +1 -1
- package/dist/compile/adapters/index.d.ts.map +1 -1
- package/dist/compile/adapters/index.js +2 -0
- package/dist/compile/adapters/index.js.map +1 -1
- package/dist/compile/adapters/kiro.d.ts.map +1 -1
- package/dist/compile/adapters/kiro.js +1 -19
- package/dist/compile/adapters/kiro.js.map +1 -1
- package/dist/compile/adapters/windsurf.d.ts.map +1 -1
- package/dist/compile/adapters/windsurf.js +2 -1
- package/dist/compile/adapters/windsurf.js.map +1 -1
- package/dist/compile/capability-resolve.d.ts +34 -0
- package/dist/compile/capability-resolve.d.ts.map +1 -0
- package/dist/compile/capability-resolve.js +85 -0
- package/dist/compile/capability-resolve.js.map +1 -0
- package/dist/compile/guidance-install.d.ts +16 -19
- package/dist/compile/guidance-install.d.ts.map +1 -1
- package/dist/compile/guidance-install.js +26 -111
- package/dist/compile/guidance-install.js.map +1 -1
- package/dist/compile/layer-install.d.ts +122 -0
- package/dist/compile/layer-install.d.ts.map +1 -0
- package/dist/compile/layer-install.js +195 -0
- package/dist/compile/layer-install.js.map +1 -0
- package/dist/compile/limits.d.ts +10 -0
- package/dist/compile/limits.d.ts.map +1 -1
- package/dist/compile/limits.js +10 -0
- package/dist/compile/limits.js.map +1 -1
- package/dist/compile/loaders.d.ts +14 -0
- package/dist/compile/loaders.d.ts.map +1 -1
- package/dist/compile/loaders.js +23 -18
- package/dist/compile/loaders.js.map +1 -1
- package/dist/compile/naming.d.ts +23 -0
- package/dist/compile/naming.d.ts.map +1 -1
- package/dist/compile/naming.js +19 -1
- package/dist/compile/naming.js.map +1 -1
- package/dist/compile/skill-format.d.ts +39 -0
- package/dist/compile/skill-format.d.ts.map +1 -0
- package/dist/compile/skill-format.js +50 -0
- package/dist/compile/skill-format.js.map +1 -0
- package/dist/compliance/check.d.ts +79 -0
- package/dist/compliance/check.d.ts.map +1 -0
- package/dist/compliance/check.js +224 -0
- package/dist/compliance/check.js.map +1 -0
- package/dist/compliance/config.d.ts +91 -0
- package/dist/compliance/config.d.ts.map +1 -0
- package/dist/compliance/config.js +173 -0
- package/dist/compliance/config.js.map +1 -0
- package/dist/compliance/findings.d.ts +70 -0
- package/dist/compliance/findings.d.ts.map +1 -0
- package/dist/compliance/findings.js +132 -0
- package/dist/compliance/findings.js.map +1 -0
- package/dist/compliance/gate-criterion.d.ts +87 -0
- package/dist/compliance/gate-criterion.d.ts.map +1 -0
- package/dist/compliance/gate-criterion.js +168 -0
- package/dist/compliance/gate-criterion.js.map +1 -0
- package/dist/compliance/install.d.ts +135 -0
- package/dist/compliance/install.d.ts.map +1 -0
- package/dist/compliance/install.js +291 -0
- package/dist/compliance/install.js.map +1 -0
- package/dist/compliance/report.d.ts +144 -0
- package/dist/compliance/report.d.ts.map +1 -0
- package/dist/compliance/report.js +347 -0
- package/dist/compliance/report.js.map +1 -0
- package/dist/compliance/resolver.d.ts +65 -0
- package/dist/compliance/resolver.d.ts.map +1 -0
- package/dist/compliance/resolver.js +176 -0
- package/dist/compliance/resolver.js.map +1 -0
- package/dist/compliance/schema.d.ts +74 -0
- package/dist/compliance/schema.d.ts.map +1 -0
- package/dist/compliance/schema.js +474 -0
- package/dist/compliance/schema.js.map +1 -0
- package/dist/compliance/types.d.ts +140 -0
- package/dist/compliance/types.d.ts.map +1 -0
- package/dist/compliance/types.js +29 -0
- package/dist/compliance/types.js.map +1 -0
- package/dist/constitution/check.d.ts +22 -0
- package/dist/constitution/check.d.ts.map +1 -0
- package/dist/constitution/check.js +89 -0
- package/dist/constitution/check.js.map +1 -0
- package/dist/constitution/docx.d.ts +51 -0
- package/dist/constitution/docx.d.ts.map +1 -0
- package/dist/constitution/docx.js +157 -0
- package/dist/constitution/docx.js.map +1 -0
- package/dist/constitution/entries.d.ts +27 -0
- package/dist/constitution/entries.d.ts.map +1 -0
- package/dist/constitution/entries.js +65 -0
- package/dist/constitution/entries.js.map +1 -0
- package/dist/constitution/extract.d.ts +34 -0
- package/dist/constitution/extract.d.ts.map +1 -0
- package/dist/constitution/extract.js +117 -0
- package/dist/constitution/extract.js.map +1 -0
- package/dist/constitution/snapshot.d.ts +47 -0
- package/dist/constitution/snapshot.d.ts.map +1 -0
- package/dist/constitution/snapshot.js +159 -0
- package/dist/constitution/snapshot.js.map +1 -0
- package/dist/constitution/statements.d.ts +37 -0
- package/dist/constitution/statements.d.ts.map +1 -0
- package/dist/constitution/statements.js +64 -0
- package/dist/constitution/statements.js.map +1 -0
- package/dist/constitution/types.d.ts +80 -0
- package/dist/constitution/types.d.ts.map +1 -0
- package/dist/constitution/types.js +9 -0
- package/dist/constitution/types.js.map +1 -0
- package/dist/core/gate.d.ts +10 -0
- package/dist/core/gate.d.ts.map +1 -1
- package/dist/core/gate.js.map +1 -1
- package/dist/core/paths.d.ts +48 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +57 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/types.d.ts +13 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/cost/hooks/registry.d.ts +44 -0
- package/dist/cost/hooks/registry.d.ts.map +1 -0
- package/dist/cost/hooks/registry.js +66 -0
- package/dist/cost/hooks/registry.js.map +1 -0
- package/dist/cost/pin.d.ts +63 -0
- package/dist/cost/pin.d.ts.map +1 -0
- package/dist/cost/pin.js +95 -0
- package/dist/cost/pin.js.map +1 -0
- package/dist/cost/providers/claude-code.d.ts +9 -2
- package/dist/cost/providers/claude-code.d.ts.map +1 -1
- package/dist/cost/providers/claude-code.js +10 -5
- package/dist/cost/providers/claude-code.js.map +1 -1
- package/dist/cost/providers/codex.d.ts +107 -0
- package/dist/cost/providers/codex.d.ts.map +1 -0
- package/dist/cost/providers/codex.js +283 -0
- package/dist/cost/providers/codex.js.map +1 -0
- package/dist/cost/providers/index.d.ts.map +1 -1
- package/dist/cost/providers/index.js +6 -0
- package/dist/cost/providers/index.js.map +1 -1
- package/dist/cost/rates.d.ts.map +1 -1
- package/dist/cost/rates.js +14 -0
- package/dist/cost/rates.js.map +1 -1
- package/dist/cost/report.d.ts +23 -1
- package/dist/cost/report.d.ts.map +1 -1
- package/dist/cost/report.js +26 -5
- package/dist/cost/report.js.map +1 -1
- package/dist/cost/sessions.d.ts +10 -1
- package/dist/cost/sessions.d.ts.map +1 -1
- package/dist/cost/sessions.js +10 -2
- package/dist/cost/sessions.js.map +1 -1
- package/dist/cost/sync.d.ts.map +1 -1
- package/dist/cost/sync.js +190 -5
- package/dist/cost/sync.js.map +1 -1
- package/dist/doctor/migrations/compliance-pack-drift.d.ts +62 -0
- package/dist/doctor/migrations/compliance-pack-drift.d.ts.map +1 -0
- package/dist/doctor/migrations/compliance-pack-drift.js +255 -0
- package/dist/doctor/migrations/compliance-pack-drift.js.map +1 -0
- package/dist/doctor/migrations/index.d.ts.map +1 -1
- package/dist/doctor/migrations/index.js +11 -0
- package/dist/doctor/migrations/index.js.map +1 -1
- package/dist/doctor/migrations/legacy-cost-hooks.d.ts.map +1 -1
- package/dist/doctor/migrations/legacy-cost-hooks.js +7 -4
- package/dist/doctor/migrations/legacy-cost-hooks.js.map +1 -1
- package/dist/doctor/migrations/missing-cost-shim.d.ts.map +1 -1
- package/dist/doctor/migrations/missing-cost-shim.js +5 -4
- package/dist/doctor/migrations/missing-cost-shim.js.map +1 -1
- package/dist/doctor/migrations/outdated-cost-hooks.d.ts.map +1 -1
- package/dist/doctor/migrations/outdated-cost-hooks.js +7 -4
- package/dist/doctor/migrations/outdated-cost-hooks.js.map +1 -1
- package/dist/doctor/migrations/stale-idea-skill.d.ts.map +1 -1
- package/dist/doctor/migrations/stale-idea-skill.js +2 -1
- package/dist/doctor/migrations/stale-idea-skill.js.map +1 -1
- package/dist/doctor/runner.js +14 -0
- package/dist/doctor/runner.js.map +1 -1
- package/dist/doctor/types.d.ts +35 -3
- package/dist/doctor/types.d.ts.map +1 -1
- package/dist/menu/roster.d.ts.map +1 -1
- package/dist/menu/roster.js +5 -0
- package/dist/menu/roster.js.map +1 -1
- package/dist/metrics/report.d.ts.map +1 -1
- package/dist/metrics/report.js +11 -2
- package/dist/metrics/report.js.map +1 -1
- package/dist/operational/packagers.d.ts.map +1 -1
- package/dist/operational/packagers.js +32 -0
- package/dist/operational/packagers.js.map +1 -1
- package/dist/review/findings-parser.d.ts +92 -0
- package/dist/review/findings-parser.d.ts.map +1 -0
- package/dist/review/findings-parser.js +196 -0
- package/dist/review/findings-parser.js.map +1 -0
- package/dist/setup/setup-compute.d.ts +10 -15
- package/dist/setup/setup-compute.d.ts.map +1 -1
- package/dist/setup/setup-compute.js +39 -0
- package/dist/setup/setup-compute.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The evidence report — the artifact a buyer hands to an auditor.
|
|
3
|
+
*
|
|
4
|
+
* Derived entirely from state already on disk. That is the bet this whole feature
|
|
5
|
+
* rests on: if producing the report required a developer to write anything they would
|
|
6
|
+
* not otherwise write, the remaining feature would be a text file with a command
|
|
7
|
+
* group around it, and the design's stated fallback would be to ship that instead.
|
|
8
|
+
*
|
|
9
|
+
* Three properties are load-bearing, and each exists because its absence would make
|
|
10
|
+
* the report actively misleading:
|
|
11
|
+
*
|
|
12
|
+
* **A checked-only control never carries evidence.** CC8.1 is a control over the
|
|
13
|
+
* change process, and the artifact trail genuinely demonstrates it. The CC6 and CC7
|
|
14
|
+
* controls operate over a running system — no markdown file evidences "the entity
|
|
15
|
+
* monitors system components for anomalies". Reporting design-intent prose as
|
|
16
|
+
* evidence of an operating control is the overclaim this feature exists to prevent,
|
|
17
|
+
* and it would happen in precisely the document least able to survive it.
|
|
18
|
+
*
|
|
19
|
+
* **Absence is reported by name.** A control with no evidence appears as absent, not
|
|
20
|
+
* omitted. A report that silently drops what it could not find reads as a clean bill
|
|
21
|
+
* of health.
|
|
22
|
+
*
|
|
23
|
+
* **The unreviewed-draft notice is emitted from code.** Not copied from pack text: a
|
|
24
|
+
* notice living only in an installed file can be edited away permanently, because a
|
|
25
|
+
* locally edited layer is preserved forever by design.
|
|
26
|
+
*
|
|
27
|
+
* Read-only. Writes nothing under `.aidlc/`, and reads only from an allowlist.
|
|
28
|
+
*
|
|
29
|
+
* Requirements: compliance-packs/AC-30, AC-32, AC-33, AC-34, AC-59, AC-60, AC-61,
|
|
30
|
+
* AC-83, AC-84, AC-85, AC-90, AC-107
|
|
31
|
+
*/
|
|
32
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
33
|
+
import { homedir } from 'node:os';
|
|
34
|
+
import { join } from 'node:path';
|
|
35
|
+
import { toPosixRelative } from '../core/paths.js';
|
|
36
|
+
import { completionInfo, loadAllTemplates, loadInstance } from '../metrics/report.js';
|
|
37
|
+
import { readComplianceConfig } from './config.js';
|
|
38
|
+
import { complianceFindingsFilename, parseComplianceFindings } from './findings.js';
|
|
39
|
+
import { resolvePack } from './resolver.js';
|
|
40
|
+
/**
|
|
41
|
+
* Whether a path is one the report is permitted to read.
|
|
42
|
+
*
|
|
43
|
+
* Exported so a test can assert against the same predicate the module documents,
|
|
44
|
+
* rather than a re-typed copy of it that could drift.
|
|
45
|
+
*/
|
|
46
|
+
export function isAllowedReadPath(projectRoot, path) {
|
|
47
|
+
const rel = toPosixRelative(projectRoot, path);
|
|
48
|
+
if (rel === '.aidlc/config.yaml')
|
|
49
|
+
return true;
|
|
50
|
+
// Instance state: the metadata, the phase files, the transitions log, the
|
|
51
|
+
// compliance findings, the review findings, and the artifacts a control names.
|
|
52
|
+
if (/^\.aidlc\/state\/[^/]+\/(instance\.yaml|transitions\.log)$/.test(rel))
|
|
53
|
+
return true;
|
|
54
|
+
if (/^\.aidlc\/state\/[^/]+\/phase-[a-z-]+\.yaml$/.test(rel))
|
|
55
|
+
return true;
|
|
56
|
+
if (/^\.aidlc\/state\/[^/]+\/.+\.compliance\.md$/.test(rel))
|
|
57
|
+
return true;
|
|
58
|
+
if (/^\.aidlc\/state\/[^/]+\/.+\.review\.md$/.test(rel))
|
|
59
|
+
return true;
|
|
60
|
+
if (/^\.aidlc\/state\/[^/]+\/[A-Za-z0-9._-]+\.md$/.test(rel))
|
|
61
|
+
return true;
|
|
62
|
+
// Custom templates participate in resolving a completion moment.
|
|
63
|
+
if (/^\.aidlc\/templates\/[^/]+$/.test(rel))
|
|
64
|
+
return true;
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The notice text, emitted from code for any pack whose control text is unreviewed.
|
|
69
|
+
*
|
|
70
|
+
* One of the notice's three enforcement points. The others are pack-source validation
|
|
71
|
+
* and a doctor check for the case where someone edits it out of an installed layer.
|
|
72
|
+
*/
|
|
73
|
+
export function unreviewedNoticeFor(meta) {
|
|
74
|
+
if (meta.reviewed_by !== null)
|
|
75
|
+
return null;
|
|
76
|
+
return (`The control text in the ${meta.regime} pack has not been reviewed by a compliance ` +
|
|
77
|
+
`practitioner. It is a working draft. This report describes what the lifecycle trail ` +
|
|
78
|
+
`records; it is not an assessment of whether your controls are adequate, and it does ` +
|
|
79
|
+
`not make this project certified or attested.`);
|
|
80
|
+
}
|
|
81
|
+
/** The sentence stating what a checked-only control does and does not establish. */
|
|
82
|
+
export function checkedOnlyCaveat(controlId) {
|
|
83
|
+
return (`${controlId} is checked, not evidenced: the trail records that the check was ` +
|
|
84
|
+
`performed, never that the control operates. Do not present this as evidence.`);
|
|
85
|
+
}
|
|
86
|
+
/** Instance directories under `.aidlc/state/`. */
|
|
87
|
+
function instanceNames(projectRoot) {
|
|
88
|
+
const stateDir = join(projectRoot, '.aidlc', 'state');
|
|
89
|
+
if (!existsSync(stateDir))
|
|
90
|
+
return [];
|
|
91
|
+
try {
|
|
92
|
+
return readdirSync(stateDir, { withFileTypes: true })
|
|
93
|
+
.filter((e) => e.isDirectory())
|
|
94
|
+
.map((e) => e.name)
|
|
95
|
+
.sort();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Decide which instances the report covers.
|
|
103
|
+
*
|
|
104
|
+
* Default scope is every instance whose completion moment falls at or after the
|
|
105
|
+
* earliest pack install. `completionInfo` from the metrics module is the single
|
|
106
|
+
* implementation of "when did this instance complete" — scope-aware, and handling the
|
|
107
|
+
* maintenance-terminal case. Re-deriving it here would give two answers differing on
|
|
108
|
+
* exactly that case, inside a document whose value is that it can be handed over.
|
|
109
|
+
*/
|
|
110
|
+
function selectInstances(projectRoot, packs, opts) {
|
|
111
|
+
const templates = loadAllTemplates(projectRoot);
|
|
112
|
+
const earliestInstall = packs
|
|
113
|
+
.map((p) => p.installed_at)
|
|
114
|
+
.sort()
|
|
115
|
+
.at(0);
|
|
116
|
+
const since = opts.since ?? earliestInstall ?? null;
|
|
117
|
+
const included = [];
|
|
118
|
+
const excluded = [];
|
|
119
|
+
for (const name of instanceNames(projectRoot)) {
|
|
120
|
+
if (opts.instance !== undefined && name !== opts.instance) {
|
|
121
|
+
excluded.push({ instance: name, reason: 'filtered', detail: `not --instance ${opts.instance}` });
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const inst = loadInstance(projectRoot, name);
|
|
125
|
+
if (inst === null) {
|
|
126
|
+
excluded.push({ instance: name, reason: 'not-complete', detail: 'no readable instance state' });
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const info = completionInfo(inst, templates);
|
|
130
|
+
if (!info.completed) {
|
|
131
|
+
excluded.push({ instance: name, reason: 'not-complete', detail: 'still in progress' });
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
// A pack cannot evidence a change that predates it. Excluded, and said out loud —
|
|
135
|
+
// the same principle absent evidence gets, applied to instances.
|
|
136
|
+
if (since !== null && info.completedAt !== null && info.completedAt < since) {
|
|
137
|
+
excluded.push({
|
|
138
|
+
instance: name,
|
|
139
|
+
reason: 'predates-pack',
|
|
140
|
+
detail: `completed ${info.completedAt}, before ${since}`,
|
|
141
|
+
});
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
included.push(name);
|
|
145
|
+
}
|
|
146
|
+
return { included, excluded };
|
|
147
|
+
}
|
|
148
|
+
/** Compliance findings files for one instance, keyed by artifact. */
|
|
149
|
+
function findingsFor(projectRoot, instance, onRead) {
|
|
150
|
+
const byArtifact = new Map();
|
|
151
|
+
const warnings = [];
|
|
152
|
+
const dir = join(projectRoot, '.aidlc', 'state', instance);
|
|
153
|
+
let entries;
|
|
154
|
+
try {
|
|
155
|
+
entries = readdirSync(dir);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return { byArtifact, warnings };
|
|
159
|
+
}
|
|
160
|
+
for (const entry of entries.filter((f) => f.endsWith('.compliance.md')).sort()) {
|
|
161
|
+
const artifact = entry.replace('.compliance.md', '');
|
|
162
|
+
try {
|
|
163
|
+
const path = join(dir, entry);
|
|
164
|
+
onRead?.(path);
|
|
165
|
+
byArtifact.set(artifact, parseComplianceFindings(readFileSync(path, 'utf8')));
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
warnings.push(`${instance}/${entry} is unreadable (${err.message})`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return { byArtifact, warnings };
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Build the report.
|
|
175
|
+
*
|
|
176
|
+
* Reads only: `.aidlc/config.yaml`, each in-scope instance's `instance.yaml` and
|
|
177
|
+
* `phase-*.yaml`, its compliance findings files, and the pack sources through the
|
|
178
|
+
* resolver. Creates and writes nothing.
|
|
179
|
+
*/
|
|
180
|
+
export function computeComplianceReport(projectRoot, opts = {}) {
|
|
181
|
+
const now = opts.now ?? new Date();
|
|
182
|
+
opts.onRead?.(join(projectRoot, '.aidlc', 'config.yaml'));
|
|
183
|
+
const config = readComplianceConfig(projectRoot);
|
|
184
|
+
const warnings = [];
|
|
185
|
+
const { included, excluded } = selectInstances(projectRoot, config.packs, opts);
|
|
186
|
+
// Findings, gathered once per in-scope instance.
|
|
187
|
+
const perInstance = new Map();
|
|
188
|
+
for (const instance of included) {
|
|
189
|
+
const gathered = findingsFor(projectRoot, instance, opts.onRead);
|
|
190
|
+
warnings.push(...gathered.warnings);
|
|
191
|
+
perInstance.set(instance, gathered);
|
|
192
|
+
}
|
|
193
|
+
const packs = [];
|
|
194
|
+
for (const record of config.packs) {
|
|
195
|
+
const resolved = resolvePack(record.id);
|
|
196
|
+
if (!resolved.ok) {
|
|
197
|
+
warnings.push(`installed pack '${record.id}' did not load: ${resolved.error.errors.join('; ')}`);
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
const pack = resolved.pack;
|
|
201
|
+
const controls = pack.controls.map((control) => {
|
|
202
|
+
const findings = [];
|
|
203
|
+
const clearedIn = [];
|
|
204
|
+
let evidenceFound = false;
|
|
205
|
+
for (const [instance, gathered] of perInstance) {
|
|
206
|
+
for (const [artifact, file] of gathered.byArtifact) {
|
|
207
|
+
for (const finding of file.findings) {
|
|
208
|
+
if (finding.control !== control.id)
|
|
209
|
+
continue;
|
|
210
|
+
findings.push({
|
|
211
|
+
id: finding.id,
|
|
212
|
+
severity: finding.severity,
|
|
213
|
+
status: finding.status,
|
|
214
|
+
// Rendered by the one path helper, so nothing absolute reaches the report.
|
|
215
|
+
source: toPosixRelative(projectRoot, join(projectRoot, '.aidlc', 'state', instance, complianceFindingsFilename(artifact))),
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
if (file.cleared.includes(control.id)) {
|
|
219
|
+
clearedIn.push(`${instance}/${artifact}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Evidence, for an evidenced control only: does the named artifact exist in
|
|
223
|
+
// this instance? That is the whole of what the trail can show.
|
|
224
|
+
if (control.kind === 'evidenced' && control.evidence_artifact !== undefined) {
|
|
225
|
+
const artifactPath = join(projectRoot, '.aidlc', 'state', instance, control.evidence_artifact);
|
|
226
|
+
opts.onRead?.(artifactPath);
|
|
227
|
+
if (existsSync(artifactPath))
|
|
228
|
+
evidenceFound = true;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const row = {
|
|
232
|
+
packId: record.id,
|
|
233
|
+
control: control.id,
|
|
234
|
+
kind: control.kind,
|
|
235
|
+
requires: control.requires,
|
|
236
|
+
findings,
|
|
237
|
+
clearedIn,
|
|
238
|
+
};
|
|
239
|
+
// The kind distinction, enforced structurally rather than by convention: the
|
|
240
|
+
// evidence fields are only ever set on an evidenced control.
|
|
241
|
+
if (control.kind === 'evidenced' && control.evidence_artifact !== undefined) {
|
|
242
|
+
row.evidenceArtifact = control.evidence_artifact;
|
|
243
|
+
row.evidenceFound = evidenceFound;
|
|
244
|
+
}
|
|
245
|
+
return row;
|
|
246
|
+
});
|
|
247
|
+
packs.push({
|
|
248
|
+
meta: pack.meta,
|
|
249
|
+
unreviewedNotice: unreviewedNoticeFor(pack.meta),
|
|
250
|
+
controls,
|
|
251
|
+
exclusions: pack.exclusions.map((e) => ({
|
|
252
|
+
id: e.id,
|
|
253
|
+
reason: e.reason,
|
|
254
|
+
...(e.note !== undefined && { note: e.note }),
|
|
255
|
+
})),
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
generatedAt: now.toISOString(),
|
|
260
|
+
instances: included,
|
|
261
|
+
excluded,
|
|
262
|
+
packs,
|
|
263
|
+
warnings,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Render the report as markdown.
|
|
268
|
+
*
|
|
269
|
+
* Every path is already repo-relative by construction. A final assertion checks the
|
|
270
|
+
* home directory does not appear, because that is the decidable form of the guarantee
|
|
271
|
+
* and it does not depend on secret redaction — the redaction helper explicitly does
|
|
272
|
+
* not classify paths as secrets.
|
|
273
|
+
*/
|
|
274
|
+
export function renderComplianceReport(report) {
|
|
275
|
+
const out = [];
|
|
276
|
+
out.push('# Compliance evidence report', '');
|
|
277
|
+
out.push(`Generated ${report.generatedAt}`, '');
|
|
278
|
+
if (report.packs.length === 0) {
|
|
279
|
+
out.push('No compliance pack is installed, so there is nothing to report.', '');
|
|
280
|
+
return out.join('\n');
|
|
281
|
+
}
|
|
282
|
+
for (const pack of report.packs) {
|
|
283
|
+
out.push(`## ${pack.meta.regime} (pack \`${pack.meta.id}\` ${pack.meta.version})`, '');
|
|
284
|
+
if (pack.unreviewedNotice !== null) {
|
|
285
|
+
out.push(`> **${pack.unreviewedNotice}**`, '');
|
|
286
|
+
}
|
|
287
|
+
out.push('### Controls covered', '');
|
|
288
|
+
for (const row of pack.controls) {
|
|
289
|
+
out.push(`#### ${row.control} — ${row.kind}`, '');
|
|
290
|
+
out.push(`- Requires: ${row.requires}`);
|
|
291
|
+
if (row.kind === 'evidenced') {
|
|
292
|
+
out.push(`- Evidence artifact: \`${row.evidenceArtifact}\``);
|
|
293
|
+
out.push(row.evidenceFound === true
|
|
294
|
+
? '- Evidence found: yes'
|
|
295
|
+
: '- Evidence found: **no — absent for every in-scope instance**');
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
out.push(`- ${checkedOnlyCaveat(row.control)}`);
|
|
299
|
+
}
|
|
300
|
+
if (row.clearedIn.length > 0) {
|
|
301
|
+
out.push(`- Checked with no issue in: ${row.clearedIn.join(', ')}`);
|
|
302
|
+
}
|
|
303
|
+
if (row.findings.length > 0) {
|
|
304
|
+
out.push('- Findings:');
|
|
305
|
+
for (const finding of row.findings) {
|
|
306
|
+
out.push(` - ${finding.id} (${finding.severity}, ${finding.status}) — \`${finding.source}\``);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (row.clearedIn.length === 0 && row.findings.length === 0) {
|
|
310
|
+
out.push('- Not checked in any in-scope instance');
|
|
311
|
+
}
|
|
312
|
+
out.push('');
|
|
313
|
+
}
|
|
314
|
+
out.push('### Criteria this pack does not cover', '');
|
|
315
|
+
for (const exclusion of pack.exclusions) {
|
|
316
|
+
out.push(`- ${exclusion.id} — ${exclusion.reason}${exclusion.note ? `: ${exclusion.note}` : ''}`);
|
|
317
|
+
}
|
|
318
|
+
out.push('');
|
|
319
|
+
}
|
|
320
|
+
out.push('## Scope', '');
|
|
321
|
+
out.push(report.instances.length > 0
|
|
322
|
+
? `Instances covered: ${report.instances.join(', ')}`
|
|
323
|
+
: 'No completed instance falls within the pack install window.');
|
|
324
|
+
out.push('');
|
|
325
|
+
if (report.excluded.length > 0) {
|
|
326
|
+
out.push('Instances excluded, with the reason:', '');
|
|
327
|
+
for (const item of report.excluded) {
|
|
328
|
+
out.push(`- ${item.instance} — ${item.reason}: ${item.detail}`);
|
|
329
|
+
}
|
|
330
|
+
out.push('');
|
|
331
|
+
}
|
|
332
|
+
if (report.warnings.length > 0) {
|
|
333
|
+
out.push('## Warnings', '');
|
|
334
|
+
for (const warning of report.warnings)
|
|
335
|
+
out.push(`- ${warning}`);
|
|
336
|
+
out.push('');
|
|
337
|
+
}
|
|
338
|
+
const rendered = out.join('\n');
|
|
339
|
+
// Defence in depth on the guarantee that matters most in a document meant to leave
|
|
340
|
+
// this machine. Throwing is right: emitting the path would be worse than failing.
|
|
341
|
+
const home = homedir();
|
|
342
|
+
if (home.length > 1 && rendered.includes(home)) {
|
|
343
|
+
throw new Error('compliance report contained an absolute home-directory path — refusing to emit it');
|
|
344
|
+
}
|
|
345
|
+
return rendered;
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/compliance/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pack resolution — the only module that reads pack sources.
|
|
3
|
+
*
|
|
4
|
+
* Every other part of the feature (install, review, gate, check, report) goes
|
|
5
|
+
* through `listPacks` and `resolvePack` and never builds a path into a pack
|
|
6
|
+
* directory itself. That is what makes adding a licensed pack later a change to
|
|
7
|
+
* this file rather than a change to how everything loads, and it is asserted at
|
|
8
|
+
* source level rather than left as an intention.
|
|
9
|
+
*
|
|
10
|
+
* **Packs come only from the content package in this release.** A pack's control
|
|
11
|
+
* text becomes instructions an agent executes during review, so the pack source is
|
|
12
|
+
* a trust boundary of the same kind `security/action-trust.ts` was built for: in a
|
|
13
|
+
* cloned repository, a project-local file's contents are the repo author's. A
|
|
14
|
+
* `.aidlc/packs/` directory is therefore not enumerated and cannot be installed.
|
|
15
|
+
* Admitting a non-bundled source later needs a trust decision, not just a code
|
|
16
|
+
* path.
|
|
17
|
+
*
|
|
18
|
+
* **A pack id from the command line is matched, never joined.** `resolvePack`
|
|
19
|
+
* compares the requested id against the enumerated set before any path is built
|
|
20
|
+
* from it, so `aidlc compliance add ../../etc` takes the unknown-pack exit rather
|
|
21
|
+
* than reaching the filesystem.
|
|
22
|
+
*
|
|
23
|
+
* Requirements: compliance-packs/AC-8, AC-16, AC-47, AC-53, AC-64, AC-66, AC-67, AC-99
|
|
24
|
+
*/
|
|
25
|
+
import type { Pack, PackError, PackMeta, PackResult } from './types.js';
|
|
26
|
+
/**
|
|
27
|
+
* Absolute path of the bundled packs directory.
|
|
28
|
+
*
|
|
29
|
+
* The single place a pack path originates. Exported for tests and for the
|
|
30
|
+
* publish-reachability assertion, not for callers wanting to read a pack.
|
|
31
|
+
*/
|
|
32
|
+
export declare function packsRoot(): string;
|
|
33
|
+
/**
|
|
34
|
+
* Resolve one pack by id.
|
|
35
|
+
*
|
|
36
|
+
* The id is matched against the enumerated set **before** any path is built from
|
|
37
|
+
* it, so a traversal-shaped argument is an unknown pack rather than a filesystem
|
|
38
|
+
* read. Never returns null: an absent pack carries a reason.
|
|
39
|
+
*/
|
|
40
|
+
export declare function resolvePack(id: string): PackResult;
|
|
41
|
+
/** Outcome of enumerating the available packs. */
|
|
42
|
+
export interface PackListing {
|
|
43
|
+
/** Packs that resolved. */
|
|
44
|
+
packs: PackMeta[];
|
|
45
|
+
/**
|
|
46
|
+
* Packs that exist but did not resolve. Listed rather than hidden: a pack that
|
|
47
|
+
* is present and broken is a different situation from one that is absent, and
|
|
48
|
+
* silently dropping it is how a shipping defect stays invisible.
|
|
49
|
+
*/
|
|
50
|
+
errors: PackError[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Enumerate every available pack.
|
|
54
|
+
*
|
|
55
|
+
* Reads the content package only. Takes no project root, so there is no parameter
|
|
56
|
+
* through which a project-local pack could be offered.
|
|
57
|
+
*/
|
|
58
|
+
export declare function listPacks(): PackListing;
|
|
59
|
+
/**
|
|
60
|
+
* Every pack id available, for exact-match validation of a command argument.
|
|
61
|
+
*/
|
|
62
|
+
export declare function availablePackIds(): string[];
|
|
63
|
+
/** Resolve a pack and return only its controls, for the phases given. */
|
|
64
|
+
export declare function controlsForPhase(pack: Pack, phase: string): import("./types.js").Control[];
|
|
65
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/compliance/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAQH,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAUxE;;;;;GAKG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AA4ED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,CAmBlD;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,2BAA2B;IAC3B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB;;;;OAIG;IACH,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,IAAI,WAAW,CAcvC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,kCAEzD"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pack resolution — the only module that reads pack sources.
|
|
3
|
+
*
|
|
4
|
+
* Every other part of the feature (install, review, gate, check, report) goes
|
|
5
|
+
* through `listPacks` and `resolvePack` and never builds a path into a pack
|
|
6
|
+
* directory itself. That is what makes adding a licensed pack later a change to
|
|
7
|
+
* this file rather than a change to how everything loads, and it is asserted at
|
|
8
|
+
* source level rather than left as an intention.
|
|
9
|
+
*
|
|
10
|
+
* **Packs come only from the content package in this release.** A pack's control
|
|
11
|
+
* text becomes instructions an agent executes during review, so the pack source is
|
|
12
|
+
* a trust boundary of the same kind `security/action-trust.ts` was built for: in a
|
|
13
|
+
* cloned repository, a project-local file's contents are the repo author's. A
|
|
14
|
+
* `.aidlc/packs/` directory is therefore not enumerated and cannot be installed.
|
|
15
|
+
* Admitting a non-bundled source later needs a trust decision, not just a code
|
|
16
|
+
* path.
|
|
17
|
+
*
|
|
18
|
+
* **A pack id from the command line is matched, never joined.** `resolvePack`
|
|
19
|
+
* compares the requested id against the enumerated set before any path is built
|
|
20
|
+
* from it, so `aidlc compliance add ../../etc` takes the unknown-pack exit rather
|
|
21
|
+
* than reaching the filesystem.
|
|
22
|
+
*
|
|
23
|
+
* Requirements: compliance-packs/AC-8, AC-16, AC-47, AC-53, AC-64, AC-66, AC-67, AC-99
|
|
24
|
+
*/
|
|
25
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
26
|
+
import { join } from 'node:path';
|
|
27
|
+
import { getContentPackageRoot } from '../compile/content-root.js';
|
|
28
|
+
import { isContainedRelative } from '../compile/layer-install.js';
|
|
29
|
+
import { validatePack } from './schema.js';
|
|
30
|
+
/** Pack slugs: lowercase alphanumeric with interior hyphens. */
|
|
31
|
+
const SLUG_RE = /^[a-z][a-z0-9-]*$/;
|
|
32
|
+
/** Filenames a pack must contain. */
|
|
33
|
+
const PACK_FILE = 'pack.yaml';
|
|
34
|
+
const CONTROLS_FILE = 'controls.yaml';
|
|
35
|
+
const GUIDANCE_DIR = 'guidance';
|
|
36
|
+
/**
|
|
37
|
+
* Absolute path of the bundled packs directory.
|
|
38
|
+
*
|
|
39
|
+
* The single place a pack path originates. Exported for tests and for the
|
|
40
|
+
* publish-reachability assertion, not for callers wanting to read a pack.
|
|
41
|
+
*/
|
|
42
|
+
export function packsRoot() {
|
|
43
|
+
return join(getContentPackageRoot(), 'packs');
|
|
44
|
+
}
|
|
45
|
+
/** Directory names under `packs/` that contain a `pack.yaml`. */
|
|
46
|
+
function packDirs() {
|
|
47
|
+
const root = packsRoot();
|
|
48
|
+
if (!existsSync(root))
|
|
49
|
+
return [];
|
|
50
|
+
const out = [];
|
|
51
|
+
for (const name of readdirSync(root).sort()) {
|
|
52
|
+
// The directory name is the pack id, so it has to satisfy the id rule before
|
|
53
|
+
// it is joined — a stray file or an oddly named directory is not a pack.
|
|
54
|
+
if (!SLUG_RE.test(name))
|
|
55
|
+
continue;
|
|
56
|
+
const dir = join(root, name);
|
|
57
|
+
try {
|
|
58
|
+
if (statSync(dir).isDirectory() && existsSync(join(dir, PACK_FILE))) {
|
|
59
|
+
out.push(name);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Unreadable entry — not a pack. Reported by `resolvePack` if asked for.
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
/** Read a pack's raw sources, or explain why it could not be read. */
|
|
69
|
+
function readSources(id) {
|
|
70
|
+
const dir = join(packsRoot(), id);
|
|
71
|
+
const packYamlPath = join(dir, PACK_FILE);
|
|
72
|
+
const controlsPath = join(dir, CONTROLS_FILE);
|
|
73
|
+
let packYaml;
|
|
74
|
+
let controlsYaml;
|
|
75
|
+
try {
|
|
76
|
+
packYaml = readFileSync(packYamlPath, 'utf8');
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return {
|
|
80
|
+
ok: false,
|
|
81
|
+
error: { code: 'unreadable', id, path: `packs/${id}/${PACK_FILE}`, errors: [`${PACK_FILE} is unreadable`] },
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
controlsYaml = readFileSync(controlsPath, 'utf8');
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return {
|
|
89
|
+
ok: false,
|
|
90
|
+
error: {
|
|
91
|
+
code: 'unreadable',
|
|
92
|
+
id,
|
|
93
|
+
path: `packs/${id}/${CONTROLS_FILE}`,
|
|
94
|
+
errors: [`${CONTROLS_FILE} is unreadable`],
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// Layer bodies. The registration list lives inside `pack.yaml`, which is not
|
|
99
|
+
// parsed yet, so every readable file in the pack's guidance directory is
|
|
100
|
+
// offered and the validator decides which are registered. Containment is
|
|
101
|
+
// checked with the one exported helper rather than a second implementation.
|
|
102
|
+
const layerBodies = new Map();
|
|
103
|
+
const guidanceDir = join(dir, GUIDANCE_DIR);
|
|
104
|
+
if (existsSync(guidanceDir)) {
|
|
105
|
+
for (const name of readdirSync(guidanceDir).sort()) {
|
|
106
|
+
if (!isContainedRelative(guidanceDir, name))
|
|
107
|
+
continue;
|
|
108
|
+
const full = join(guidanceDir, name);
|
|
109
|
+
try {
|
|
110
|
+
if (statSync(full).isFile())
|
|
111
|
+
layerBodies.set(name, readFileSync(full, 'utf8'));
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// Unreadable layer file — surfaces as a missing-body validation error.
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return { ok: true, sources: { id, packYaml, controlsYaml, layerBodies } };
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Resolve one pack by id.
|
|
122
|
+
*
|
|
123
|
+
* The id is matched against the enumerated set **before** any path is built from
|
|
124
|
+
* it, so a traversal-shaped argument is an unknown pack rather than a filesystem
|
|
125
|
+
* read. Never returns null: an absent pack carries a reason.
|
|
126
|
+
*/
|
|
127
|
+
export function resolvePack(id) {
|
|
128
|
+
if (!SLUG_RE.test(id)) {
|
|
129
|
+
return { ok: false, error: { code: 'not-found', id, errors: [`'${id}' is not a pack id`] } };
|
|
130
|
+
}
|
|
131
|
+
if (!packDirs().includes(id)) {
|
|
132
|
+
return { ok: false, error: { code: 'not-found', id, errors: [`no pack named '${id}'`] } };
|
|
133
|
+
}
|
|
134
|
+
const read = readSources(id);
|
|
135
|
+
if (!read.ok)
|
|
136
|
+
return { ok: false, error: read.error };
|
|
137
|
+
const validation = validatePack(read.sources);
|
|
138
|
+
if (!validation.ok) {
|
|
139
|
+
return {
|
|
140
|
+
ok: false,
|
|
141
|
+
error: { code: 'invalid', id, path: `packs/${id}`, errors: validation.errors },
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
return { ok: true, pack: validation.pack };
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Enumerate every available pack.
|
|
148
|
+
*
|
|
149
|
+
* Reads the content package only. Takes no project root, so there is no parameter
|
|
150
|
+
* through which a project-local pack could be offered.
|
|
151
|
+
*/
|
|
152
|
+
export function listPacks() {
|
|
153
|
+
const packs = [];
|
|
154
|
+
const errors = [];
|
|
155
|
+
for (const id of packDirs()) {
|
|
156
|
+
const result = resolvePack(id);
|
|
157
|
+
if (result.ok) {
|
|
158
|
+
packs.push(result.pack.meta);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
errors.push(result.error);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return { packs, errors };
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Every pack id available, for exact-match validation of a command argument.
|
|
168
|
+
*/
|
|
169
|
+
export function availablePackIds() {
|
|
170
|
+
return packDirs();
|
|
171
|
+
}
|
|
172
|
+
/** Resolve a pack and return only its controls, for the phases given. */
|
|
173
|
+
export function controlsForPhase(pack, phase) {
|
|
174
|
+
return pack.controls.filter((c) => c.phases.includes(phase));
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/compliance/resolver.ts"],"names":[],"mappings":"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"}
|