verification-layer 0.27.13 → 0.28.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 (68) hide show
  1. package/COMPLIANCE_DELIVERY.md +161 -0
  2. package/dist/acknowledgments.d.ts +1 -1
  3. package/dist/acknowledgments.d.ts.map +1 -1
  4. package/dist/acknowledgments.js +29 -11
  5. package/dist/acknowledgments.js.map +1 -1
  6. package/dist/baseline.d.ts +50 -12
  7. package/dist/baseline.d.ts.map +1 -1
  8. package/dist/baseline.js +165 -23
  9. package/dist/baseline.js.map +1 -1
  10. package/dist/delivery/diff.d.ts +10 -0
  11. package/dist/delivery/diff.d.ts.map +1 -0
  12. package/dist/delivery/diff.js +41 -0
  13. package/dist/delivery/diff.js.map +1 -0
  14. package/dist/delivery/evidence.d.ts +11 -0
  15. package/dist/delivery/evidence.d.ts.map +1 -0
  16. package/dist/delivery/evidence.js +87 -0
  17. package/dist/delivery/evidence.js.map +1 -0
  18. package/dist/delivery/git.d.ts +8 -0
  19. package/dist/delivery/git.d.ts.map +1 -0
  20. package/dist/delivery/git.js +98 -0
  21. package/dist/delivery/git.js.map +1 -0
  22. package/dist/delivery/governance.d.ts +23 -0
  23. package/dist/delivery/governance.d.ts.map +1 -0
  24. package/dist/delivery/governance.js +118 -0
  25. package/dist/delivery/governance.js.map +1 -0
  26. package/dist/delivery/graph.d.ts +11 -0
  27. package/dist/delivery/graph.d.ts.map +1 -0
  28. package/dist/delivery/graph.js +130 -0
  29. package/dist/delivery/graph.js.map +1 -0
  30. package/dist/delivery/index.d.ts +14 -0
  31. package/dist/delivery/index.d.ts.map +1 -0
  32. package/dist/delivery/index.js +10 -0
  33. package/dist/delivery/index.js.map +1 -0
  34. package/dist/delivery/policy.d.ts +13 -0
  35. package/dist/delivery/policy.d.ts.map +1 -0
  36. package/dist/delivery/policy.js +100 -0
  37. package/dist/delivery/policy.js.map +1 -0
  38. package/dist/delivery/remediation.d.ts +9 -0
  39. package/dist/delivery/remediation.d.ts.map +1 -0
  40. package/dist/delivery/remediation.js +60 -0
  41. package/dist/delivery/remediation.js.map +1 -0
  42. package/dist/delivery/runner.d.ts +26 -0
  43. package/dist/delivery/runner.d.ts.map +1 -0
  44. package/dist/delivery/runner.js +79 -0
  45. package/dist/delivery/runner.js.map +1 -0
  46. package/dist/delivery/types.d.ts +156 -0
  47. package/dist/delivery/types.d.ts.map +1 -0
  48. package/dist/delivery/types.js +2 -0
  49. package/dist/delivery/types.js.map +1 -0
  50. package/dist/delivery/upload.d.ts +20 -0
  51. package/dist/delivery/upload.d.ts.map +1 -0
  52. package/dist/delivery/upload.js +72 -0
  53. package/dist/delivery/upload.js.map +1 -0
  54. package/dist/delivery-cli.d.ts +3 -0
  55. package/dist/delivery-cli.d.ts.map +1 -0
  56. package/dist/delivery-cli.js +306 -0
  57. package/dist/delivery-cli.js.map +1 -0
  58. package/dist/delivery-upload-cli.d.ts +3 -0
  59. package/dist/delivery-upload-cli.d.ts.map +1 -0
  60. package/dist/delivery-upload-cli.js +37 -0
  61. package/dist/delivery-upload-cli.js.map +1 -0
  62. package/dist/index.d.ts +2 -1
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +2 -1
  65. package/dist/index.js.map +1 -1
  66. package/dist/rule-catalog.json +1 -1
  67. package/package.json +15 -9
  68. package/templates/github-actions/compliance-gate.yml +61 -0
