@veraxhq/verax 0.3.0 → 0.4.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 +28 -20
- package/bin/verax.js +11 -18
- package/package.json +28 -7
- package/src/cli/commands/baseline.js +1 -2
- package/src/cli/commands/default.js +72 -81
- package/src/cli/commands/doctor.js +29 -0
- package/src/cli/commands/ga.js +3 -0
- package/src/cli/commands/gates.js +1 -1
- package/src/cli/commands/inspect.js +6 -133
- package/src/cli/commands/release-check.js +2 -0
- package/src/cli/commands/run.js +74 -246
- package/src/cli/commands/security-check.js +2 -1
- package/src/cli/commands/truth.js +0 -1
- package/src/cli/entry.js +82 -309
- package/src/cli/util/angular-component-extractor.js +2 -2
- package/src/cli/util/angular-navigation-detector.js +2 -2
- package/src/cli/util/ast-interactive-detector.js +4 -6
- package/src/cli/util/ast-network-detector.js +3 -3
- package/src/cli/util/ast-promise-extractor.js +581 -0
- package/src/cli/util/ast-usestate-detector.js +3 -3
- package/src/cli/util/atomic-write.js +12 -1
- package/src/cli/util/console-reporter.js +72 -0
- package/src/cli/util/detection-engine.js +105 -41
- package/src/cli/util/determinism-runner.js +2 -1
- package/src/cli/util/determinism-writer.js +1 -1
- package/src/cli/util/digest-engine.js +359 -0
- package/src/cli/util/dom-diff.js +226 -0
- package/src/cli/util/env-url.js +0 -4
- package/src/cli/util/evidence-engine.js +287 -0
- package/src/cli/util/expectation-extractor.js +217 -367
- package/src/cli/util/findings-writer.js +19 -126
- package/src/cli/util/framework-detector.js +572 -0
- package/src/cli/util/idgen.js +1 -1
- package/src/cli/util/interaction-planner.js +529 -0
- package/src/cli/util/learn-writer.js +2 -2
- package/src/cli/util/ledger-writer.js +110 -0
- package/src/cli/util/monorepo-resolver.js +162 -0
- package/src/cli/util/observation-engine.js +127 -278
- package/src/cli/util/observe-writer.js +2 -2
- package/src/cli/util/paths.js +12 -3
- package/src/cli/util/project-discovery.js +284 -3
- package/src/cli/util/project-writer.js +2 -2
- package/src/cli/util/run-id.js +23 -27
- package/src/cli/util/run-result.js +778 -0
- package/src/cli/util/selector-resolver.js +235 -0
- package/src/cli/util/summary-writer.js +2 -1
- package/src/cli/util/svelte-navigation-detector.js +3 -3
- package/src/cli/util/svelte-sfc-extractor.js +0 -1
- package/src/cli/util/svelte-state-detector.js +1 -2
- package/src/cli/util/trust-activation-integration.js +496 -0
- package/src/cli/util/trust-activation-wrapper.js +85 -0
- package/src/cli/util/trust-integration-hooks.js +164 -0
- package/src/cli/util/types.js +153 -0
- package/src/cli/util/url-validation.js +40 -0
- package/src/cli/util/vue-navigation-detector.js +4 -3
- package/src/cli/util/vue-sfc-extractor.js +1 -2
- package/src/cli/util/vue-state-detector.js +1 -1
- package/src/types/fs-augment.d.ts +23 -0
- package/src/types/global.d.ts +137 -0
- package/src/types/internal-types.d.ts +35 -0
- package/src/verax/cli/finding-explainer.js +3 -56
- package/src/verax/cli/init.js +4 -18
- package/src/verax/core/action-classifier.js +4 -3
- package/src/verax/core/artifacts/registry.js +0 -15
- package/src/verax/core/artifacts/verifier.js +18 -8
- package/src/verax/core/baseline/baseline.snapshot.js +2 -0
- package/src/verax/core/capabilities/gates.js +7 -1
- package/src/verax/core/confidence/confidence-compute.js +14 -7
- package/src/verax/core/confidence/confidence.loader.js +1 -0
- package/src/verax/core/confidence-engine-refactor.js +8 -3
- package/src/verax/core/confidence-engine.js +162 -23
- package/src/verax/core/contracts/types.js +1 -0
- package/src/verax/core/contracts/validators.js +79 -4
- package/src/verax/core/decision-snapshot.js +3 -30
- package/src/verax/core/decisions/decision.trace.js +2 -0
- package/src/verax/core/determinism/contract-writer.js +2 -2
- package/src/verax/core/determinism/contract.js +1 -1
- package/src/verax/core/determinism/diff.js +42 -1
- package/src/verax/core/determinism/engine.js +7 -6
- package/src/verax/core/determinism/finding-identity.js +3 -2
- package/src/verax/core/determinism/normalize.js +32 -4
- package/src/verax/core/determinism/report-writer.js +1 -0
- package/src/verax/core/determinism/run-fingerprint.js +7 -2
- package/src/verax/core/dynamic-route-intelligence.js +8 -7
- package/src/verax/core/evidence/evidence-capture-service.js +1 -0
- package/src/verax/core/evidence/evidence-intent-ledger.js +2 -1
- package/src/verax/core/evidence-builder.js +2 -2
- package/src/verax/core/execution-mode-context.js +1 -1
- package/src/verax/core/execution-mode-detector.js +5 -3
- package/src/verax/core/failures/exit-codes.js +39 -37
- package/src/verax/core/failures/failure-summary.js +1 -1
- package/src/verax/core/failures/failure.factory.js +3 -3
- package/src/verax/core/failures/failure.ledger.js +3 -2
- package/src/verax/core/ga/ga.artifact.js +1 -1
- package/src/verax/core/ga/ga.contract.js +3 -2
- package/src/verax/core/ga/ga.enforcer.js +1 -0
- package/src/verax/core/guardrails/policy.loader.js +1 -0
- package/src/verax/core/guardrails/truth-reconciliation.js +1 -1
- package/src/verax/core/guardrails-engine.js +2 -2
- package/src/verax/core/incremental-store.js +1 -0
- package/src/verax/core/integrity/budget.js +138 -0
- package/src/verax/core/integrity/determinism.js +342 -0
- package/src/verax/core/integrity/integrity.js +208 -0
- package/src/verax/core/integrity/poisoning.js +108 -0
- package/src/verax/core/integrity/transaction.js +140 -0
- package/src/verax/core/observe/run-timeline.js +2 -0
- package/src/verax/core/perf/perf.report.js +2 -0
- package/src/verax/core/pipeline-tracker.js +5 -0
- package/src/verax/core/release/provenance.builder.js +73 -214
- package/src/verax/core/release/release.enforcer.js +14 -9
- package/src/verax/core/release/reproducibility.check.js +1 -0
- package/src/verax/core/release/sbom.builder.js +32 -23
- package/src/verax/core/replay-validator.js +2 -0
- package/src/verax/core/replay.js +4 -0
- package/src/verax/core/report/cross-index.js +6 -3
- package/src/verax/core/report/human-summary.js +141 -1
- package/src/verax/core/route-intelligence.js +4 -3
- package/src/verax/core/run-id.js +6 -3
- package/src/verax/core/run-manifest.js +4 -3
- package/src/verax/core/security/secrets.scan.js +10 -7
- package/src/verax/core/security/security.enforcer.js +4 -0
- package/src/verax/core/security/supplychain.policy.js +9 -1
- package/src/verax/core/security/vuln.scan.js +2 -2
- package/src/verax/core/truth/truth.certificate.js +3 -1
- package/src/verax/core/ui-feedback-intelligence.js +12 -46
- package/src/verax/detect/conditional-ui-silent-failure.js +84 -0
- package/src/verax/detect/confidence-engine.js +100 -660
- package/src/verax/detect/confidence-helper.js +1 -0
- package/src/verax/detect/detection-engine.js +1 -18
- package/src/verax/detect/dynamic-route-findings.js +17 -14
- package/src/verax/detect/expectation-chain-detector.js +1 -1
- package/src/verax/detect/expectation-model.js +3 -5
- package/src/verax/detect/failure-cause-inference.js +293 -0
- package/src/verax/detect/findings-writer.js +126 -166
- package/src/verax/detect/flow-detector.js +2 -2
- package/src/verax/detect/form-silent-failure.js +98 -0
- package/src/verax/detect/index.js +51 -234
- package/src/verax/detect/invariants-enforcer.js +147 -0
- package/src/verax/detect/journey-stall-detector.js +4 -4
- package/src/verax/detect/navigation-silent-failure.js +82 -0
- package/src/verax/detect/problem-aggregator.js +361 -0
- package/src/verax/detect/route-findings.js +7 -6
- package/src/verax/detect/summary-writer.js +477 -0
- package/src/verax/detect/test-failure-cause-inference.js +314 -0
- package/src/verax/detect/ui-feedback-findings.js +18 -18
- package/src/verax/detect/verdict-engine.js +3 -57
- package/src/verax/detect/view-switch-correlator.js +2 -2
- package/src/verax/flow/flow-engine.js +2 -1
- package/src/verax/flow/flow-spec.js +0 -6
- package/src/verax/index.js +48 -412
- package/src/verax/intel/ts-program.js +1 -0
- package/src/verax/intel/vue-navigation-extractor.js +3 -0
- package/src/verax/learn/action-contract-extractor.js +67 -682
- package/src/verax/learn/ast-contract-extractor.js +1 -1
- package/src/verax/learn/flow-extractor.js +1 -0
- package/src/verax/learn/project-detector.js +5 -0
- package/src/verax/learn/react-router-extractor.js +2 -0
- package/src/verax/learn/route-validator.js +1 -4
- package/src/verax/learn/source-instrumenter.js +1 -0
- package/src/verax/learn/state-extractor.js +2 -1
- package/src/verax/learn/static-extractor.js +1 -0
- package/src/verax/observe/coverage-gaps.js +132 -0
- package/src/verax/observe/expectation-handler.js +126 -0
- package/src/verax/observe/incremental-skip.js +46 -0
- package/src/verax/observe/index.js +735 -84
- package/src/verax/observe/interaction-executor.js +192 -0
- package/src/verax/observe/interaction-runner.js +782 -530
- package/src/verax/observe/network-firewall.js +86 -0
- package/src/verax/observe/observation-builder.js +169 -0
- package/src/verax/observe/observe-context.js +1 -1
- package/src/verax/observe/observe-helpers.js +2 -1
- package/src/verax/observe/observe-runner.js +28 -24
- package/src/verax/observe/observers/budget-observer.js +3 -3
- package/src/verax/observe/observers/console-observer.js +4 -4
- package/src/verax/observe/observers/coverage-observer.js +4 -4
- package/src/verax/observe/observers/interaction-observer.js +3 -3
- package/src/verax/observe/observers/navigation-observer.js +4 -4
- package/src/verax/observe/observers/network-observer.js +4 -4
- package/src/verax/observe/observers/safety-observer.js +1 -1
- package/src/verax/observe/observers/ui-feedback-observer.js +4 -4
- package/src/verax/observe/page-traversal.js +138 -0
- package/src/verax/observe/snapshot-ops.js +94 -0
- package/src/verax/observe/ui-signal-sensor.js +2 -148
- package/src/verax/scan-summary-writer.js +10 -42
- package/src/verax/shared/artifact-manager.js +30 -13
- package/src/verax/shared/caching.js +1 -0
- package/src/verax/shared/expectation-tracker.js +1 -0
- package/src/verax/shared/zip-artifacts.js +6 -0
- package/src/verax/core/confidence-engine.js.backup +0 -471
- package/src/verax/shared/config-loader.js +0 -169
- /package/src/verax/shared/{expectation-proof.js → expectation-validation.js} +0 -0
package/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# 🛡️ VERAX
|
|
2
2
|
|
|
3
|
-
> **SOURCE CODE REQUIRED** — VERAX requires local access to source code. It is not a public website scanner. See [docs/README.md](docs/README.md) for the canonical product contract.
|
|
4
|
-
|
|
5
3
|
A forensic observation engine for real user outcomes
|
|
6
4
|
|
|
7
5
|
VERAX observes and reports gaps between what your code explicitly promises and what users can actually observe.
|
|
@@ -53,11 +51,11 @@ It means the observation produced no verifiable effect for the promise being eva
|
|
|
53
51
|
|
|
54
52
|
🧠 Extracts expectations from source code using static analysis:
|
|
55
53
|
|
|
56
|
-
Navigation from HTML links
|
|
54
|
+
Navigation from HTML links, React Router, Vue Router, and Next.js routes
|
|
57
55
|
|
|
58
56
|
Network actions from fetch / axios calls with static URLs
|
|
59
57
|
|
|
60
|
-
State mutations from React useState, Redux
|
|
58
|
+
State mutations from React useState, Redux, Vuex, Pinia, Zustand set operations
|
|
61
59
|
|
|
62
60
|
🖱️ Observes websites like a real user using Playwright
|
|
63
61
|
(clicks, forms, navigation, scrolling)
|
|
@@ -78,11 +76,15 @@ DOM and state changes
|
|
|
78
76
|
|
|
79
77
|
🧱 Supports real-world projects:
|
|
80
78
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
React SPAs
|
|
79
|
+
**Fully verified (production-ready):**
|
|
80
|
+
- Static HTML sites
|
|
81
|
+
- React SPAs (with react-router-dom)
|
|
84
82
|
|
|
85
|
-
|
|
83
|
+
**Supported (learn-only / partial observation):**
|
|
84
|
+
- Next.js (App Router & Pages Router)
|
|
85
|
+
- Vue.js (with Vue Router)
|
|
86
|
+
- Angular
|
|
87
|
+
- SvelteKit
|
|
86
88
|
|
|
87
89
|
🔐 Protects privacy by automatically redacting secrets and sensitive data
|
|
88
90
|
|
|
@@ -231,21 +233,27 @@ MEDIUM (60–79) — likely discrepancy with some ambiguity
|
|
|
231
233
|
|
|
232
234
|
LOW (<60) — weak or partial evidence; interpret cautiously
|
|
233
235
|
|
|
234
|
-
🧭
|
|
236
|
+
🧭 When VERAX is a good fit
|
|
237
|
+
|
|
238
|
+
SaaS signup and pricing flows
|
|
239
|
+
|
|
240
|
+
React and Next.js projects
|
|
241
|
+
|
|
242
|
+
CI pipelines that need UX reality checks
|
|
243
|
+
|
|
244
|
+
Teams that value evidence over assumptions
|
|
245
|
+
|
|
246
|
+
🚫 When VERAX is NOT a good fit
|
|
247
|
+
|
|
248
|
+
Internal admin dashboards
|
|
249
|
+
|
|
250
|
+
Authentication-heavy systems
|
|
235
251
|
|
|
236
|
-
|
|
237
|
-
- CI pipelines that can mount the repository so VERAX can analyze it
|
|
238
|
-
- Developer workstations that need evidence-backed silent failure detection
|
|
239
|
-
- Teams that value deterministic evidence over heuristics or AI guesses
|
|
240
|
-
- Demo projects in this repo (see [demos/](demos/))
|
|
252
|
+
Apps built around highly dynamic routing
|
|
241
253
|
|
|
242
|
-
|
|
254
|
+
Unsupported frameworks
|
|
243
255
|
|
|
244
|
-
|
|
245
|
-
- Production monitoring or hosted/public scanning
|
|
246
|
-
- Highly dynamic routing without static promises to analyze
|
|
247
|
-
- Closed-source third-party targets where code is unavailable
|
|
248
|
-
- Using VERAX as a drop-in QA replacement
|
|
256
|
+
Teams expecting a full QA replacement
|
|
249
257
|
|
|
250
258
|
🧪 Project status
|
|
251
259
|
|
package/bin/verax.js
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* VERAX CLI Shim
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import('../src/cli/entry.js').catch((error) => {
|
|
13
|
-
console.error(`Failed to load CLI: ${error.message}`);
|
|
14
|
-
if (error.stack) {
|
|
15
|
-
console.error(error.stack);
|
|
16
|
-
}
|
|
17
|
-
process.exit(2);
|
|
18
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* VERAX CLI Shim
|
|
5
|
+
* Delegates to src/cli/entry.js
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import('../src/cli/entry.js').catch((error) => {
|
|
9
|
+
console.error(`Failed to load CLI: ${error.message}`);
|
|
10
|
+
process.exit(2);
|
|
11
|
+
});
|
package/package.json
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veraxhq/verax",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Public Flow Sanity Guard — Trust-Locked, Deterministic, CI-Safe.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"public-flows",
|
|
7
|
+
"pre-auth",
|
|
8
|
+
"sanity-guard",
|
|
9
|
+
"silent-failures",
|
|
10
|
+
"deterministic",
|
|
11
|
+
"trust-lock",
|
|
12
|
+
"ci-safe",
|
|
13
|
+
"playwright"
|
|
14
|
+
],
|
|
5
15
|
"license": "MIT",
|
|
6
16
|
"type": "module",
|
|
7
17
|
"bin": {
|
|
8
18
|
"verax": "bin/verax.js"
|
|
9
19
|
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/odavlstudio/verax.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/odavlstudio/verax/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/odavlstudio/verax#readme",
|
|
10
28
|
"files": [
|
|
11
29
|
"bin/",
|
|
12
30
|
"src/",
|
|
@@ -14,27 +32,30 @@
|
|
|
14
32
|
"LICENSE"
|
|
15
33
|
],
|
|
16
34
|
"scripts": {
|
|
17
|
-
"test": "node
|
|
18
|
-
"test:pack": "node
|
|
35
|
+
"test": "node test/infrastructure/test-runner-wrapper.js",
|
|
36
|
+
"test:pack": "node test/infrastructure/test-pack.js",
|
|
19
37
|
"verify-release": "node scripts/verify-release.js",
|
|
20
38
|
"lint": "eslint . --max-warnings 0",
|
|
21
39
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
22
40
|
},
|
|
23
41
|
"dependencies": {
|
|
42
|
+
"@babel/parser": "^7.28.5",
|
|
43
|
+
"@babel/traverse": "^7.28.5",
|
|
24
44
|
"glob": "^10.3.10",
|
|
25
45
|
"inquirer": "^9.2.15",
|
|
26
46
|
"node-html-parser": "^7.0.1",
|
|
27
47
|
"playwright": "^1.40.0",
|
|
28
48
|
"typescript": "^5.9.3"
|
|
29
49
|
},
|
|
50
|
+
"optionalDependencies": {
|
|
51
|
+
"pngjs": "^7.0.0"
|
|
52
|
+
},
|
|
30
53
|
"engines": {
|
|
31
54
|
"node": ">=18.0.0"
|
|
32
55
|
},
|
|
33
56
|
"devDependencies": {
|
|
34
|
-
"@babel/parser": "^7.28.5",
|
|
35
|
-
"@babel/traverse": "^7.28.5",
|
|
36
57
|
"@reduxjs/toolkit": "^2.11.2",
|
|
37
|
-
"@
|
|
58
|
+
"@types/node": "^18.0.0",
|
|
38
59
|
"eslint": "^8.57.0",
|
|
39
60
|
"next": "^16.1.1",
|
|
40
61
|
"react": "^19.2.3",
|
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
* `verax baseline` - Shows baseline hash and drift status
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { resolve } from 'path';
|
|
8
7
|
import { loadBaselineSnapshot, buildBaselineSnapshot } from '../../verax/core/baseline/baseline.snapshot.js';
|
|
9
|
-
import { compareBaselines
|
|
8
|
+
import { compareBaselines } from '../../verax/core/baseline/baseline.enforcer.js';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* Baseline command
|
|
@@ -3,7 +3,6 @@ import { existsSync, readFileSync } from 'fs';
|
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { dirname } from 'path';
|
|
5
5
|
import inquirer from 'inquirer';
|
|
6
|
-
import { assertExecutionBootstrapAllowed } from '../util/bootstrap-guard.js';
|
|
7
6
|
import { DataError } from '../util/errors.js';
|
|
8
7
|
import { generateRunId } from '../util/run-id.js';
|
|
9
8
|
import { getRunPaths, ensureRunDirectories } from '../util/paths.js';
|
|
@@ -20,7 +19,8 @@ import { detectFindings } from '../util/detection-engine.js';
|
|
|
20
19
|
import { writeFindingsJson } from '../util/findings-writer.js';
|
|
21
20
|
import { writeSummaryJson } from '../util/summary-writer.js';
|
|
22
21
|
import { computeRuntimeBudget, withTimeout } from '../util/runtime-budget.js';
|
|
23
|
-
import {
|
|
22
|
+
import { saveDigest } from '../util/digest-engine.js';
|
|
23
|
+
import { ARTIFACT_REGISTRY, getArtifactVersions } from '../../verax/core/artifacts/registry.js';
|
|
24
24
|
|
|
25
25
|
const __filename = fileURLToPath(import.meta.url);
|
|
26
26
|
const __dirname = dirname(__filename);
|
|
@@ -28,10 +28,11 @@ const __dirname = dirname(__filename);
|
|
|
28
28
|
function getVersion() {
|
|
29
29
|
try {
|
|
30
30
|
const pkgPath = resolve(__dirname, '../../../package.json');
|
|
31
|
-
|
|
31
|
+
// @ts-expect-error - readFileSync with encoding returns string
|
|
32
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
32
33
|
return pkg.version;
|
|
33
34
|
} catch {
|
|
34
|
-
return '0.
|
|
35
|
+
return '0.2.0';
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -40,14 +41,16 @@ function getVersion() {
|
|
|
40
41
|
* Interactive mode with intelligent URL detection
|
|
41
42
|
*/
|
|
42
43
|
export async function defaultCommand(options = {}) {
|
|
44
|
+
// Interactive mode disabled by constitution: require explicit verax run --url
|
|
45
|
+
throw new DataError('Interactive mode is disabled. Use: verax run --url <url>');
|
|
46
|
+
|
|
47
|
+
/* eslint-disable no-unreachable */
|
|
43
48
|
const {
|
|
44
49
|
src = '.',
|
|
45
50
|
out = '.verax',
|
|
46
51
|
url = null,
|
|
47
52
|
json = false,
|
|
48
53
|
verbose = false,
|
|
49
|
-
determinism = false,
|
|
50
|
-
determinismRuns = 2,
|
|
51
54
|
} = options;
|
|
52
55
|
|
|
53
56
|
const projectRoot = resolve(process.cwd());
|
|
@@ -57,9 +60,6 @@ export async function defaultCommand(options = {}) {
|
|
|
57
60
|
if (!existsSync(srcPath)) {
|
|
58
61
|
throw new DataError(`Source directory not found: ${srcPath}`);
|
|
59
62
|
}
|
|
60
|
-
|
|
61
|
-
// Enforce local source availability (no URL-only scans)
|
|
62
|
-
assertHasLocalSource(srcPath);
|
|
63
63
|
|
|
64
64
|
// Create event emitter
|
|
65
65
|
const events = new RunEventEmitter();
|
|
@@ -101,7 +101,7 @@ export async function defaultCommand(options = {}) {
|
|
|
101
101
|
const failedAt = new Date().toISOString();
|
|
102
102
|
atomicWriteJson(paths.runStatusJson, {
|
|
103
103
|
contractVersion: 1,
|
|
104
|
-
artifactVersions:
|
|
104
|
+
artifactVersions: getArtifactVersions(),
|
|
105
105
|
status: 'FAILED',
|
|
106
106
|
runId,
|
|
107
107
|
startedAt,
|
|
@@ -110,8 +110,7 @@ export async function defaultCommand(options = {}) {
|
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
atomicWriteJson(paths.runMetaJson, {
|
|
113
|
-
contractVersion:
|
|
114
|
-
artifactVersions: paths.artifactVersions,
|
|
113
|
+
contractVersion: ARTIFACT_REGISTRY.runMeta.contractVersion,
|
|
115
114
|
veraxVersion: getVersion(),
|
|
116
115
|
nodeVersion: process.version,
|
|
117
116
|
platform: process.platform,
|
|
@@ -240,9 +239,6 @@ export async function defaultCommand(options = {}) {
|
|
|
240
239
|
console.log(''); // blank line
|
|
241
240
|
}
|
|
242
241
|
|
|
243
|
-
// PHASE 21.6.1: Runtime guard - crash if called during inspection
|
|
244
|
-
assertExecutionBootstrapAllowed('inquirer.prompt');
|
|
245
|
-
|
|
246
242
|
const answer = await inquirer.prompt([
|
|
247
243
|
{
|
|
248
244
|
type: 'input',
|
|
@@ -273,7 +269,7 @@ export async function defaultCommand(options = {}) {
|
|
|
273
269
|
});
|
|
274
270
|
|
|
275
271
|
// Generate run ID
|
|
276
|
-
let runId = generateRunId();
|
|
272
|
+
let runId = generateRunId(resolvedUrl);
|
|
277
273
|
if (verbose && !json) console.log(`Run ID: ${runId}`);
|
|
278
274
|
|
|
279
275
|
let paths = getRunPaths(projectRoot, out, runId);
|
|
@@ -290,15 +286,14 @@ export async function defaultCommand(options = {}) {
|
|
|
290
286
|
|
|
291
287
|
atomicWriteJson(paths.runStatusJson, {
|
|
292
288
|
contractVersion: 1,
|
|
293
|
-
artifactVersions:
|
|
289
|
+
artifactVersions: getArtifactVersions(),
|
|
294
290
|
status: 'RUNNING',
|
|
295
291
|
runId,
|
|
296
292
|
startedAt,
|
|
297
293
|
});
|
|
298
294
|
|
|
299
295
|
atomicWriteJson(paths.runMetaJson, {
|
|
300
|
-
contractVersion:
|
|
301
|
-
artifactVersions: paths.artifactVersions,
|
|
296
|
+
contractVersion: ARTIFACT_REGISTRY.runMeta.contractVersion,
|
|
302
297
|
veraxVersion: getVersion(),
|
|
303
298
|
nodeVersion: process.version,
|
|
304
299
|
platform: process.platform,
|
|
@@ -416,7 +411,8 @@ export async function defaultCommand(options = {}) {
|
|
|
416
411
|
const status = progress.observed ? '✓' : '✗';
|
|
417
412
|
console.log(` ${status} ${progress.index}/${expectations.length}`);
|
|
418
413
|
}
|
|
419
|
-
}
|
|
414
|
+
},
|
|
415
|
+
{}
|
|
420
416
|
),
|
|
421
417
|
'Observe'
|
|
422
418
|
);
|
|
@@ -555,9 +551,30 @@ export async function defaultCommand(options = {}) {
|
|
|
555
551
|
|
|
556
552
|
const completedAt = new Date().toISOString();
|
|
557
553
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
554
|
+
atomicWriteJson(paths.runStatusJson, {
|
|
555
|
+
status: 'COMPLETE',
|
|
556
|
+
runId,
|
|
557
|
+
startedAt,
|
|
558
|
+
completedAt,
|
|
559
|
+
contractVersion: 1,
|
|
560
|
+
artifactVersions: getArtifactVersions(),
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
atomicWriteJson(paths.runMetaJson, {
|
|
564
|
+
contractVersion: ARTIFACT_REGISTRY.runMeta.contractVersion,
|
|
565
|
+
veraxVersion: getVersion(),
|
|
566
|
+
nodeVersion: process.version,
|
|
567
|
+
platform: process.platform,
|
|
568
|
+
cwd: projectRoot,
|
|
569
|
+
command: 'default',
|
|
570
|
+
args: { url: resolvedUrl, src },
|
|
571
|
+
url: resolvedUrl,
|
|
572
|
+
src: srcPath,
|
|
573
|
+
startedAt,
|
|
574
|
+
completedAt,
|
|
575
|
+
error: null,
|
|
576
|
+
});
|
|
577
|
+
|
|
561
578
|
// Write summary with stable digest
|
|
562
579
|
writeSummaryJson(paths.summaryJson, {
|
|
563
580
|
runId,
|
|
@@ -577,6 +594,9 @@ export async function defaultCommand(options = {}) {
|
|
|
577
594
|
informational: detectData.stats?.informational || 0,
|
|
578
595
|
});
|
|
579
596
|
|
|
597
|
+
// Write detect results (or empty if detection failed)
|
|
598
|
+
writeFindingsJson(paths.baseDir, detectData);
|
|
599
|
+
|
|
580
600
|
// Write traces (include all events including heartbeats)
|
|
581
601
|
const allEvents = events.getEvents();
|
|
582
602
|
const tracesContent = allEvents
|
|
@@ -592,53 +612,11 @@ export async function defaultCommand(options = {}) {
|
|
|
592
612
|
|
|
593
613
|
// Write observe results
|
|
594
614
|
writeObserveJson(paths.baseDir, observeData);
|
|
595
|
-
|
|
596
|
-
// PHASE 6: Verify artifacts after all writers finish
|
|
597
|
-
const { verifyRun } = await import('../../verax/core/artifacts/verifier.js');
|
|
598
|
-
const verification = verifyRun(paths.baseDir, paths.artifactVersions);
|
|
599
|
-
|
|
600
|
-
// Determine final status based on verification
|
|
601
|
-
let finalStatus = 'COMPLETE';
|
|
602
|
-
if (!verification.ok) {
|
|
603
|
-
finalStatus = 'INVALID';
|
|
604
|
-
} else if (verification.warnings.length > 0) {
|
|
605
|
-
finalStatus = 'VALID_WITH_WARNINGS';
|
|
606
|
-
}
|
|
607
615
|
|
|
608
|
-
// Write
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
status: finalStatus,
|
|
613
|
-
runId,
|
|
614
|
-
startedAt,
|
|
615
|
-
completedAt,
|
|
616
|
-
enforcement: findingsResult?.payload?.enforcement || null,
|
|
617
|
-
verification: {
|
|
618
|
-
ok: verification.ok,
|
|
619
|
-
status: finalStatus,
|
|
620
|
-
errorsCount: verification.errors.length,
|
|
621
|
-
warningsCount: verification.warnings.length,
|
|
622
|
-
verifiedAt: verification.verifiedAt
|
|
623
|
-
}
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
// Update metadata with completion time
|
|
627
|
-
atomicWriteJson(paths.runMetaJson, {
|
|
628
|
-
contractVersion: 1,
|
|
629
|
-
artifactVersions: paths.artifactVersions,
|
|
630
|
-
veraxVersion: getVersion(),
|
|
631
|
-
nodeVersion: process.version,
|
|
632
|
-
platform: process.platform,
|
|
633
|
-
cwd: projectRoot,
|
|
634
|
-
command: 'default',
|
|
635
|
-
args: { url: resolvedUrl, src },
|
|
636
|
-
url: resolvedUrl,
|
|
637
|
-
src: srcPath,
|
|
638
|
-
startedAt,
|
|
639
|
-
completedAt,
|
|
640
|
-
error: null,
|
|
641
|
-
});
|
|
616
|
+
// H5: Write deterministic digest for reproducibility proof
|
|
617
|
+
if (observeData && observeData.digest) {
|
|
618
|
+
saveDigest(resolve(paths.baseDir, 'run.digest.json'), observeData.digest);
|
|
619
|
+
}
|
|
642
620
|
|
|
643
621
|
events.emit('phase:completed', {
|
|
644
622
|
phase: 'Finalize Artifacts',
|
|
@@ -647,15 +625,28 @@ export async function defaultCommand(options = {}) {
|
|
|
647
625
|
|
|
648
626
|
// Print summary if not JSON mode
|
|
649
627
|
if (!json) {
|
|
650
|
-
|
|
651
|
-
console.log(
|
|
652
|
-
console.log(
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
628
|
+
const relativePath = paths.baseDir.replace(/\\/g, '/').split('/').slice(-1)[0];
|
|
629
|
+
console.log('');
|
|
630
|
+
console.log('VERAX — Silent Failure Detection');
|
|
631
|
+
console.log('');
|
|
632
|
+
console.log(`✔ Project detected: ${projectProfile.framework}`);
|
|
633
|
+
console.log(`✔ URL resolved: ${resolvedUrl}`);
|
|
634
|
+
console.log('');
|
|
635
|
+
console.log('Learn phase:');
|
|
636
|
+
console.log(` → Extracted ${expectations.length} promises`);
|
|
637
|
+
console.log('');
|
|
638
|
+
console.log('Observe phase:');
|
|
639
|
+
console.log(` → Executed ${observeData.stats?.attempted || 0} interactions`);
|
|
640
|
+
console.log(` → Observed: ${observeData.stats?.observed || 0}/${observeData.stats?.attempted || 0}`);
|
|
641
|
+
console.log('');
|
|
642
|
+
console.log('Detect phase:');
|
|
643
|
+
console.log(` → Silent failures: ${detectData.stats?.silentFailures || 0}`);
|
|
644
|
+
console.log(` → Unproven: ${detectData.stats?.unproven || 0}`);
|
|
645
|
+
console.log(` → Coverage gaps: ${detectData.stats?.coverageGaps || 0}`);
|
|
646
|
+
console.log('');
|
|
647
|
+
console.log('Artifacts written to:');
|
|
648
|
+
console.log(` .verax/runs/${relativePath}/`);
|
|
657
649
|
console.log('');
|
|
658
|
-
console.log(verificationOutput);
|
|
659
650
|
}
|
|
660
651
|
|
|
661
652
|
return { runId, paths, url: resolvedUrl, success: true };
|
|
@@ -673,19 +664,18 @@ export async function defaultCommand(options = {}) {
|
|
|
673
664
|
try {
|
|
674
665
|
const failedAt = new Date().toISOString();
|
|
675
666
|
atomicWriteJson(paths.runStatusJson, {
|
|
676
|
-
contractVersion: 1,
|
|
677
|
-
artifactVersions: paths.artifactVersions,
|
|
678
667
|
status: 'FAILED',
|
|
679
668
|
runId,
|
|
680
669
|
startedAt,
|
|
681
670
|
failedAt,
|
|
682
671
|
error: error.message,
|
|
672
|
+
contractVersion: 1,
|
|
673
|
+
artifactVersions: getArtifactVersions(),
|
|
683
674
|
});
|
|
684
675
|
|
|
685
676
|
// Update metadata
|
|
686
677
|
atomicWriteJson(paths.runMetaJson, {
|
|
687
|
-
contractVersion:
|
|
688
|
-
artifactVersions: paths.artifactVersions,
|
|
678
|
+
contractVersion: ARTIFACT_REGISTRY.runMeta.contractVersion,
|
|
689
679
|
veraxVersion: getVersion(),
|
|
690
680
|
nodeVersion: process.version,
|
|
691
681
|
platform: process.platform,
|
|
@@ -732,4 +722,5 @@ export async function defaultCommand(options = {}) {
|
|
|
732
722
|
});
|
|
733
723
|
throw error;
|
|
734
724
|
}
|
|
725
|
+
/* eslint-enable no-unreachable */
|
|
735
726
|
}
|
|
@@ -32,6 +32,35 @@ export async function doctorCommand(options = {}) {
|
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
// Test-mode / smoke fast path: skip heavyweight checks to keep runtime under tight budgets
|
|
36
|
+
if (process.env.VERAX_TEST_MODE === '1' || process.env.VERAX_DOCTOR_SMOKE_TIMEOUT_MS) {
|
|
37
|
+
addCheck('Test mode', 'pass', 'Diagnostics skipped in test/smoke mode');
|
|
38
|
+
addCheck('Node.js version', 'pass', `Detected v${nodeVersion}`);
|
|
39
|
+
addCheck('Playwright package', 'pass', 'Skipped (smoke mode)');
|
|
40
|
+
addCheck('Headless smoke test', 'pass', 'Skipped (smoke mode)');
|
|
41
|
+
const ok = true;
|
|
42
|
+
if (json) {
|
|
43
|
+
const report = {
|
|
44
|
+
ok,
|
|
45
|
+
platform: platformName,
|
|
46
|
+
nodeVersion,
|
|
47
|
+
playwrightVersion: null,
|
|
48
|
+
checks,
|
|
49
|
+
recommendations,
|
|
50
|
+
};
|
|
51
|
+
console.log(JSON.stringify(report, null, 2));
|
|
52
|
+
return report;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
console.log('VERAX Doctor — Environment Diagnostics (test mode)');
|
|
56
|
+
checks.forEach((c) => {
|
|
57
|
+
const label = c.status === 'pass' ? 'PASS' : 'FAIL';
|
|
58
|
+
console.log(`[${label}] ${c.name}: ${c.details}`);
|
|
59
|
+
});
|
|
60
|
+
console.log('\nOverall: OK (test mode)');
|
|
61
|
+
return { ok, checks, recommendations };
|
|
62
|
+
}
|
|
63
|
+
|
|
35
64
|
// 1) Node.js version
|
|
36
65
|
const nodeMajor = parseInt(nodeVersion.split('.')[0], 10);
|
|
37
66
|
if (Number.isFinite(nodeMajor) && nodeMajor >= 18) {
|
package/src/cli/commands/ga.js
CHANGED
|
@@ -29,6 +29,7 @@ function loadFailureLedger(projectDir, runId) {
|
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
31
|
const content = readFileSync(ledgerPath, 'utf-8');
|
|
32
|
+
// @ts-expect-error - readFileSync with encoding returns string
|
|
32
33
|
const ledger = JSON.parse(content);
|
|
33
34
|
return ledger.summary || null;
|
|
34
35
|
} catch (error) {
|
|
@@ -50,6 +51,7 @@ async function loadDeterminismVerdict(projectDir, runId) {
|
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
try {
|
|
54
|
+
// @ts-expect-error - readFileSync with encoding returns string
|
|
53
55
|
const decisions = JSON.parse(readFileSync(decisionsPath, 'utf-8'));
|
|
54
56
|
const { DecisionRecorder } = await import('../../verax/core/determinism-model.js');
|
|
55
57
|
const recorder = DecisionRecorder.fromExport(decisions);
|
|
@@ -76,6 +78,7 @@ function checkEvidenceLawViolations(projectDir, runId) {
|
|
|
76
78
|
|
|
77
79
|
try {
|
|
78
80
|
const content = readFileSync(findingsPath, 'utf-8');
|
|
81
|
+
// @ts-expect-error - readFileSync with encoding returns string
|
|
79
82
|
const findings = JSON.parse(content);
|
|
80
83
|
|
|
81
84
|
if (!Array.isArray(findings.findings)) {
|
|
@@ -22,7 +22,7 @@ const __dirname = dirname(__filename);
|
|
|
22
22
|
* @param {boolean} options.json - Output as JSON
|
|
23
23
|
* @param {boolean} options.verbose - Verbose output
|
|
24
24
|
*/
|
|
25
|
-
export async function gatesCommand(options = {}) {
|
|
25
|
+
export async function gatesCommand(options = { json: false, verbose: false }) {
|
|
26
26
|
const { json = false, verbose = false } = options;
|
|
27
27
|
|
|
28
28
|
// Pass explicit project root to ensure correct path resolution
|