@veraxhq/verax 0.2.0 → 0.3.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 +14 -18
- package/bin/verax.js +7 -0
- package/package.json +15 -5
- package/src/cli/commands/baseline.js +104 -0
- package/src/cli/commands/default.js +323 -111
- package/src/cli/commands/doctor.js +36 -4
- package/src/cli/commands/ga.js +243 -0
- package/src/cli/commands/gates.js +95 -0
- package/src/cli/commands/inspect.js +131 -2
- package/src/cli/commands/release-check.js +213 -0
- package/src/cli/commands/run.js +498 -103
- package/src/cli/commands/security-check.js +211 -0
- package/src/cli/commands/truth.js +114 -0
- package/src/cli/entry.js +305 -68
- package/src/cli/util/angular-component-extractor.js +179 -0
- package/src/cli/util/angular-navigation-detector.js +141 -0
- package/src/cli/util/angular-network-detector.js +161 -0
- package/src/cli/util/angular-state-detector.js +162 -0
- package/src/cli/util/ast-interactive-detector.js +546 -0
- package/src/cli/util/ast-network-detector.js +603 -0
- package/src/cli/util/ast-usestate-detector.js +602 -0
- package/src/cli/util/bootstrap-guard.js +86 -0
- package/src/cli/util/detection-engine.js +4 -3
- package/src/cli/util/determinism-runner.js +123 -0
- package/src/cli/util/determinism-writer.js +129 -0
- package/src/cli/util/env-url.js +4 -0
- package/src/cli/util/events.js +76 -0
- package/src/cli/util/expectation-extractor.js +380 -74
- package/src/cli/util/findings-writer.js +126 -15
- package/src/cli/util/learn-writer.js +3 -1
- package/src/cli/util/observation-engine.js +69 -23
- package/src/cli/util/observe-writer.js +3 -1
- package/src/cli/util/paths.js +6 -14
- package/src/cli/util/project-discovery.js +23 -0
- package/src/cli/util/project-writer.js +3 -1
- package/src/cli/util/redact.js +2 -2
- package/src/cli/util/run-resolver.js +64 -0
- package/src/cli/util/runtime-budget.js +147 -0
- package/src/cli/util/source-requirement.js +55 -0
- package/src/cli/util/summary-writer.js +13 -1
- package/src/cli/util/svelte-navigation-detector.js +163 -0
- package/src/cli/util/svelte-network-detector.js +80 -0
- package/src/cli/util/svelte-sfc-extractor.js +147 -0
- package/src/cli/util/svelte-state-detector.js +243 -0
- package/src/cli/util/vue-navigation-detector.js +177 -0
- package/src/cli/util/vue-sfc-extractor.js +162 -0
- package/src/cli/util/vue-state-detector.js +215 -0
- package/src/types/global.d.ts +28 -0
- package/src/types/ts-ast.d.ts +24 -0
- package/src/verax/cli/doctor.js +2 -2
- package/src/verax/cli/finding-explainer.js +56 -3
- package/src/verax/cli/init.js +1 -1
- package/src/verax/cli/url-safety.js +12 -2
- package/src/verax/cli/wizard.js +13 -2
- package/src/verax/core/artifacts/registry.js +154 -0
- package/src/verax/core/artifacts/verifier.js +980 -0
- package/src/verax/core/baseline/baseline.enforcer.js +137 -0
- package/src/verax/core/baseline/baseline.snapshot.js +231 -0
- package/src/verax/core/budget-engine.js +1 -1
- package/src/verax/core/capabilities/gates.js +499 -0
- package/src/verax/core/capabilities/registry.js +475 -0
- package/src/verax/core/confidence/confidence-compute.js +137 -0
- package/src/verax/core/confidence/confidence-invariants.js +234 -0
- package/src/verax/core/confidence/confidence-report-writer.js +112 -0
- package/src/verax/core/confidence/confidence-weights.js +44 -0
- package/src/verax/core/confidence/confidence.defaults.js +65 -0
- package/src/verax/core/confidence/confidence.loader.js +79 -0
- package/src/verax/core/confidence/confidence.schema.js +94 -0
- package/src/verax/core/confidence-engine-refactor.js +484 -0
- package/src/verax/core/confidence-engine.js +486 -0
- package/src/verax/core/confidence-engine.js.backup +471 -0
- package/src/verax/core/contracts/index.js +29 -0
- package/src/verax/core/contracts/types.js +185 -0
- package/src/verax/core/contracts/validators.js +381 -0
- package/src/verax/core/decision-snapshot.js +31 -4
- package/src/verax/core/decisions/decision.trace.js +276 -0
- package/src/verax/core/determinism/contract-writer.js +89 -0
- package/src/verax/core/determinism/contract.js +139 -0
- package/src/verax/core/determinism/diff.js +364 -0
- package/src/verax/core/determinism/engine.js +221 -0
- package/src/verax/core/determinism/finding-identity.js +148 -0
- package/src/verax/core/determinism/normalize.js +438 -0
- package/src/verax/core/determinism/report-writer.js +92 -0
- package/src/verax/core/determinism/run-fingerprint.js +118 -0
- package/src/verax/core/determinism-model.js +35 -6
- package/src/verax/core/dynamic-route-intelligence.js +528 -0
- package/src/verax/core/evidence/evidence-capture-service.js +307 -0
- package/src/verax/core/evidence/evidence-intent-ledger.js +165 -0
- package/src/verax/core/evidence-builder.js +487 -0
- package/src/verax/core/execution-mode-context.js +77 -0
- package/src/verax/core/execution-mode-detector.js +190 -0
- package/src/verax/core/failures/exit-codes.js +86 -0
- package/src/verax/core/failures/failure-summary.js +76 -0
- package/src/verax/core/failures/failure.factory.js +225 -0
- package/src/verax/core/failures/failure.ledger.js +132 -0
- package/src/verax/core/failures/failure.types.js +196 -0
- package/src/verax/core/failures/index.js +10 -0
- package/src/verax/core/ga/ga-report-writer.js +43 -0
- package/src/verax/core/ga/ga.artifact.js +49 -0
- package/src/verax/core/ga/ga.contract.js +434 -0
- package/src/verax/core/ga/ga.enforcer.js +86 -0
- package/src/verax/core/guardrails/guardrails-report-writer.js +109 -0
- package/src/verax/core/guardrails/policy.defaults.js +210 -0
- package/src/verax/core/guardrails/policy.loader.js +83 -0
- package/src/verax/core/guardrails/policy.schema.js +110 -0
- package/src/verax/core/guardrails/truth-reconciliation.js +136 -0
- package/src/verax/core/guardrails-engine.js +505 -0
- package/src/verax/core/incremental-store.js +15 -7
- package/src/verax/core/observe/run-timeline.js +316 -0
- package/src/verax/core/perf/perf.contract.js +186 -0
- package/src/verax/core/perf/perf.display.js +65 -0
- package/src/verax/core/perf/perf.enforcer.js +91 -0
- package/src/verax/core/perf/perf.monitor.js +209 -0
- package/src/verax/core/perf/perf.report.js +198 -0
- package/src/verax/core/pipeline-tracker.js +238 -0
- package/src/verax/core/product-definition.js +127 -0
- package/src/verax/core/release/provenance.builder.js +271 -0
- package/src/verax/core/release/release-report-writer.js +40 -0
- package/src/verax/core/release/release.enforcer.js +159 -0
- package/src/verax/core/release/reproducibility.check.js +221 -0
- package/src/verax/core/release/sbom.builder.js +283 -0
- package/src/verax/core/replay-validator.js +4 -4
- package/src/verax/core/replay.js +1 -1
- package/src/verax/core/report/cross-index.js +192 -0
- package/src/verax/core/report/human-summary.js +222 -0
- package/src/verax/core/route-intelligence.js +419 -0
- package/src/verax/core/security/secrets.scan.js +326 -0
- package/src/verax/core/security/security-report.js +50 -0
- package/src/verax/core/security/security.enforcer.js +124 -0
- package/src/verax/core/security/supplychain.defaults.json +38 -0
- package/src/verax/core/security/supplychain.policy.js +326 -0
- package/src/verax/core/security/vuln.scan.js +265 -0
- package/src/verax/core/silence-impact.js +1 -1
- package/src/verax/core/silence-model.js +9 -7
- package/src/verax/core/truth/truth.certificate.js +250 -0
- package/src/verax/core/ui-feedback-intelligence.js +515 -0
- package/src/verax/detect/comparison.js +8 -3
- package/src/verax/detect/confidence-engine.js +645 -57
- package/src/verax/detect/confidence-helper.js +33 -0
- package/src/verax/detect/detection-engine.js +19 -2
- package/src/verax/detect/dynamic-route-findings.js +335 -0
- package/src/verax/detect/evidence-index.js +15 -65
- package/src/verax/detect/expectation-chain-detector.js +417 -0
- package/src/verax/detect/expectation-model.js +56 -3
- package/src/verax/detect/explanation-helpers.js +1 -1
- package/src/verax/detect/finding-detector.js +2 -2
- package/src/verax/detect/findings-writer.js +149 -20
- package/src/verax/detect/flow-detector.js +4 -4
- package/src/verax/detect/index.js +265 -15
- package/src/verax/detect/interactive-findings.js +3 -4
- package/src/verax/detect/journey-stall-detector.js +558 -0
- package/src/verax/detect/route-findings.js +218 -0
- package/src/verax/detect/signal-mapper.js +2 -2
- package/src/verax/detect/skip-classifier.js +4 -4
- package/src/verax/detect/ui-feedback-findings.js +207 -0
- package/src/verax/detect/verdict-engine.js +61 -9
- package/src/verax/detect/view-switch-correlator.js +242 -0
- package/src/verax/flow/flow-engine.js +3 -2
- package/src/verax/flow/flow-spec.js +1 -2
- package/src/verax/index.js +413 -33
- package/src/verax/intel/effect-detector.js +1 -1
- package/src/verax/intel/index.js +2 -2
- package/src/verax/intel/route-extractor.js +3 -3
- package/src/verax/intel/vue-navigation-extractor.js +81 -18
- package/src/verax/intel/vue-router-extractor.js +4 -2
- package/src/verax/learn/action-contract-extractor.js +684 -66
- package/src/verax/learn/ast-contract-extractor.js +53 -1
- package/src/verax/learn/index.js +36 -2
- package/src/verax/learn/manifest-writer.js +28 -14
- package/src/verax/learn/route-extractor.js +1 -1
- package/src/verax/learn/route-validator.js +12 -8
- package/src/verax/learn/state-extractor.js +1 -1
- package/src/verax/learn/static-extractor-navigation.js +1 -1
- package/src/verax/learn/static-extractor-validation.js +2 -2
- package/src/verax/learn/static-extractor.js +8 -7
- package/src/verax/learn/ts-contract-resolver.js +14 -12
- package/src/verax/observe/browser.js +22 -3
- package/src/verax/observe/console-sensor.js +2 -2
- package/src/verax/observe/expectation-executor.js +2 -1
- package/src/verax/observe/focus-sensor.js +1 -1
- package/src/verax/observe/human-driver.js +29 -10
- package/src/verax/observe/index.js +92 -844
- package/src/verax/observe/interaction-discovery.js +27 -15
- package/src/verax/observe/interaction-runner.js +31 -14
- package/src/verax/observe/loading-sensor.js +6 -0
- package/src/verax/observe/navigation-sensor.js +1 -1
- package/src/verax/observe/observe-context.js +205 -0
- package/src/verax/observe/observe-helpers.js +191 -0
- package/src/verax/observe/observe-runner.js +226 -0
- package/src/verax/observe/observers/budget-observer.js +185 -0
- package/src/verax/observe/observers/console-observer.js +102 -0
- package/src/verax/observe/observers/coverage-observer.js +107 -0
- package/src/verax/observe/observers/interaction-observer.js +471 -0
- package/src/verax/observe/observers/navigation-observer.js +132 -0
- package/src/verax/observe/observers/network-observer.js +87 -0
- package/src/verax/observe/observers/safety-observer.js +82 -0
- package/src/verax/observe/observers/ui-feedback-observer.js +99 -0
- package/src/verax/observe/settle.js +1 -0
- package/src/verax/observe/state-sensor.js +8 -4
- package/src/verax/observe/state-ui-sensor.js +7 -1
- package/src/verax/observe/traces-writer.js +27 -16
- package/src/verax/observe/ui-feedback-detector.js +742 -0
- package/src/verax/observe/ui-signal-sensor.js +155 -2
- package/src/verax/scan-summary-writer.js +46 -9
- package/src/verax/shared/artifact-manager.js +9 -6
- package/src/verax/shared/budget-profiles.js +2 -2
- package/src/verax/shared/caching.js +1 -1
- package/src/verax/shared/config-loader.js +1 -2
- package/src/verax/shared/css-spinner-rules.js +204 -0
- package/src/verax/shared/dynamic-route-utils.js +12 -6
- package/src/verax/shared/retry-policy.js +1 -6
- package/src/verax/shared/root-artifacts.js +1 -1
- package/src/verax/shared/view-switch-rules.js +208 -0
- package/src/verax/shared/zip-artifacts.js +1 -0
- package/src/verax/validate/context-validator.js +1 -1
- package/src/verax/observe/index.js.backup +0 -1
- package/src/verax/validate/context-validator.js.bak +0 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PHASE 21.8 — Security Check CLI Command
|
|
3
|
+
*
|
|
4
|
+
* Checks security baseline: secrets, vulnerabilities, supply-chain.
|
|
5
|
+
* Exit codes: 0 = SECURITY-OK, 6 = SECURITY-BLOCKED, 70 = Internal corruption
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { scanSecrets, writeSecretsReport } from '../../verax/core/security/secrets.scan.js';
|
|
9
|
+
import { scanVulnerabilities, writeVulnReport } from '../../verax/core/security/vuln.scan.js';
|
|
10
|
+
import { evaluateSupplyChainPolicy, writeSupplyChainReport } from '../../verax/core/security/supplychain.policy.js';
|
|
11
|
+
import { writeSecurityReport } from '../../verax/core/security/security-report.js';
|
|
12
|
+
import { resolve } from 'path';
|
|
13
|
+
import { mkdirSync, existsSync } from 'fs';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Security check command
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} options - Options
|
|
19
|
+
* @param {boolean} [options.json] - Output as JSON
|
|
20
|
+
*/
|
|
21
|
+
export async function securityCheckCommand(options = {}) {
|
|
22
|
+
const { json = false } = options;
|
|
23
|
+
const projectDir = resolve(process.cwd());
|
|
24
|
+
|
|
25
|
+
const status = {
|
|
26
|
+
secrets: { ok: false, hasSecrets: false, blockers: [], tool: 'VERAX_SECRETS_SCANNER' },
|
|
27
|
+
vulnerabilities: { ok: false, blocking: false, blockers: [], warnings: [], tool: null, availability: 'UNKNOWN' },
|
|
28
|
+
supplychain: { ok: false, violations: [], blockers: [], tool: 'VERAX_SUPPLYCHAIN_POLICY' }
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// 1. Scan for secrets
|
|
32
|
+
try {
|
|
33
|
+
const secretsResult = await scanSecrets(projectDir);
|
|
34
|
+
writeSecretsReport(projectDir, secretsResult);
|
|
35
|
+
|
|
36
|
+
status.secrets.ok = secretsResult.ok;
|
|
37
|
+
status.secrets.hasSecrets = secretsResult.hasSecrets;
|
|
38
|
+
|
|
39
|
+
if (secretsResult.hasSecrets) {
|
|
40
|
+
const critical = secretsResult.findings.filter(f => f.severity === 'CRITICAL');
|
|
41
|
+
const high = secretsResult.findings.filter(f => f.severity === 'HIGH');
|
|
42
|
+
|
|
43
|
+
if (critical.length > 0) {
|
|
44
|
+
status.secrets.blockers.push(`${critical.length} CRITICAL secret(s) detected`);
|
|
45
|
+
}
|
|
46
|
+
if (high.length > 0) {
|
|
47
|
+
status.secrets.blockers.push(`${high.length} HIGH severity secret(s) detected`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Add sample findings (first 3)
|
|
51
|
+
const sampleFindings = secretsResult.findings.slice(0, 3).map(f =>
|
|
52
|
+
`${f.type} in ${f.file}:${f.line}`
|
|
53
|
+
);
|
|
54
|
+
status.secrets.blockers.push(`Sample findings: ${sampleFindings.join(', ')}`);
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
status.secrets.blockers.push(`Secrets scan failed: ${error.message}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 2. Scan vulnerabilities
|
|
61
|
+
let vulnResult = null;
|
|
62
|
+
try {
|
|
63
|
+
vulnResult = await scanVulnerabilities(projectDir);
|
|
64
|
+
writeVulnReport(projectDir, vulnResult);
|
|
65
|
+
|
|
66
|
+
status.vulnerabilities.ok = !vulnResult.blocking;
|
|
67
|
+
status.vulnerabilities.blocking = vulnResult.blocking;
|
|
68
|
+
status.vulnerabilities.tool = vulnResult.tool || null;
|
|
69
|
+
status.vulnerabilities.availability = vulnResult.availability || 'UNKNOWN';
|
|
70
|
+
status.vulnerabilities.osvAvailable = vulnResult.osvAvailable || false;
|
|
71
|
+
|
|
72
|
+
if (vulnResult.availability === 'NOT_AVAILABLE') {
|
|
73
|
+
status.vulnerabilities.warnings.push('OSV scanner not available, using npm audit fallback');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (vulnResult.blocking) {
|
|
77
|
+
if (vulnResult.summary.critical > 0) {
|
|
78
|
+
status.vulnerabilities.blockers.push(`${vulnResult.summary.critical} CRITICAL vulnerability/vulnerabilities`);
|
|
79
|
+
}
|
|
80
|
+
if (vulnResult.summary.high > 0) {
|
|
81
|
+
status.vulnerabilities.blockers.push(`${vulnResult.summary.high} HIGH severity vulnerability/vulnerabilities`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (vulnResult.summary.medium > 0 && !vulnResult.blocking) {
|
|
86
|
+
status.vulnerabilities.warnings.push(`${vulnResult.summary.medium} MEDIUM severity vulnerability/vulnerabilities (non-blocking)`);
|
|
87
|
+
}
|
|
88
|
+
} catch (error) {
|
|
89
|
+
status.vulnerabilities.blockers.push(`Vulnerability scan failed: ${error.message}`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 3. Check supply-chain policy
|
|
93
|
+
let supplyChainResult = null;
|
|
94
|
+
try {
|
|
95
|
+
supplyChainResult = await evaluateSupplyChainPolicy(projectDir);
|
|
96
|
+
writeSupplyChainReport(projectDir, supplyChainResult);
|
|
97
|
+
|
|
98
|
+
status.supplychain.ok = supplyChainResult.ok;
|
|
99
|
+
status.supplychain.violations = supplyChainResult.violations;
|
|
100
|
+
|
|
101
|
+
if (!supplyChainResult.ok) {
|
|
102
|
+
for (const violation of supplyChainResult.violations) {
|
|
103
|
+
status.supplychain.blockers.push(violation.message);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
} catch (error) {
|
|
107
|
+
status.supplychain.blockers.push(`Supply-chain check failed: ${error.message}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Determine overall status
|
|
111
|
+
const allOk = status.secrets.ok && status.vulnerabilities.ok && status.supplychain.ok;
|
|
112
|
+
|
|
113
|
+
// Write unified security report
|
|
114
|
+
let secretsReport = null;
|
|
115
|
+
try {
|
|
116
|
+
const secretsPath = resolve(projectDir, 'release', 'security.secrets.report.json');
|
|
117
|
+
if (existsSync(secretsPath)) {
|
|
118
|
+
const { readFileSync } = await import('fs');
|
|
119
|
+
secretsReport = JSON.parse(readFileSync(secretsPath, 'utf-8'));
|
|
120
|
+
}
|
|
121
|
+
} catch {
|
|
122
|
+
// Ignore
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let vulnReportData = vulnResult;
|
|
126
|
+
let supplyChainReportData = supplyChainResult;
|
|
127
|
+
|
|
128
|
+
const unifiedReport = {
|
|
129
|
+
securityOk: allOk,
|
|
130
|
+
status,
|
|
131
|
+
summary: {
|
|
132
|
+
secrets: status.secrets.ok ? 'OK' : 'BLOCKED',
|
|
133
|
+
vulnerabilities: status.vulnerabilities.ok ? 'OK' : (status.vulnerabilities.blocking ? 'BLOCKED' : (status.vulnerabilities.availability === 'NOT_AVAILABLE' ? 'NOT_AVAILABLE' : 'WARN')),
|
|
134
|
+
supplychain: status.supplychain.ok ? 'OK' : 'BLOCKED'
|
|
135
|
+
},
|
|
136
|
+
secretsReport,
|
|
137
|
+
vulnReport: vulnReportData,
|
|
138
|
+
supplyChainReport: supplyChainReportData
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const unifiedReportPath = writeSecurityReport(projectDir, unifiedReport);
|
|
142
|
+
const hasInternalCorruption =
|
|
143
|
+
status.secrets.blockers.some(b => b.includes('corruption') || b.includes('Internal')) ||
|
|
144
|
+
status.vulnerabilities.blockers.some(b => b.includes('corruption')) ||
|
|
145
|
+
status.supplychain.blockers.some(b => b.includes('corruption'));
|
|
146
|
+
|
|
147
|
+
// Output
|
|
148
|
+
if (json) {
|
|
149
|
+
console.log(JSON.stringify({
|
|
150
|
+
securityOk: allOk,
|
|
151
|
+
status,
|
|
152
|
+
summary: {
|
|
153
|
+
secrets: status.secrets.ok ? 'OK' : 'BLOCKED',
|
|
154
|
+
vulnerabilities: status.vulnerabilities.ok ? 'OK' : (status.vulnerabilities.blocking ? 'BLOCKED' : (status.vulnerabilities.availability === 'NOT_AVAILABLE' ? 'NOT_AVAILABLE' : 'WARN')),
|
|
155
|
+
supplychain: status.supplychain.ok ? 'OK' : 'BLOCKED'
|
|
156
|
+
},
|
|
157
|
+
unifiedReportPath: unifiedReportPath
|
|
158
|
+
}, null, 2));
|
|
159
|
+
} else {
|
|
160
|
+
console.log('\n' + '='.repeat(80));
|
|
161
|
+
console.log('SECURITY BASELINE CHECK');
|
|
162
|
+
console.log('='.repeat(80));
|
|
163
|
+
|
|
164
|
+
console.log(`\nSecrets: ${status.secrets.ok ? '✅ OK' : '❌ BLOCKED'}`);
|
|
165
|
+
if (status.secrets.blockers.length > 0) {
|
|
166
|
+
for (const blocker of status.secrets.blockers) {
|
|
167
|
+
console.log(` - ${blocker}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
console.log(`\nVulnerabilities: ${status.vulnerabilities.ok ? '✅ OK' : (status.vulnerabilities.blocking ? '❌ BLOCKED' : '⚠️ WARN')}`);
|
|
172
|
+
if (status.vulnerabilities.blockers.length > 0) {
|
|
173
|
+
for (const blocker of status.vulnerabilities.blockers) {
|
|
174
|
+
console.log(` - ${blocker}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (status.vulnerabilities.warnings.length > 0) {
|
|
178
|
+
for (const warning of status.vulnerabilities.warnings) {
|
|
179
|
+
console.log(` ⚠️ ${warning}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
console.log(`\nSupply-chain: ${status.supplychain.ok ? '✅ OK' : '❌ BLOCKED'}`);
|
|
184
|
+
if (status.supplychain.blockers.length > 0) {
|
|
185
|
+
for (const blocker of status.supplychain.blockers) {
|
|
186
|
+
console.log(` - ${blocker}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
console.log(`\nOverall: ${allOk ? '✅ SECURITY-OK' : '❌ SECURITY-BLOCKED'}`);
|
|
191
|
+
console.log(`\nSee unified report: ${unifiedReportPath}`);
|
|
192
|
+
console.log('='.repeat(80) + '\n');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Exit codes: 0 = SECURITY-OK, 6 = SECURITY-BLOCKED, 70 = Internal corruption
|
|
196
|
+
// NOT_AVAILABLE tools exit 0 only if policy allows (strict mode would exit 2)
|
|
197
|
+
const hasNotAvailable = status.vulnerabilities.availability === 'NOT_AVAILABLE';
|
|
198
|
+
const strictMode = process.env.VERAX_SECURITY_STRICT === '1';
|
|
199
|
+
|
|
200
|
+
if (allOk) {
|
|
201
|
+
process.exit(0);
|
|
202
|
+
} else if (hasNotAvailable && !strictMode) {
|
|
203
|
+
// NOT_AVAILABLE is not a blocker unless strict mode
|
|
204
|
+
process.exit(0);
|
|
205
|
+
} else if (hasInternalCorruption) {
|
|
206
|
+
process.exit(70);
|
|
207
|
+
} else {
|
|
208
|
+
process.exit(6);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PHASE 21.11 — Truth Command
|
|
3
|
+
*
|
|
4
|
+
* `verax truth` - Shows truth certificate summary
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { resolve } from 'path';
|
|
8
|
+
import { findLatestRunId } from '../util/run-resolver.js';
|
|
9
|
+
import { generateTruthCertificate, loadTruthCertificate } from '../../verax/core/truth/truth.certificate.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Truth command
|
|
13
|
+
*
|
|
14
|
+
* @param {string} projectDir - Project directory
|
|
15
|
+
* @param {Object} options - Command options
|
|
16
|
+
*/
|
|
17
|
+
export async function truthCommand(projectDir, options = {}) {
|
|
18
|
+
const { json = false, runId: runIdOpt = null } = options;
|
|
19
|
+
|
|
20
|
+
const runId = runIdOpt || findLatestRunId(projectDir);
|
|
21
|
+
|
|
22
|
+
if (!runId) {
|
|
23
|
+
if (json) {
|
|
24
|
+
console.log(JSON.stringify({
|
|
25
|
+
error: 'NO_RUNS_FOUND',
|
|
26
|
+
message: 'No runs found. Run a scan first.'
|
|
27
|
+
}, null, 2));
|
|
28
|
+
} else {
|
|
29
|
+
console.log('\n=== Truth Certificate ===\n');
|
|
30
|
+
console.log('Error: No runs found. Run a scan first.\n');
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Try to load existing certificate, otherwise generate
|
|
36
|
+
let certificate = loadTruthCertificate(projectDir, runId);
|
|
37
|
+
|
|
38
|
+
if (!certificate) {
|
|
39
|
+
certificate = await generateTruthCertificate(projectDir, runId);
|
|
40
|
+
if (certificate) {
|
|
41
|
+
const { writeTruthCertificate } = await import('../../verax/core/truth/truth.certificate.js');
|
|
42
|
+
writeTruthCertificate(projectDir, runId, certificate);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!certificate) {
|
|
47
|
+
if (json) {
|
|
48
|
+
console.log(JSON.stringify({
|
|
49
|
+
error: 'CERTIFICATE_GENERATION_FAILED',
|
|
50
|
+
message: 'Failed to generate truth certificate'
|
|
51
|
+
}, null, 2));
|
|
52
|
+
} else {
|
|
53
|
+
console.log('\n=== Truth Certificate ===\n');
|
|
54
|
+
console.log('Error: Failed to generate truth certificate\n');
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (json) {
|
|
60
|
+
console.log(JSON.stringify(certificate, null, 2));
|
|
61
|
+
} else {
|
|
62
|
+
console.log('\n=== Truth Certificate ===\n');
|
|
63
|
+
console.log(`Run ID: ${certificate.runId}`);
|
|
64
|
+
console.log(`URL: ${certificate.url || 'N/A'}`);
|
|
65
|
+
console.log(`Generated: ${certificate.generatedAt}`);
|
|
66
|
+
|
|
67
|
+
console.log('\nEvidence Law:');
|
|
68
|
+
console.log(` Status: ${certificate.evidenceLaw.status}`);
|
|
69
|
+
console.log(` Violated: ${certificate.evidenceLaw.violated ? 'YES' : 'NO'}`);
|
|
70
|
+
|
|
71
|
+
console.log('\nDeterminism:');
|
|
72
|
+
console.log(` Verdict: ${certificate.determinism.verdict}`);
|
|
73
|
+
console.log(` Message: ${certificate.determinism.message}`);
|
|
74
|
+
|
|
75
|
+
console.log('\nFailures:');
|
|
76
|
+
console.log(` Total: ${certificate.failures.total}`);
|
|
77
|
+
console.log(` Blocking: ${certificate.failures.blocking ? 'YES' : 'NO'}`);
|
|
78
|
+
console.log(` Degraded: ${certificate.failures.degraded ? 'YES' : 'NO'}`);
|
|
79
|
+
console.log(` By Severity: ${JSON.stringify(certificate.failures.bySeverity)}`);
|
|
80
|
+
|
|
81
|
+
console.log('\nGA:');
|
|
82
|
+
console.log(` Verdict: ${certificate.ga.verdict}`);
|
|
83
|
+
console.log(` Ready: ${certificate.ga.ready ? 'YES' : 'NO'}`);
|
|
84
|
+
console.log(` Blockers: ${certificate.ga.blockers}`);
|
|
85
|
+
console.log(` Warnings: ${certificate.ga.warnings}`);
|
|
86
|
+
|
|
87
|
+
console.log('\nSecurity:');
|
|
88
|
+
console.log(` Overall: ${certificate.security.overall}`);
|
|
89
|
+
console.log(` Secrets: ${certificate.security.secrets}`);
|
|
90
|
+
console.log(` Vulnerabilities: ${certificate.security.vulnerabilities}`);
|
|
91
|
+
|
|
92
|
+
console.log('\nPerformance:');
|
|
93
|
+
console.log(` Verdict: ${certificate.performance.verdict}`);
|
|
94
|
+
console.log(` OK: ${certificate.performance.ok ? 'YES' : 'NO'}`);
|
|
95
|
+
console.log(` Violations: ${certificate.performance.violations}`);
|
|
96
|
+
|
|
97
|
+
console.log('\nBaseline:');
|
|
98
|
+
console.log(` Hash: ${certificate.baseline.hash || 'N/A'}`);
|
|
99
|
+
console.log(` Frozen: ${certificate.baseline.frozen ? 'YES' : 'NO'}`);
|
|
100
|
+
console.log(` Version: ${certificate.baseline.version || 'N/A'}`);
|
|
101
|
+
|
|
102
|
+
console.log('\nProvenance:');
|
|
103
|
+
console.log(` Hash: ${certificate.provenance.hash || 'N/A'}`);
|
|
104
|
+
console.log(` Version: ${certificate.provenance.version || 'N/A'}`);
|
|
105
|
+
|
|
106
|
+
console.log('\nOverall Verdict:');
|
|
107
|
+
console.log(` Status: ${certificate.overallVerdict.status}`);
|
|
108
|
+
if (certificate.overallVerdict.reasons.length > 0) {
|
|
109
|
+
console.log(` Reasons: ${certificate.overallVerdict.reasons.join('; ')}`);
|
|
110
|
+
}
|
|
111
|
+
console.log('');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|