@@ -0,0 +1,306 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { readFile, writeFile } from 'fs/promises';
5
+ import { resolve } from 'path';
6
+ import { applyFixes } from './fixer/index.js';
7
+ import { buildComplianceGraph, buildEvidencePackage, buildRemediationPlan, getAcknowledgmentLifecycle, graphToMermaid, remediationToMarkdown, runComplianceGuard, saveEvidencePackage, verifyEvidencePackage, } from './delivery/index.js';
8
+ function addCommonOptions(command) {
9
+ return command
10
+ .option('--baseline <path>', 'Baseline file (default: .vlayer-baseline.json when present)')
11
+ .option('--config <path>', 'Scanner configuration file')
12
+ .option('--policy <path>', 'Delivery policy JSON file')
13
+ .option('--base <ref>', 'Git base branch, tag, or SHA')
14
+ .option('--head <ref>', 'Git head branch, tag, or SHA', 'HEAD')
15
+ .option('--all-files', 'Evaluate all new findings instead of changed files only')
16
+ .option('--ai', 'Enable AI triage for this gate (off by default for deterministic CI)')
17
+ .option('--min-confidence <level>', 'Minimum confidence: high, medium, low');
18
+ }
19
+ async function executeGuard(path, options) {
20
+ return runComplianceGuard({
21
+ path,
22
+ baselineFile: options.baseline,
23
+ configFile: options.config,
24
+ policyFile: options.policy,
25
+ baseRef: options.base,
26
+ headRef: options.head,
27
+ changedFilesOnly: options.allFiles ? false : undefined,
28
+ enableAI: options.ai === true,
29
+ minConfidence: options.minConfidence,
30
+ });
31
+ }
32
+ function guardJson(guard) {
33
+ return {
34
+ schemaVersion: '1.0',
35
+ generatedAt: new Date().toISOString(),
36
+ source: guard.git,
37
+ baseline: {
38
+ loaded: guard.baselineLoaded,
39
+ path: guard.baselinePath,
40
+ },
41
+ policySource: guard.policySource,
42
+ decision: guard.decision,
43
+ summary: {
44
+ scannedFiles: guard.scannedFiles,
45
+ complianceScore: guard.complianceScore,
46
+ newFindings: guard.delta.newFindings.length,
47
+ newFindingsInChangedFiles: guard.delta.newFindingsInChangedFiles.length,
48
+ baselineFindings: guard.delta.baselineFindings.length,
49
+ resolvedFindings: guard.delta.resolvedFindings.length,
50
+ expiredAcknowledgments: guard.acknowledgmentLifecycle.expired.length,
51
+ },
52
+ newFindings: guard.delta.newFindings.map(finding => ({
53
+ id: finding.id,
54
+ severity: finding.severity,
55
+ title: finding.title,
56
+ file: finding.file,
57
+ line: finding.line,
58
+ recommendation: finding.recommendation,
59
+ hipaaReference: finding.hipaaReference,
60
+ fixType: finding.fixType,
61
+ })),
62
+ resolvedFindings: guard.delta.resolvedFindings,
63
+ };
64
+ }
65
+ function printDecision(guard) {
66
+ const decision = guard.decision;
67
+ console.log('');
68
+ console.log(decision.deployAllowed
69
+ ? chalk.green.bold('DEPLOYMENT APPROVED')
70
+ : chalk.red.bold('DEPLOYMENT BLOCKED'));
71
+ console.log(chalk.gray(`Scope: ${decision.consideredScope}`));
72
+ if (guard.git.headSha)
73
+ console.log(chalk.gray(`Head: ${guard.git.headSha}`));
74
+ if (guard.git.baseSha)
75
+ console.log(chalk.gray(`Base: ${guard.git.baseSha}`));
76
+ console.log(chalk.gray(`Changed files: ${guard.git.changedFiles.length}`));
77
+ console.log(`Compliance score: ${guard.complianceScore ?? 'N/A'}`);
78
+ console.log(`New findings: ${guard.delta.newFindings.length}`);
79
+ console.log(`New in changed files: ${guard.delta.newFindingsInChangedFiles.length}`);
80
+ console.log(`Resolved: ${guard.delta.resolvedFindings.length}`);
81
+ console.log(`Baseline debt: ${guard.delta.baselineFindings.length}`);
82
+ if (decision.reasons.length > 0) {
83
+ console.log(chalk.bold('\nPolicy reasons:'));
84
+ for (const reason of decision.reasons) {
85
+ console.log(chalk.red(` - ${reason.message}`));
86
+ }
87
+ }
88
+ const soon = guard.acknowledgmentLifecycle.expiringSoon.length;
89
+ if (soon > 0) {
90
+ console.log(chalk.yellow(`\n${soon} acknowledgment${soon === 1 ? '' : 's'} expire within 30 days.`));
91
+ }
92
+ }
93
+ async function appendGithubSummary(guard) {
94
+ const summaryFile = process.env.GITHUB_STEP_SUMMARY;
95
+ if (!summaryFile)
96
+ return;
97
+ const lines = [
98
+ '## vlayer compliance delivery gate',
99
+ '',
100
+ `**Decision:** ${guard.decision.deployAllowed ? 'PASS' : 'FAIL'}`,
101
+ '',
102
+ '| Metric | Value |',
103
+ '|---|---:|',
104
+ `| Compliance score | ${guard.complianceScore ?? 'N/A'} |`,
105
+ `| New findings | ${guard.delta.newFindings.length} |`,
106
+ `| New in changed files | ${guard.delta.newFindingsInChangedFiles.length} |`,
107
+ `| Resolved | ${guard.delta.resolvedFindings.length} |`,
108
+ `| Baseline debt | ${guard.delta.baselineFindings.length} |`,
109
+ `| Expired exceptions | ${guard.acknowledgmentLifecycle.expired.length} |`,
110
+ '',
111
+ ];
112
+ if (guard.decision.reasons.length > 0) {
113
+ lines.push('### Policy reasons', '');
114
+ for (const reason of guard.decision.reasons)
115
+ lines.push(`- ${reason.message}`);
116
+ lines.push('');
117
+ }
118
+ await writeFile(summaryFile, `${lines.join('\n')}\n`, { flag: 'a' });
119
+ }
120
+ function setDecisionExitCode(guard) {
121
+ if (!guard.decision.deployAllowed)
122
+ process.exitCode = 2;
123
+ }
124
+ const program = new Command();
125
+ program
126
+ .name('vlayer-ci')
127
+ .description('Compliance delivery gates, evidence, graph, and remediation for vlayer')
128
+ .version('1.0.0');
129
+ addCommonOptions(program
130
+ .command('guard')
131
+ .description('Decide whether a software change may be deployed')
132
+ .argument('[path]', 'Repository path', '.')
133
+ .option('-o, --output <path>', 'Write the machine-readable guard result to JSON')).action(async (path, options) => {
134
+ try {
135
+ const guard = await executeGuard(path, options);
136
+ printDecision(guard);
137
+ await appendGithubSummary(guard);
138
+ if (options.output) {
139
+ const output = resolve(options.output);
140
+ await writeFile(output, JSON.stringify(guardJson(guard), null, 2), 'utf-8');
141
+ console.log(chalk.gray(`\nGuard result: ${output}`));
142
+ }
143
+ setDecisionExitCode(guard);
144
+ }
145
+ catch (error) {
146
+ console.error(chalk.red(error instanceof Error ? error.message : 'Compliance guard failed'));
147
+ process.exitCode = 1;
148
+ }
149
+ });
150
+ addCommonOptions(program
151
+ .command('evidence')
152
+ .description('Generate a tamper-evident compliance evidence package')
153
+ .argument('[path]', 'Repository path', '.')
154
+ .option('-o, --output <path>', 'Evidence package output', 'vlayer-evidence.json')).action(async (path, options) => {
155
+ try {
156
+ const guard = await executeGuard(path, options);
157
+ const evidence = buildEvidencePackage(guard.git.root, guard);
158
+ const output = resolve(options.output);
159
+ await saveEvidencePackage(output, evidence);
160
+ printDecision(guard);
161
+ console.log(chalk.cyan(`\nEvidence package: ${output}`));
162
+ console.log(chalk.cyan(`SHA256: ${evidence.packageHash}`));
163
+ setDecisionExitCode(guard);
164
+ }
165
+ catch (error) {
166
+ console.error(chalk.red(error instanceof Error ? error.message : 'Evidence generation failed'));
167
+ process.exitCode = 1;
168
+ }
169
+ });
170
+ addCommonOptions(program
171
+ .command('graph')
172
+ .description('Generate the code-to-control compliance graph')
173
+ .argument('[path]', 'Repository path', '.')
174
+ .option('-o, --output <path>', 'Graph JSON output', 'vlayer-compliance-graph.json')
175
+ .option('--mermaid <path>', 'Also write a Mermaid graph file')).action(async (path, options) => {
176
+ try {
177
+ const guard = await executeGuard(path, options);
178
+ const graph = buildComplianceGraph(guard.findings, guard.git.root, guard.decision, guard.git);
179
+ const output = resolve(options.output);
180
+ await writeFile(output, JSON.stringify(graph, null, 2), 'utf-8');
181
+ console.log(chalk.cyan(`Compliance graph: ${output}`));
182
+ console.log(chalk.gray(`${graph.nodes.length} nodes / ${graph.edges.length} edges`));
183
+ if (options.mermaid) {
184
+ const mermaidPath = resolve(options.mermaid);
185
+ await writeFile(mermaidPath, graphToMermaid(graph), 'utf-8');
186
+ console.log(chalk.cyan(`Mermaid graph: ${mermaidPath}`));
187
+ }
188
+ setDecisionExitCode(guard);
189
+ }
190
+ catch (error) {
191
+ console.error(chalk.red(error instanceof Error ? error.message : 'Graph generation failed'));
192
+ process.exitCode = 1;
193
+ }
194
+ });
195
+ program
196
+ .command('exceptions')
197
+ .description('Review acknowledgment/exception lifecycle')
198
+ .argument('[path]', 'Repository path', '.')
199
+ .option('--config <path>', 'Scanner configuration file')
200
+ .option('-f, --format <format>', 'text or json', 'text')
201
+ .action(async (path, options) => {
202
+ try {
203
+ const lifecycle = await getAcknowledgmentLifecycle(path, options.config);
204
+ if (options.format === 'json') {
205
+ console.log(JSON.stringify(lifecycle, null, 2));
206
+ }
207
+ else {
208
+ console.log(chalk.bold('\nCompliance exceptions'));
209
+ console.log(`Total: ${lifecycle.total}`);
210
+ console.log(`Active: ${lifecycle.active.length}`);
211
+ console.log(`Expiring in 30 days: ${lifecycle.expiringSoon.length}`);
212
+ console.log(`Expired: ${lifecycle.expired.length}`);
213
+ for (const acknowledgment of lifecycle.expired) {
214
+ console.log(chalk.red(` - ${acknowledgment.id ?? acknowledgment.pattern}: ${acknowledgment.reason}`));
215
+ }
216
+ }
217
+ if (lifecycle.expired.length > 0)
218
+ process.exitCode = 2;
219
+ }
220
+ catch (error) {
221
+ console.error(chalk.red(error instanceof Error ? error.message : 'Exception review failed'));
222
+ process.exitCode = 1;
223
+ }
224
+ });
225
+ addCommonOptions(program
226
+ .command('agent')
227
+ .description('Explain a deployment decision and generate a remediation plan')
228
+ .argument('[path]', 'Repository path', '.')
229
+ .option('-o, --output <path>', 'Write agent result JSON')
230
+ .option('--markdown <path>', 'Write remediation plan as Markdown')
231
+ .option('--apply-safe-fixes', 'Apply registered deterministic fixes, then re-evaluate')).action(async (path, options) => {
232
+ try {
233
+ let guard = await executeGuard(path, options);
234
+ let fixReport;
235
+ if (options.applySafeFixes && !guard.decision.deployAllowed) {
236
+ const candidates = (guard.decision.consideredScope === 'changed-files'
237
+ ? guard.delta.newFindingsInChangedFiles
238
+ : guard.delta.newFindings).filter(finding => finding.fixType);
239
+ if (candidates.length > 0) {
240
+ const report = await applyFixes(candidates, guard.git.root, guard.scannedFiles, 0);
241
+ fixReport = { fixedCount: report.fixedCount, skippedCount: report.skippedCount };
242
+ guard = await executeGuard(path, options);
243
+ }
244
+ }
245
+ const remediation = buildRemediationPlan(guard.git.root, guard);
246
+ printDecision(guard);
247
+ console.log(chalk.bold('\nRemediation'));
248
+ if (remediation.items.length === 0) {
249
+ console.log(remediation.deployAllowed
250
+ ? chalk.green('No blocking remediation required.')
251
+ : chalk.yellow('Policy failed for a governance condition; review policy reasons above.'));
252
+ }
253
+ else {
254
+ for (const item of remediation.items) {
255
+ console.log(`\n${chalk.red(item.severity.toUpperCase())} ${item.title}`);
256
+ console.log(chalk.gray(`${item.file}${item.line ? `:${item.line}` : ''}`));
257
+ console.log(item.recommendation);
258
+ if (item.autoFixAvailable)
259
+ console.log(chalk.cyan('Deterministic auto-fix is registered.'));
260
+ }
261
+ }
262
+ if (fixReport) {
263
+ console.log(chalk.cyan(`\nSafe fixes applied: ${fixReport.fixedCount}; skipped: ${fixReport.skippedCount}`));
264
+ }
265
+ if (options.markdown) {
266
+ await writeFile(resolve(options.markdown), remediationToMarkdown(remediation), 'utf-8');
267
+ }
268
+ if (options.output) {
269
+ await writeFile(resolve(options.output), JSON.stringify({
270
+ schemaVersion: '1.0',
271
+ decision: guard.decision,
272
+ remediation,
273
+ fixReport,
274
+ }, null, 2), 'utf-8');
275
+ }
276
+ setDecisionExitCode(guard);
277
+ }
278
+ catch (error) {
279
+ console.error(chalk.red(error instanceof Error ? error.message : 'Compliance agent failed'));
280
+ process.exitCode = 1;
281
+ }
282
+ });
283
+ program
284
+ .command('verify-evidence')
285
+ .description('Verify the SHA256 integrity of a vlayer evidence package')
286
+ .argument('<file>', 'Evidence package JSON')
287
+ .action(async (file) => {
288
+ try {
289
+ const evidence = JSON.parse(await readFile(resolve(file), 'utf-8'));
290
+ const valid = verifyEvidencePackage(evidence);
291
+ console.log(valid
292
+ ? chalk.green.bold('Evidence package integrity verified')
293
+ : chalk.red.bold('Evidence package integrity check FAILED'));
294
+ if (!valid)
295
+ process.exitCode = 2;
296
+ }
297
+ catch (error) {
298
+ console.error(chalk.red(error instanceof Error ? error.message : 'Evidence verification failed'));
299
+ process.exitCode = 1;
300
+ }
301
+ });
302
+ program.parseAsync().catch(error => {
303
+ console.error(chalk.red(error instanceof Error ? error.message : 'vlayer-ci failed'));
304
+ process.exitCode = 1;
305
+ });
306
+ //# sourceMappingURL=delivery-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-cli.js","sourceRoot":"","sources":["../src/delivery-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=delivery-upload-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-upload-cli.d.ts","sourceRoot":"","sources":["../src/delivery-upload-cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { uploadEvidenceFile } from './delivery/upload.js';
5
+ const program = new Command();
6
+ program
7
+ .name('vlayer-upload')
8
+ .description('Upload a verified vlayer evidence package to a compliance workspace')
9
+ .argument('<file>', 'Evidence package JSON')
10
+ .option('--url <url>', 'Workspace ingest URL (default: VLAYER_INGEST_URL or https://vlayer.app/api/ingest)')
11
+ .option('--token-env <name>', 'Environment variable containing the project token', 'VLAYER_TOKEN')
12
+ .action(async (file, options) => {
13
+ try {
14
+ const token = process.env[options.tokenEnv];
15
+ if (!token) {
16
+ throw new Error(`${options.tokenEnv} is not set`);
17
+ }
18
+ const result = await uploadEvidenceFile(file, {
19
+ url: options.url,
20
+ token,
21
+ });
22
+ console.log(chalk.green.bold('Evidence uploaded'));
23
+ if (result.projectId)
24
+ console.log(`Project: ${result.projectId}`);
25
+ if (result.scanId)
26
+ console.log(`Scan: ${result.scanId}`);
27
+ }
28
+ catch (error) {
29
+ console.error(chalk.red(error instanceof Error ? error.message : 'Evidence upload failed'));
30
+ process.exitCode = 1;
31
+ }
32
+ });
33
+ program.parseAsync().catch(error => {
34
+ console.error(chalk.red(error instanceof Error ? error.message : 'vlayer-upload failed'));
35
+ process.exitCode = 1;
36
+ });
37
+ //# sourceMappingURL=delivery-upload-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-upload-cli.js","sourceRoot":"","sources":["../src/delivery-upload-cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,eAAe,CAAC;KACrB,WAAW,CAAC,qEAAqE,CAAC;KAClF,QAAQ,CAAC,QAAQ,EAAE,uBAAuB,CAAC;KAC3C,MAAM,CAAC,aAAa,EAAE,oFAAoF,CAAC;KAC3G,MAAM,CAAC,oBAAoB,EAAE,mDAAmD,EAAE,cAAc,CAAC;KACjG,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAA2C,EAAE,EAAE;IAC1E,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,CAAC,QAAQ,aAAa,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE;YAC5C,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK;SACN,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACnD,IAAI,MAAM,CAAC,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAClE,IAAI,MAAM,CAAC,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC;QAC5F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACjC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAC1F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -3,10 +3,11 @@ export { generateReport } from './reporters/index.js';
3
3
  export { loadCustomRules, validateRulesFile, scanWithCustomRules } from './rules/index.js';
