@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.
Files changed (217) hide show
  1. package/README.md +14 -18
  2. package/bin/verax.js +7 -0
  3. package/package.json +15 -5
  4. package/src/cli/commands/baseline.js +104 -0
  5. package/src/cli/commands/default.js +323 -111
  6. package/src/cli/commands/doctor.js +36 -4
  7. package/src/cli/commands/ga.js +243 -0
  8. package/src/cli/commands/gates.js +95 -0
  9. package/src/cli/commands/inspect.js +131 -2
  10. package/src/cli/commands/release-check.js +213 -0
  11. package/src/cli/commands/run.js +498 -103
  12. package/src/cli/commands/security-check.js +211 -0
  13. package/src/cli/commands/truth.js +114 -0
  14. package/src/cli/entry.js +305 -68
  15. package/src/cli/util/angular-component-extractor.js +179 -0
  16. package/src/cli/util/angular-navigation-detector.js +141 -0
  17. package/src/cli/util/angular-network-detector.js +161 -0
  18. package/src/cli/util/angular-state-detector.js +162 -0
  19. package/src/cli/util/ast-interactive-detector.js +546 -0
  20. package/src/cli/util/ast-network-detector.js +603 -0
  21. package/src/cli/util/ast-usestate-detector.js +602 -0
  22. package/src/cli/util/bootstrap-guard.js +86 -0
  23. package/src/cli/util/detection-engine.js +4 -3
  24. package/src/cli/util/determinism-runner.js +123 -0
  25. package/src/cli/util/determinism-writer.js +129 -0
  26. package/src/cli/util/env-url.js +4 -0
  27. package/src/cli/util/events.js +76 -0
  28. package/src/cli/util/expectation-extractor.js +380 -74
  29. package/src/cli/util/findings-writer.js +126 -15
  30. package/src/cli/util/learn-writer.js +3 -1
  31. package/src/cli/util/observation-engine.js +69 -23
  32. package/src/cli/util/observe-writer.js +3 -1
  33. package/src/cli/util/paths.js +6 -14
  34. package/src/cli/util/project-discovery.js +23 -0
  35. package/src/cli/util/project-writer.js +3 -1
  36. package/src/cli/util/redact.js +2 -2
  37. package/src/cli/util/run-resolver.js +64 -0
  38. package/src/cli/util/runtime-budget.js +147 -0
  39. package/src/cli/util/source-requirement.js +55 -0
  40. package/src/cli/util/summary-writer.js +13 -1
  41. package/src/cli/util/svelte-navigation-detector.js +163 -0
  42. package/src/cli/util/svelte-network-detector.js +80 -0
  43. package/src/cli/util/svelte-sfc-extractor.js +147 -0
  44. package/src/cli/util/svelte-state-detector.js +243 -0
  45. package/src/cli/util/vue-navigation-detector.js +177 -0
  46. package/src/cli/util/vue-sfc-extractor.js +162 -0
  47. package/src/cli/util/vue-state-detector.js +215 -0
  48. package/src/types/global.d.ts +28 -0
  49. package/src/types/ts-ast.d.ts +24 -0
  50. package/src/verax/cli/doctor.js +2 -2
  51. package/src/verax/cli/finding-explainer.js +56 -3
  52. package/src/verax/cli/init.js +1 -1
  53. package/src/verax/cli/url-safety.js +12 -2
  54. package/src/verax/cli/wizard.js +13 -2
  55. package/src/verax/core/artifacts/registry.js +154 -0
  56. package/src/verax/core/artifacts/verifier.js +980 -0
  57. package/src/verax/core/baseline/baseline.enforcer.js +137 -0
  58. package/src/verax/core/baseline/baseline.snapshot.js +231 -0
  59. package/src/verax/core/budget-engine.js +1 -1
  60. package/src/verax/core/capabilities/gates.js +499 -0
  61. package/src/verax/core/capabilities/registry.js +475 -0
  62. package/src/verax/core/confidence/confidence-compute.js +137 -0
  63. package/src/verax/core/confidence/confidence-invariants.js +234 -0
  64. package/src/verax/core/confidence/confidence-report-writer.js +112 -0
  65. package/src/verax/core/confidence/confidence-weights.js +44 -0
  66. package/src/verax/core/confidence/confidence.defaults.js +65 -0
  67. package/src/verax/core/confidence/confidence.loader.js +79 -0
  68. package/src/verax/core/confidence/confidence.schema.js +94 -0
  69. package/src/verax/core/confidence-engine-refactor.js +484 -0
  70. package/src/verax/core/confidence-engine.js +486 -0
  71. package/src/verax/core/confidence-engine.js.backup +471 -0
  72. package/src/verax/core/contracts/index.js +29 -0
  73. package/src/verax/core/contracts/types.js +185 -0
  74. package/src/verax/core/contracts/validators.js +381 -0
  75. package/src/verax/core/decision-snapshot.js +31 -4
  76. package/src/verax/core/decisions/decision.trace.js +276 -0
  77. package/src/verax/core/determinism/contract-writer.js +89 -0
  78. package/src/verax/core/determinism/contract.js +139 -0
  79. package/src/verax/core/determinism/diff.js +364 -0
  80. package/src/verax/core/determinism/engine.js +221 -0
  81. package/src/verax/core/determinism/finding-identity.js +148 -0
  82. package/src/verax/core/determinism/normalize.js +438 -0
  83. package/src/verax/core/determinism/report-writer.js +92 -0
  84. package/src/verax/core/determinism/run-fingerprint.js +118 -0
  85. package/src/verax/core/determinism-model.js +35 -6
  86. package/src/verax/core/dynamic-route-intelligence.js +528 -0
  87. package/src/verax/core/evidence/evidence-capture-service.js +307 -0
  88. package/src/verax/core/evidence/evidence-intent-ledger.js +165 -0
  89. package/src/verax/core/evidence-builder.js +487 -0
  90. package/src/verax/core/execution-mode-context.js +77 -0
  91. package/src/verax/core/execution-mode-detector.js +190 -0
  92. package/src/verax/core/failures/exit-codes.js +86 -0
  93. package/src/verax/core/failures/failure-summary.js +76 -0
  94. package/src/verax/core/failures/failure.factory.js +225 -0
  95. package/src/verax/core/failures/failure.ledger.js +132 -0
  96. package/src/verax/core/failures/failure.types.js +196 -0
  97. package/src/verax/core/failures/index.js +10 -0
  98. package/src/verax/core/ga/ga-report-writer.js +43 -0
  99. package/src/verax/core/ga/ga.artifact.js +49 -0
  100. package/src/verax/core/ga/ga.contract.js +434 -0
  101. package/src/verax/core/ga/ga.enforcer.js +86 -0
  102. package/src/verax/core/guardrails/guardrails-report-writer.js +109 -0
  103. package/src/verax/core/guardrails/policy.defaults.js +210 -0
  104. package/src/verax/core/guardrails/policy.loader.js +83 -0
  105. package/src/verax/core/guardrails/policy.schema.js +110 -0
  106. package/src/verax/core/guardrails/truth-reconciliation.js +136 -0
  107. package/src/verax/core/guardrails-engine.js +505 -0
  108. package/src/verax/core/incremental-store.js +15 -7
  109. package/src/verax/core/observe/run-timeline.js +316 -0
  110. package/src/verax/core/perf/perf.contract.js +186 -0
  111. package/src/verax/core/perf/perf.display.js +65 -0
  112. package/src/verax/core/perf/perf.enforcer.js +91 -0
  113. package/src/verax/core/perf/perf.monitor.js +209 -0
  114. package/src/verax/core/perf/perf.report.js +198 -0
  115. package/src/verax/core/pipeline-tracker.js +238 -0
  116. package/src/verax/core/product-definition.js +127 -0
  117. package/src/verax/core/release/provenance.builder.js +271 -0
  118. package/src/verax/core/release/release-report-writer.js +40 -0
  119. package/src/verax/core/release/release.enforcer.js +159 -0
  120. package/src/verax/core/release/reproducibility.check.js +221 -0
  121. package/src/verax/core/release/sbom.builder.js +283 -0
  122. package/src/verax/core/replay-validator.js +4 -4
  123. package/src/verax/core/replay.js +1 -1
  124. package/src/verax/core/report/cross-index.js +192 -0
  125. package/src/verax/core/report/human-summary.js +222 -0
  126. package/src/verax/core/route-intelligence.js +419 -0
  127. package/src/verax/core/security/secrets.scan.js +326 -0
  128. package/src/verax/core/security/security-report.js +50 -0
  129. package/src/verax/core/security/security.enforcer.js +124 -0
  130. package/src/verax/core/security/supplychain.defaults.json +38 -0
  131. package/src/verax/core/security/supplychain.policy.js +326 -0
  132. package/src/verax/core/security/vuln.scan.js +265 -0
  133. package/src/verax/core/silence-impact.js +1 -1
  134. package/src/verax/core/silence-model.js +9 -7
  135. package/src/verax/core/truth/truth.certificate.js +250 -0
  136. package/src/verax/core/ui-feedback-intelligence.js +515 -0
  137. package/src/verax/detect/comparison.js +8 -3
  138. package/src/verax/detect/confidence-engine.js +645 -57
  139. package/src/verax/detect/confidence-helper.js +33 -0
  140. package/src/verax/detect/detection-engine.js +19 -2
  141. package/src/verax/detect/dynamic-route-findings.js +335 -0
  142. package/src/verax/detect/evidence-index.js +15 -65
  143. package/src/verax/detect/expectation-chain-detector.js +417 -0
  144. package/src/verax/detect/expectation-model.js +56 -3
  145. package/src/verax/detect/explanation-helpers.js +1 -1
  146. package/src/verax/detect/finding-detector.js +2 -2
  147. package/src/verax/detect/findings-writer.js +149 -20
  148. package/src/verax/detect/flow-detector.js +4 -4
  149. package/src/verax/detect/index.js +265 -15
  150. package/src/verax/detect/interactive-findings.js +3 -4
  151. package/src/verax/detect/journey-stall-detector.js +558 -0
  152. package/src/verax/detect/route-findings.js +218 -0
  153. package/src/verax/detect/signal-mapper.js +2 -2
  154. package/src/verax/detect/skip-classifier.js +4 -4
  155. package/src/verax/detect/ui-feedback-findings.js +207 -0
  156. package/src/verax/detect/verdict-engine.js +61 -9
  157. package/src/verax/detect/view-switch-correlator.js +242 -0
  158. package/src/verax/flow/flow-engine.js +3 -2
  159. package/src/verax/flow/flow-spec.js +1 -2
  160. package/src/verax/index.js +413 -33
  161. package/src/verax/intel/effect-detector.js +1 -1
  162. package/src/verax/intel/index.js +2 -2
  163. package/src/verax/intel/route-extractor.js +3 -3
  164. package/src/verax/intel/vue-navigation-extractor.js +81 -18
  165. package/src/verax/intel/vue-router-extractor.js +4 -2
  166. package/src/verax/learn/action-contract-extractor.js +684 -66
  167. package/src/verax/learn/ast-contract-extractor.js +53 -1
  168. package/src/verax/learn/index.js +36 -2
  169. package/src/verax/learn/manifest-writer.js +28 -14
  170. package/src/verax/learn/route-extractor.js +1 -1
  171. package/src/verax/learn/route-validator.js +12 -8
  172. package/src/verax/learn/state-extractor.js +1 -1
  173. package/src/verax/learn/static-extractor-navigation.js +1 -1
  174. package/src/verax/learn/static-extractor-validation.js +2 -2
  175. package/src/verax/learn/static-extractor.js +8 -7
  176. package/src/verax/learn/ts-contract-resolver.js +14 -12
  177. package/src/verax/observe/browser.js +22 -3
  178. package/src/verax/observe/console-sensor.js +2 -2
  179. package/src/verax/observe/expectation-executor.js +2 -1
  180. package/src/verax/observe/focus-sensor.js +1 -1
  181. package/src/verax/observe/human-driver.js +29 -10
  182. package/src/verax/observe/index.js +92 -844
  183. package/src/verax/observe/interaction-discovery.js +27 -15
  184. package/src/verax/observe/interaction-runner.js +31 -14
  185. package/src/verax/observe/loading-sensor.js +6 -0
  186. package/src/verax/observe/navigation-sensor.js +1 -1
  187. package/src/verax/observe/observe-context.js +205 -0
  188. package/src/verax/observe/observe-helpers.js +191 -0
  189. package/src/verax/observe/observe-runner.js +226 -0
  190. package/src/verax/observe/observers/budget-observer.js +185 -0
  191. package/src/verax/observe/observers/console-observer.js +102 -0
  192. package/src/verax/observe/observers/coverage-observer.js +107 -0
  193. package/src/verax/observe/observers/interaction-observer.js +471 -0
  194. package/src/verax/observe/observers/navigation-observer.js +132 -0
  195. package/src/verax/observe/observers/network-observer.js +87 -0
  196. package/src/verax/observe/observers/safety-observer.js +82 -0
  197. package/src/verax/observe/observers/ui-feedback-observer.js +99 -0
  198. package/src/verax/observe/settle.js +1 -0
  199. package/src/verax/observe/state-sensor.js +8 -4
  200. package/src/verax/observe/state-ui-sensor.js +7 -1
  201. package/src/verax/observe/traces-writer.js +27 -16
  202. package/src/verax/observe/ui-feedback-detector.js +742 -0
  203. package/src/verax/observe/ui-signal-sensor.js +155 -2
  204. package/src/verax/scan-summary-writer.js +46 -9
  205. package/src/verax/shared/artifact-manager.js +9 -6
  206. package/src/verax/shared/budget-profiles.js +2 -2
  207. package/src/verax/shared/caching.js +1 -1
  208. package/src/verax/shared/config-loader.js +1 -2
  209. package/src/verax/shared/css-spinner-rules.js +204 -0
  210. package/src/verax/shared/dynamic-route-utils.js +12 -6
  211. package/src/verax/shared/retry-policy.js +1 -6
  212. package/src/verax/shared/root-artifacts.js +1 -1
  213. package/src/verax/shared/view-switch-rules.js +208 -0
  214. package/src/verax/shared/zip-artifacts.js +1 -0
  215. package/src/verax/validate/context-validator.js +1 -1
  216. package/src/verax/observe/index.js.backup +0 -1
  217. 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
+