@veraxhq/verax 0.2.1 → 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 +3 -3
- package/src/cli/commands/baseline.js +104 -0
- package/src/cli/commands/default.js +79 -25
- 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 +246 -35
- package/src/cli/commands/security-check.js +211 -0
- package/src/cli/commands/truth.js +114 -0
- package/src/cli/entry.js +304 -67
- 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/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/expectation-extractor.js +369 -73
- package/src/cli/util/findings-writer.js +126 -16
- package/src/cli/util/learn-writer.js +3 -1
- package/src/cli/util/observe-writer.js +3 -1
- package/src/cli/util/paths.js +3 -12
- package/src/cli/util/project-discovery.js +3 -0
- package/src/cli/util/project-writer.js +3 -1
- package/src/cli/util/run-resolver.js +64 -0
- package/src/cli/util/source-requirement.js +55 -0
- package/src/cli/util/summary-writer.js +1 -0
- 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/verax/cli/finding-explainer.js +56 -3
- 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/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 +30 -3
- 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/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/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/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/truth/truth.certificate.js +250 -0
- package/src/verax/core/ui-feedback-intelligence.js +515 -0
- package/src/verax/detect/confidence-engine.js +628 -40
- package/src/verax/detect/confidence-helper.js +33 -0
- package/src/verax/detect/detection-engine.js +18 -1
- package/src/verax/detect/dynamic-route-findings.js +335 -0
- package/src/verax/detect/expectation-chain-detector.js +417 -0
- package/src/verax/detect/expectation-model.js +3 -1
- package/src/verax/detect/findings-writer.js +141 -5
- package/src/verax/detect/index.js +229 -5
- package/src/verax/detect/journey-stall-detector.js +558 -0
- package/src/verax/detect/route-findings.js +218 -0
- package/src/verax/detect/ui-feedback-findings.js +207 -0
- package/src/verax/detect/verdict-engine.js +57 -3
- package/src/verax/detect/view-switch-correlator.js +242 -0
- package/src/verax/index.js +413 -45
- package/src/verax/learn/action-contract-extractor.js +682 -64
- package/src/verax/learn/route-validator.js +4 -1
- package/src/verax/observe/index.js +88 -843
- package/src/verax/observe/interaction-runner.js +25 -8
- 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/ui-feedback-detector.js +742 -0
- package/src/verax/observe/ui-signal-sensor.js +148 -2
- package/src/verax/scan-summary-writer.js +42 -8
- package/src/verax/shared/artifact-manager.js +8 -5
- package/src/verax/shared/css-spinner-rules.js +204 -0
- package/src/verax/shared/view-switch-rules.js +208 -0
|
@@ -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
|
+
|
package/src/cli/entry.js
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* VERAX CLI Entry Point
|
|
5
5
|
*
|
|
6
|
+
* PHASE 21.6.1: Two-Phase CLI Bootstrap
|
|
7
|
+
*
|
|
8
|
+
* Phase A: Raw argv parsing with zero side effects
|
|
9
|
+
* Phase B: Dispatch - inspection commands bypass execution bootstrap
|
|
10
|
+
*
|
|
6
11
|
* Commands:
|
|
7
12
|
* - verax (smart default with URL detection/prompting)
|
|
8
13
|
* - verax run --url <url> (strict, non-interactive)
|
|
@@ -22,11 +27,47 @@ import { defaultCommand } from './commands/default.js';
|
|
|
22
27
|
import { runCommand } from './commands/run.js';
|
|
23
28
|
import { inspectCommand } from './commands/inspect.js';
|
|
24
29
|
import { doctorCommand } from './commands/doctor.js';
|
|
30
|
+
import { gatesCommand } from './commands/gates.js';
|
|
31
|
+
import { gaCommand } from './commands/ga.js';
|
|
32
|
+
import { releaseCheckCommand } from './commands/release-check.js';
|
|
33
|
+
import { securityCheckCommand } from './commands/security-check.js';
|
|
34
|
+
import { baselineCommand } from './commands/baseline.js';
|
|
35
|
+
import { truthCommand } from './commands/truth.js';
|
|
25
36
|
import { getExitCode, UsageError } from './util/errors.js';
|
|
37
|
+
import { getSourceCodeRequirementBanner } from '../verax/core/product-definition.js';
|
|
38
|
+
import { enableInspectionMode, disableInspectionMode } from './util/bootstrap-guard.js';
|
|
26
39
|
|
|
27
40
|
const __filename = fileURLToPath(import.meta.url);
|
|
28
41
|
const __dirname = dirname(__filename);
|
|
29
42
|
|
|
43
|
+
/**
|
|
44
|
+
* PHASE 21.6.1: CLI Self-Identification
|
|
45
|
+
* Prints diagnostic information to identify which binary is executed
|
|
46
|
+
*/
|
|
47
|
+
function printCLIIdentity(args) {
|
|
48
|
+
const verbose = args.includes('--verbose');
|
|
49
|
+
const debugCli = process.env.VERAX_DEBUG_CLI === '1';
|
|
50
|
+
|
|
51
|
+
if (!verbose && !debugCli) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
console.error('=== VERAX CLI IDENTITY ===');
|
|
56
|
+
console.error(`process.argv[1]: ${process.argv[1]}`);
|
|
57
|
+
console.error(`__filename: ${__filename}`);
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const pkgPath = resolve(__dirname, '../../package.json');
|
|
61
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
62
|
+
console.error(`package.json version: ${pkg.version}`);
|
|
63
|
+
console.error(`package.json location: ${pkgPath}`);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error(`Failed to read package.json: ${error.message}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
console.error('========================');
|
|
69
|
+
}
|
|
70
|
+
|
|
30
71
|
// Read package.json for version
|
|
31
72
|
function getVersion() {
|
|
32
73
|
try {
|
|
@@ -38,84 +79,263 @@ function getVersion() {
|
|
|
38
79
|
}
|
|
39
80
|
}
|
|
40
81
|
|
|
41
|
-
|
|
42
|
-
|
|
82
|
+
/**
|
|
83
|
+
* PHASE A: Raw argv parsing with zero side effects
|
|
84
|
+
*
|
|
85
|
+
* @param {string[]} args - Raw command line arguments
|
|
86
|
+
* @returns {Object} Parsed command structure
|
|
87
|
+
*/
|
|
88
|
+
function parseCommand(args) {
|
|
89
|
+
// Handle --version (no side effects)
|
|
90
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
91
|
+
return { type: 'version' };
|
|
92
|
+
}
|
|
43
93
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
94
|
+
// Handle explicit --help (no side effects)
|
|
95
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
96
|
+
return { type: 'help' };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// If no args, default to smart mode
|
|
100
|
+
if (args.length === 0) {
|
|
101
|
+
return { type: 'default', options: {} };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const command = args[0];
|
|
105
|
+
|
|
106
|
+
// Inspection commands (must bypass execution bootstrap)
|
|
107
|
+
if (command === 'inspect') {
|
|
108
|
+
if (args.length < 2) {
|
|
109
|
+
throw new UsageError('inspect command requires a run path argument');
|
|
49
110
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
111
|
+
return {
|
|
112
|
+
type: 'inspect',
|
|
113
|
+
runPath: args[1],
|
|
114
|
+
json: args.includes('--json'),
|
|
115
|
+
timeline: args.includes('--timeline'),
|
|
116
|
+
decisions: args.includes('--decisions'),
|
|
117
|
+
failures: args.includes('--failures'),
|
|
118
|
+
performance: args.includes('--performance'),
|
|
119
|
+
evidence: args.includes('--evidence')
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (command === 'gates') {
|
|
124
|
+
return {
|
|
125
|
+
type: 'gates',
|
|
126
|
+
json: args.includes('--json'),
|
|
127
|
+
verbose: args.includes('--verbose')
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (command === 'ga') {
|
|
132
|
+
return {
|
|
133
|
+
type: 'ga',
|
|
134
|
+
runId: parseArg(args, '--run-id'),
|
|
135
|
+
json: args.includes('--json')
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (command === 'release:check' || command === 'release-check') {
|
|
140
|
+
return {
|
|
141
|
+
type: 'release:check',
|
|
142
|
+
json: args.includes('--json')
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (command === 'security:check' || command === 'security-check') {
|
|
147
|
+
return {
|
|
148
|
+
type: 'security:check',
|
|
149
|
+
json: args.includes('--json')
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (command === 'baseline') {
|
|
154
|
+
return {
|
|
155
|
+
type: 'baseline',
|
|
156
|
+
json: args.includes('--json')
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (command === 'truth') {
|
|
161
|
+
return {
|
|
162
|
+
type: 'truth',
|
|
163
|
+
runId: parseArg(args, '--run-id'),
|
|
164
|
+
json: args.includes('--json')
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (command === 'doctor') {
|
|
169
|
+
const allowedFlags = new Set(['--json']);
|
|
170
|
+
const extraFlags = args.slice(1).filter((a) => a.startsWith('-') && !allowedFlags.has(a));
|
|
171
|
+
return {
|
|
172
|
+
type: 'doctor',
|
|
173
|
+
json: args.includes('--json'),
|
|
174
|
+
extraFlags
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Execution commands
|
|
179
|
+
if (command === 'run') {
|
|
180
|
+
const url = parseArg(args, '--url');
|
|
181
|
+
const fixture = parseArg(args, '--fixture');
|
|
182
|
+
if (!url && !fixture) {
|
|
183
|
+
throw new UsageError('run command requires --url <url> or --fixture <fixture> argument');
|
|
55
184
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
185
|
+
return {
|
|
186
|
+
type: 'run',
|
|
187
|
+
url,
|
|
188
|
+
fixture,
|
|
189
|
+
src: parseArg(args, '--src') || '.',
|
|
190
|
+
out: parseArg(args, '--out') || '.verax',
|
|
191
|
+
json: args.includes('--json'),
|
|
192
|
+
verbose: args.includes('--verbose'),
|
|
193
|
+
determinism: args.includes('--determinism'),
|
|
194
|
+
determinismRuns: args.includes('--determinism') ? parseInt(parseArg(args, '--determinism-runs') || '2', 10) : 0
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (command === 'help' || command === '--help' || command === '-h') {
|
|
199
|
+
return { type: 'help' };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Default command: smart scanning mode
|
|
203
|
+
return {
|
|
204
|
+
type: 'default',
|
|
205
|
+
options: {
|
|
206
|
+
url: parseArg(args, '--url'),
|
|
207
|
+
src: parseArg(args, '--src') || '.',
|
|
208
|
+
out: parseArg(args, '--out') || '.verax',
|
|
209
|
+
json: args.includes('--json'),
|
|
210
|
+
verbose: args.includes('--verbose')
|
|
61
211
|
}
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* PHASE B: Dispatch with isolation enforcement
|
|
217
|
+
*
|
|
218
|
+
* @param {Object} parsed - Parsed command from Phase A
|
|
219
|
+
*/
|
|
220
|
+
async function dispatch(parsed) {
|
|
221
|
+
try {
|
|
222
|
+
// Inspection commands: enable guard mode
|
|
223
|
+
const isInspectionCommand = ['inspect', 'gates', 'ga', 'doctor', 'release:check', 'security:check', 'baseline', 'truth'].includes(parsed.type);
|
|
62
224
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// Handle 'run' command
|
|
66
|
-
if (command === 'run') {
|
|
67
|
-
const url = parseArg(args, '--url');
|
|
68
|
-
const src = parseArg(args, '--src') || '.';
|
|
69
|
-
const out = parseArg(args, '--out') || '.verax';
|
|
70
|
-
const json = args.includes('--json');
|
|
71
|
-
const verbose = args.includes('--verbose');
|
|
72
|
-
|
|
73
|
-
if (!url) {
|
|
74
|
-
throw new UsageError('run command requires --url <url> argument');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
await runCommand({ url, src, out, json, verbose });
|
|
78
|
-
process.exit(0);
|
|
225
|
+
if (isInspectionCommand) {
|
|
226
|
+
enableInspectionMode();
|
|
79
227
|
}
|
|
80
228
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
229
|
+
try {
|
|
230
|
+
switch (parsed.type) {
|
|
231
|
+
case 'version':
|
|
232
|
+
console.log(`verax ${getVersion()}`);
|
|
233
|
+
process.exit(0);
|
|
234
|
+
break;
|
|
235
|
+
|
|
236
|
+
case 'help':
|
|
237
|
+
showHelp();
|
|
238
|
+
process.exit(0);
|
|
239
|
+
break;
|
|
240
|
+
|
|
241
|
+
case 'inspect':
|
|
242
|
+
await inspectCommand(parsed.runPath, {
|
|
243
|
+
json: parsed.json,
|
|
244
|
+
timeline: parsed.timeline,
|
|
245
|
+
decisions: parsed.decisions,
|
|
246
|
+
failures: parsed.failures,
|
|
247
|
+
performance: parsed.performance,
|
|
248
|
+
evidence: parsed.evidence
|
|
249
|
+
});
|
|
250
|
+
process.exit(0);
|
|
251
|
+
break;
|
|
252
|
+
|
|
253
|
+
case 'gates':
|
|
254
|
+
await gatesCommand({ json: parsed.json, verbose: parsed.verbose });
|
|
255
|
+
// gatesCommand handles exit code internally
|
|
256
|
+
return;
|
|
257
|
+
|
|
258
|
+
case 'ga':
|
|
259
|
+
await gaCommand({ runId: parsed.runId, json: parsed.json });
|
|
260
|
+
// gaCommand handles exit code internally
|
|
261
|
+
return;
|
|
262
|
+
|
|
263
|
+
case 'release:check':
|
|
264
|
+
await releaseCheckCommand({ json: parsed.json });
|
|
265
|
+
// releaseCheckCommand handles exit code internally
|
|
266
|
+
return;
|
|
267
|
+
|
|
268
|
+
case 'security:check':
|
|
269
|
+
await securityCheckCommand({ json: parsed.json });
|
|
270
|
+
// securityCheckCommand handles exit code internally
|
|
271
|
+
return;
|
|
272
|
+
|
|
273
|
+
case 'baseline':
|
|
274
|
+
await baselineCommand(process.cwd(), { json: parsed.json });
|
|
275
|
+
process.exit(0);
|
|
276
|
+
break;
|
|
277
|
+
|
|
278
|
+
case 'truth':
|
|
279
|
+
await truthCommand(process.cwd(), { json: parsed.json, runId: parsed.runId });
|
|
280
|
+
process.exit(0);
|
|
281
|
+
break;
|
|
282
|
+
|
|
283
|
+
case 'doctor':
|
|
284
|
+
await doctorCommand({ json: parsed.json, extraFlags: parsed.extraFlags });
|
|
285
|
+
process.exit(0);
|
|
286
|
+
break;
|
|
287
|
+
|
|
288
|
+
case 'run':
|
|
289
|
+
await runCommand({
|
|
290
|
+
url: parsed.url,
|
|
291
|
+
fixture: parsed.fixture,
|
|
292
|
+
src: parsed.src,
|
|
293
|
+
out: parsed.out,
|
|
294
|
+
json: parsed.json,
|
|
295
|
+
verbose: parsed.verbose,
|
|
296
|
+
determinism: parsed.determinism,
|
|
297
|
+
determinismRuns: parsed.determinismRuns
|
|
298
|
+
});
|
|
299
|
+
process.exit(0);
|
|
300
|
+
break;
|
|
301
|
+
|
|
302
|
+
case 'default':
|
|
303
|
+
await defaultCommand(parsed.options);
|
|
304
|
+
process.exit(0);
|
|
305
|
+
break;
|
|
306
|
+
|
|
307
|
+
default:
|
|
308
|
+
throw new UsageError(`Unknown command: ${parsed.type}`);
|
|
309
|
+
}
|
|
310
|
+
} finally {
|
|
311
|
+
if (isInspectionCommand) {
|
|
312
|
+
disableInspectionMode();
|
|
85
313
|
}
|
|
86
|
-
|
|
87
|
-
const runPath = args[1];
|
|
88
|
-
const json = args.includes('--json');
|
|
89
|
-
|
|
90
|
-
await inspectCommand(runPath, { json });
|
|
91
|
-
process.exit(0);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Handle 'doctor' command
|
|
95
|
-
if (command === 'doctor') {
|
|
96
|
-
const allowedFlags = new Set(['--json']);
|
|
97
|
-
const extraFlags = args.slice(1).filter((a) => a.startsWith('-') && !allowedFlags.has(a));
|
|
98
|
-
const json = args.includes('--json');
|
|
99
|
-
await doctorCommand({ json, extraFlags });
|
|
100
|
-
process.exit(0);
|
|
101
314
|
}
|
|
102
|
-
|
|
103
|
-
//
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
process.exit(0);
|
|
315
|
+
} catch (error) {
|
|
316
|
+
// Print error message
|
|
317
|
+
if (error.message) {
|
|
318
|
+
console.error(`Error: ${error.message}`);
|
|
107
319
|
}
|
|
108
320
|
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
321
|
+
// Get exit code
|
|
322
|
+
const exitCode = getExitCode(error);
|
|
323
|
+
process.exit(exitCode);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
async function main() {
|
|
328
|
+
const args = process.argv.slice(2);
|
|
329
|
+
|
|
330
|
+
// PHASE 21.6.1: Print CLI identity for debugging
|
|
331
|
+
printCLIIdentity(args);
|
|
332
|
+
|
|
333
|
+
try {
|
|
334
|
+
// PHASE A: Parse command (zero side effects)
|
|
335
|
+
const parsed = parseCommand(args);
|
|
116
336
|
|
|
117
|
-
|
|
118
|
-
|
|
337
|
+
// PHASE B: Dispatch with isolation enforcement
|
|
338
|
+
await dispatch(parsed);
|
|
119
339
|
} catch (error) {
|
|
120
340
|
// Print error message
|
|
121
341
|
if (error.message) {
|
|
@@ -130,24 +350,41 @@ async function main() {
|
|
|
130
350
|
|
|
131
351
|
function showHelp() {
|
|
132
352
|
const version = getVersion();
|
|
353
|
+
const banner = getSourceCodeRequirementBanner();
|
|
133
354
|
console.log(`
|
|
134
355
|
verax ${version}
|
|
135
356
|
VERAX — Silent failure detection for websites
|
|
136
357
|
|
|
358
|
+
${banner}
|
|
359
|
+
Canonical product contract: docs/README.md
|
|
360
|
+
|
|
137
361
|
USAGE:
|
|
138
362
|
verax [options] Smart mode (detects/prompts for URL)
|
|
139
363
|
verax run --url <url> [options] Strict mode (non-interactive, CI-friendly)
|
|
140
364
|
verax inspect <runPath> [--json] Inspect an existing run
|
|
365
|
+
verax inspect <runPath> --timeline Show chronological timeline
|
|
366
|
+
verax inspect <runPath> --decisions Show decision trace
|
|
367
|
+
verax inspect <runPath> --failures Show failure ledger
|
|
368
|
+
verax inspect <runPath> --performance Show performance metrics
|
|
369
|
+
verax inspect <runPath> --evidence Show evidence cross-index
|
|
141
370
|
verax doctor [--json] Diagnose local environment
|
|
371
|
+
verax gates [--json] [--verbose] Evaluate capability gates (PHASE 19)
|
|
372
|
+
verax ga [--run-id <id>] [--json] Evaluate GA readiness (PHASE 21.6)
|
|
373
|
+
verax release:check [--json] Check release readiness (PHASE 21.7)
|
|
374
|
+
verax security:check [--json] Check security baseline (PHASE 21.8)
|
|
375
|
+
verax baseline [--json] Show baseline hash and drift status (PHASE 21.11)
|
|
376
|
+
verax truth [--run-id <id>] [--json] Show truth certificate (PHASE 21.11)
|
|
142
377
|
verax --version Show version
|
|
143
378
|
verax --help Show this help
|
|
144
379
|
|
|
145
380
|
OPTIONS:
|
|
146
381
|
--url <url> Target URL to scan
|
|
147
|
-
--src <path> Source directory (default: .)
|
|
382
|
+
--src <path> Source directory (default: .) — required; URL-only scans are blocked
|
|
148
383
|
--out <path> Output directory for artifacts (default: .verax)
|
|
149
384
|
--json Output as JSON lines (progress events)
|
|
150
385
|
--verbose Verbose output
|
|
386
|
+
--determinism Run determinism check (executes scan multiple times and compares results)
|
|
387
|
+
--determinism-runs <N> Number of runs for determinism check (default: 2)
|
|
151
388
|
--help Show this help
|
|
152
389
|
--version Show version
|
|
153
390
|
|