4
4
  export { RULE_CATALOG, getAllRules, getRulesByCategory, getCategoryCounts, } from './rules/catalog.js';
5
5
  export type { CatalogRule, CatalogSeverity, Category } from './rules/catalog.js';
6
- export { loadBaseline, saveBaseline, applyBaseline, generateFindingHash } from './baseline.js';
6
+ export { BASELINE_VERSION, applyBaseline, canonicalRuleId, createBaselineEntry, generateFindingHash, getFindingAnchor, inferProjectRoot, loadBaseline, normalizeFindingFile, saveBaseline, } from './baseline.js';
7
7
  export { checkInlineSuppression, applyInlineSuppressions } from './suppression.js';
8
8
  export { checkAcknowledgment, applyAcknowledgments } from './acknowledgments.js';
9
9
  export { calculateComplianceScore, formatScore, getScoreColor, getScoreSummary } from './compliance-score.js';
10
+ export * from './delivery/index.js';
10
11
  export type { Finding, ScanResult, ScanOptions, Report, ReportOptions, Scanner, Severity, ComplianceCategory, Confidence, VlayerConfig, AcknowledgedFinding, ContextLine, CompiledCustomRule, CustomRuleFix, ComplianceScore, GroupedFinding, Occurrence, } from './types.js';
11
12
  export type { LoadRulesResult, RuleLoadError, CustomRuleDefinition, RulesFile } from './rules/index.js';
12
13
  export type { Baseline, BaselineEntry } from './baseline.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EACL,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9G,YAAY,EACV,OAAO,EACP,UAAU,EACV,WAAW,EACX,MAAM,EACN,aAAa,EACb,OAAO,EACP,QAAQ,EACR,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACxG,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EACL,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,EACpB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9G,cAAc,qBAAqB,CAAC;AACpC,YAAY,EACV,OAAO,EACP,UAAU,EACV,WAAW,EACX,MAAM,EACN,aAAa,EACb,OAAO,EACP,QAAQ,EACR,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACxG,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -2,8 +2,9 @@ export { scan, groupFindings } from './scan.js';
2
2
  export { generateReport } from './reporters/index.js';
3
3
  export { loadCustomRules, validateRulesFile, scanWithCustomRules } from './rules/index.js';
4
4
  export { RULE_CATALOG, getAllRules, getRulesByCategory, getCategoryCounts, } from './rules/catalog.js';
5
- export { loadBaseline, saveBaseline, applyBaseline, generateFindingHash } from './baseline.js';
5
+ export { BASELINE_VERSION, applyBaseline, canonicalRuleId, createBaselineEntry, generateFindingHash, getFindingAnchor, inferProjectRoot, loadBaseline, normalizeFindingFile, saveBaseline, } from './baseline.js';
6
6
  export { checkInlineSuppression, applyInlineSuppressions } from './suppression.js';
7
7
  export { checkAcknowledgment, applyAcknowledgments } from './acknowledgments.js';
8
8
  export { calculateComplianceScore, formatScore, getScoreColor, getScoreSummary } from './compliance-score.js';
9
+ export * from './delivery/index.js';
9
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EACL,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EACL,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,EACpB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9G,cAAc,qBAAqB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "verification-layer",
3
- "version": "0.27.13",
3
+ "version": "0.28.0",
4
4
  "total": 143,
5
5
  "counts": {
6
6
  "phi-exposure": 29,
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "verification-layer",
3
- "version": "0.27.13",
4
- "description": "Open-source HIPAA compliance scanner for healthcare code. 143 rules, 5 HIPAA categories. CLI + CI/CD + VS Code.",
3
+ "version": "0.28.0",
4
+ "description": "Open-source HIPAA compliance scanner and compliance delivery gate for healthcare code. 143 rules, evidence packages, policy gates, CLI + CI/CD.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "bin": {
8
- "vlayer": "dist/cli.js"
8
+ "vlayer": "dist/cli.js",
9
+ "vlayer-ci": "dist/delivery-cli.js",
10
+ "vlayer-upload": "dist/delivery-upload-cli.js"
9
11
  },
10
12
  "type": "module",
11
13
  "exports": {
@@ -18,6 +20,7 @@
18
20
  "dist",
19
21
  "templates",
20
22
  "README.md",
23
+ "COMPLIANCE_DELIVERY.md",
21
24
  "LICENSE"
22
25
  ],
23
26
  "scripts": {
@@ -27,7 +30,7 @@
27
30
  "start": "node dist/cli.js",
28
31
  "test": "vitest",
29
32
  "test:run": "vitest run",
30
- "lint": "eslint src/",
33
+ "lint": "eslint src/ --max-warnings 23",
31
34
  "typecheck": "tsc --noEmit",
32
35
  "prepare": "husky || true",
33
36
  "prepublishOnly": "npm run build"
@@ -52,7 +55,11 @@
52
55
  "suppression",
53
56
  "github-action",
54
57
  "devsecops",
55
- "healthtech"
58
+ "healthtech",
59
+ "compliance-as-code",
60
+ "policy-gate",
61
+ "audit-evidence",
62
+ "software-supply-chain"
56
63
  ],
57
64
  "author": "Simon Franco",
58
65
  "license": "MIT",
@@ -65,15 +72,14 @@
65
72
  },
66
73
  "homepage": "https://github.com/Francosimon53/verification-layer#readme",
67
74
  "devDependencies": {
68
- "@semantic-release/changelog": "^6.0.3",
69
- "@semantic-release/git": "^10.0.1",
75
+ "@eslint/js": "^9.39.5",
70
76
  "@types/node": "^20.0.0",
71
77
  "@typescript-eslint/eslint-plugin": "^8.54.0",
72
78
  "@typescript-eslint/parser": "^8.54.0",
73
- "eslint": "^8.57.0",
79
+ "eslint": "^9.39.5",
74
80
  "husky": "^9.1.7",
75
- "semantic-release": "^24.2.9",
76
81
  "typescript": "^5.4.0",
82
+ "typescript-eslint": "^8.69.0",
77
83
  "vitest": "^4.1.11"
78
84
  },
79
85
  "dependencies": {
@@ -0,0 +1,61 @@
1
+ name: vlayer compliance gate
2
+
3
+ on:
4
+ pull_request:
5
+ workflow_dispatch:
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ compliance:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - name: Checkout full history
15
+ uses: actions/checkout@v6
16
+ with:
17
+ fetch-depth: 0
18
+
19
+ - name: Setup Node.js
20
+ uses: actions/setup-node@v6
21
+ with:
22
+ node-version: '22'
23
+
24
+ - name: Evaluate changed-code compliance
25
+ id: guard
26
+ continue-on-error: true
27
+ run: |
28
+ npm exec --yes --package=verification-layer -- \
29
+ vlayer-ci guard . \
30
+ --baseline .vlayer-baseline.json \
31
+ --policy vlayer.policy.json \
32
+ --base "${{ github.base_ref }}" \
33
+ --output vlayer-guard.json
34
+
35
+ - name: Generate evidence package
36
+ if: always()
37
+ continue-on-error: true
38
+ run: |
39
+ npm exec --yes --package=verification-layer -- \
40
+ vlayer-ci evidence . \
41
+ --baseline .vlayer-baseline.json \
42
+ --policy vlayer.policy.json \
43
+ --base "${{ github.base_ref }}" \
44
+ --output vlayer-evidence.json
45
+
46
+ - name: Upload compliance evidence
47
+ if: always()
48
+ uses: actions/upload-artifact@v7
49
+ with:
50
+ name: vlayer-compliance-${{ github.run_number }}
51
+ path: |
52
+ vlayer-guard.json
53
+ vlayer-evidence.json
54
+ if-no-files-found: warn
55
+ retention-days: 90
56
+
57
+ - name: Enforce delivery decision
58
+ if: steps.guard.outcome != 'success'
59
+ run: |
60
+ echo "vlayer compliance policy blocked this change or the guard failed."
61
+ exit 1