@veraxhq/verax 0.2.1 → 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 +10 -6
- package/bin/verax.js +11 -11
- package/package.json +29 -8
- package/src/cli/commands/baseline.js +103 -0
- package/src/cli/commands/default.js +51 -6
- package/src/cli/commands/doctor.js +29 -0
- package/src/cli/commands/ga.js +246 -0
- package/src/cli/commands/gates.js +95 -0
- package/src/cli/commands/inspect.js +4 -2
- package/src/cli/commands/release-check.js +215 -0
- package/src/cli/commands/run.js +45 -6
- package/src/cli/commands/security-check.js +212 -0
- package/src/cli/commands/truth.js +113 -0
- package/src/cli/entry.js +30 -20
- 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 +544 -0
- package/src/cli/util/ast-network-detector.js +603 -0
- package/src/cli/util/ast-promise-extractor.js +581 -0
- package/src/cli/util/ast-usestate-detector.js +602 -0
- package/src/cli/util/atomic-write.js +12 -1
- package/src/cli/util/bootstrap-guard.js +86 -0
- 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 +124 -0
- package/src/cli/util/determinism-writer.js +129 -0
- package/src/cli/util/digest-engine.js +359 -0
- package/src/cli/util/dom-diff.js +226 -0
- package/src/cli/util/evidence-engine.js +287 -0
- package/src/cli/util/expectation-extractor.js +151 -5
- package/src/cli/util/findings-writer.js +3 -0
- 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 -0
- 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 -0
- package/src/cli/util/project-discovery.js +284 -0
- package/src/cli/util/project-writer.js +2 -0
- package/src/cli/util/run-id.js +23 -27
- package/src/cli/util/run-resolver.js +64 -0
- package/src/cli/util/run-result.js +778 -0
- package/src/cli/util/selector-resolver.js +235 -0
- package/src/cli/util/source-requirement.js +55 -0
- package/src/cli/util/summary-writer.js +2 -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 +146 -0
- package/src/cli/util/svelte-state-detector.js +242 -0
- 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 +178 -0
- package/src/cli/util/vue-sfc-extractor.js +161 -0
- package/src/cli/util/vue-state-detector.js +215 -0
- 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/init.js +4 -18
- package/src/verax/core/action-classifier.js +4 -3
- package/src/verax/core/artifacts/registry.js +139 -0
- package/src/verax/core/artifacts/verifier.js +990 -0
- package/src/verax/core/baseline/baseline.enforcer.js +137 -0
- package/src/verax/core/baseline/baseline.snapshot.js +233 -0
- package/src/verax/core/capabilities/gates.js +505 -0
- package/src/verax/core/capabilities/registry.js +475 -0
- package/src/verax/core/confidence/confidence-compute.js +144 -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 +80 -0
- package/src/verax/core/confidence/confidence.schema.js +94 -0
- package/src/verax/core/confidence-engine-refactor.js +489 -0
- package/src/verax/core/confidence-engine.js +625 -0
- package/src/verax/core/contracts/index.js +29 -0
- package/src/verax/core/contracts/types.js +186 -0
- package/src/verax/core/contracts/validators.js +456 -0
- package/src/verax/core/decisions/decision.trace.js +278 -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 +405 -0
- package/src/verax/core/determinism/engine.js +222 -0
- package/src/verax/core/determinism/finding-identity.js +149 -0
- package/src/verax/core/determinism/normalize.js +466 -0
- package/src/verax/core/determinism/report-writer.js +93 -0
- package/src/verax/core/determinism/run-fingerprint.js +123 -0
- package/src/verax/core/dynamic-route-intelligence.js +529 -0
- package/src/verax/core/evidence/evidence-capture-service.js +308 -0
- package/src/verax/core/evidence/evidence-intent-ledger.js +166 -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 +192 -0
- package/src/verax/core/failures/exit-codes.js +88 -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 +133 -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 +435 -0
- package/src/verax/core/ga/ga.enforcer.js +87 -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 +84 -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 +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 +318 -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 +200 -0
- package/src/verax/core/pipeline-tracker.js +243 -0
- package/src/verax/core/product-definition.js +127 -0
- package/src/verax/core/release/provenance.builder.js +130 -0
- package/src/verax/core/release/release-report-writer.js +40 -0
- package/src/verax/core/release/release.enforcer.js +164 -0
- package/src/verax/core/release/reproducibility.check.js +222 -0
- package/src/verax/core/release/sbom.builder.js +292 -0
- 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 +195 -0
- package/src/verax/core/report/human-summary.js +362 -0
- package/src/verax/core/route-intelligence.js +420 -0
- 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 +329 -0
- package/src/verax/core/security/security-report.js +50 -0
- package/src/verax/core/security/security.enforcer.js +128 -0
- package/src/verax/core/security/supplychain.defaults.json +38 -0
- package/src/verax/core/security/supplychain.policy.js +334 -0
- package/src/verax/core/security/vuln.scan.js +265 -0
- package/src/verax/core/truth/truth.certificate.js +252 -0
- package/src/verax/core/ui-feedback-intelligence.js +481 -0
- package/src/verax/detect/conditional-ui-silent-failure.js +84 -0
- package/src/verax/detect/confidence-engine.js +62 -34
- package/src/verax/detect/confidence-helper.js +34 -0
- package/src/verax/detect/dynamic-route-findings.js +338 -0
- package/src/verax/detect/expectation-chain-detector.js +417 -0
- package/src/verax/detect/expectation-model.js +2 -2
- package/src/verax/detect/failure-cause-inference.js +293 -0
- package/src/verax/detect/findings-writer.js +131 -35
- 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 +46 -5
- package/src/verax/detect/invariants-enforcer.js +147 -0
- package/src/verax/detect/journey-stall-detector.js +558 -0
- 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 +219 -0
- 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 +207 -0
- package/src/verax/detect/view-switch-correlator.js +242 -0
- package/src/verax/flow/flow-engine.js +2 -1
- package/src/verax/flow/flow-spec.js +0 -6
- package/src/verax/index.js +4 -0
- 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 +3 -0
- 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/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 +51 -155
- package/src/verax/observe/interaction-executor.js +192 -0
- package/src/verax/observe/interaction-runner.js +782 -513
- 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 +205 -0
- package/src/verax/observe/observe-helpers.js +192 -0
- package/src/verax/observe/observe-runner.js +230 -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/page-traversal.js +138 -0
- package/src/verax/observe/snapshot-ops.js +94 -0
- package/src/verax/observe/ui-feedback-detector.js +742 -0
- package/src/verax/scan-summary-writer.js +2 -0
- package/src/verax/shared/artifact-manager.js +25 -5
- package/src/verax/shared/caching.js +1 -0
- package/src/verax/shared/css-spinner-rules.js +204 -0
- package/src/verax/shared/expectation-tracker.js +1 -0
- package/src/verax/shared/view-switch-rules.js +208 -0
- package/src/verax/shared/zip-artifacts.js +6 -0
- package/src/verax/shared/config-loader.js +0 -169
- /package/src/verax/shared/{expectation-proof.js → expectation-validation.js} +0 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PHASE 20 — Vue State Promise Detection
|
|
3
|
+
*
|
|
4
|
+
* Detects ref/reactive mutations that are UI-bound:
|
|
5
|
+
* - ref declarations: const count = ref(0);
|
|
6
|
+
* - reactive: const state = reactive({ x: 1 });
|
|
7
|
+
* - Only emit if identifiers are used in template bindings
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { parse } from '@babel/parser';
|
|
11
|
+
import _traverse from '@babel/traverse';
|
|
12
|
+
|
|
13
|
+
const traverse = _traverse.default || _traverse;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* PHASE 20: Detect Vue state promises
|
|
17
|
+
*
|
|
18
|
+
* @param {string} scriptContent - Script block content
|
|
19
|
+
* @param {string} filePath - File path
|
|
20
|
+
* @param {string} relPath - Relative path
|
|
21
|
+
* @param {Object} scriptBlock - Script block metadata
|
|
22
|
+
* @param {Object} templateBindings - Template bindings
|
|
23
|
+
* @returns {Array} State promises
|
|
24
|
+
*/
|
|
25
|
+
export function detectVueStatePromises(scriptContent, filePath, relPath, scriptBlock, templateBindings) {
|
|
26
|
+
const promises = [];
|
|
27
|
+
const templateVars = new Set(templateBindings.bindings || []);
|
|
28
|
+
|
|
29
|
+
if (templateVars.size === 0) {
|
|
30
|
+
return promises; // No template bindings, skip
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const ast = parse(scriptContent, {
|
|
35
|
+
sourceType: 'module',
|
|
36
|
+
plugins: [
|
|
37
|
+
'typescript',
|
|
38
|
+
'classProperties',
|
|
39
|
+
'optionalChaining',
|
|
40
|
+
'nullishCoalescingOperator',
|
|
41
|
+
'dynamicImport',
|
|
42
|
+
'topLevelAwait',
|
|
43
|
+
'objectRestSpread',
|
|
44
|
+
],
|
|
45
|
+
errorRecovery: true,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const lines = scriptContent.split('\n');
|
|
49
|
+
const refDeclarations = new Map(); // varName -> { loc, astSource }
|
|
50
|
+
const reactiveDeclarations = new Map();
|
|
51
|
+
|
|
52
|
+
traverse(ast, {
|
|
53
|
+
// Detect ref() declarations
|
|
54
|
+
VariableDeclarator(path) {
|
|
55
|
+
const node = path.node;
|
|
56
|
+
const init = node.init;
|
|
57
|
+
|
|
58
|
+
if (init && init.type === 'CallExpression') {
|
|
59
|
+
const callee = init.callee;
|
|
60
|
+
|
|
61
|
+
// ref(0) or ref({})
|
|
62
|
+
if (callee.type === 'Identifier' && callee.name === 'ref') {
|
|
63
|
+
const varName = node.id.name;
|
|
64
|
+
if (templateVars.has(varName)) {
|
|
65
|
+
const loc = node.loc;
|
|
66
|
+
const line = loc ? loc.start.line : 1;
|
|
67
|
+
const astSource = lines.slice(line - 1, loc ? loc.end.line : line)
|
|
68
|
+
.join('\n')
|
|
69
|
+
.substring(0, 200);
|
|
70
|
+
|
|
71
|
+
refDeclarations.set(varName, {
|
|
72
|
+
loc,
|
|
73
|
+
astSource,
|
|
74
|
+
line,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// reactive({})
|
|
80
|
+
if (callee.type === 'Identifier' && callee.name === 'reactive') {
|
|
81
|
+
const varName = node.id.name;
|
|
82
|
+
if (templateVars.has(varName)) {
|
|
83
|
+
const loc = node.loc;
|
|
84
|
+
const line = loc ? loc.start.line : 1;
|
|
85
|
+
const astSource = lines.slice(line - 1, loc ? loc.end.line : line)
|
|
86
|
+
.join('\n')
|
|
87
|
+
.substring(0, 200);
|
|
88
|
+
|
|
89
|
+
reactiveDeclarations.set(varName, {
|
|
90
|
+
loc,
|
|
91
|
+
astSource,
|
|
92
|
+
line,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
// Detect mutations: count.value = ... or state.x = ...
|
|
100
|
+
AssignmentExpression(path) {
|
|
101
|
+
const node = path.node;
|
|
102
|
+
const left = node.left;
|
|
103
|
+
|
|
104
|
+
// count.value = ...
|
|
105
|
+
if (left.type === 'MemberExpression' &&
|
|
106
|
+
left.property.name === 'value' &&
|
|
107
|
+
left.object.type === 'Identifier') {
|
|
108
|
+
const varName = left.object.name;
|
|
109
|
+
|
|
110
|
+
if (refDeclarations.has(varName) && templateVars.has(varName)) {
|
|
111
|
+
const _decl = refDeclarations.get(varName);
|
|
112
|
+
const loc = node.loc;
|
|
113
|
+
const line = loc ? loc.start.line : 1;
|
|
114
|
+
const column = loc ? loc.start.column : 0;
|
|
115
|
+
|
|
116
|
+
const astSource = lines.slice(line - 1, loc ? loc.end.line : line)
|
|
117
|
+
.join('\n')
|
|
118
|
+
.substring(0, 200);
|
|
119
|
+
|
|
120
|
+
const context = buildContext(path);
|
|
121
|
+
|
|
122
|
+
promises.push({
|
|
123
|
+
type: 'state',
|
|
124
|
+
promise: {
|
|
125
|
+
kind: 'state-change',
|
|
126
|
+
value: `${varName}.value`,
|
|
127
|
+
stateVar: varName,
|
|
128
|
+
},
|
|
129
|
+
source: {
|
|
130
|
+
file: relPath,
|
|
131
|
+
line,
|
|
132
|
+
column,
|
|
133
|
+
context,
|
|
134
|
+
astSource,
|
|
135
|
+
},
|
|
136
|
+
confidence: 0.9,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// state.x = ...
|
|
142
|
+
if (left.type === 'MemberExpression' &&
|
|
143
|
+
left.object.type === 'Identifier') {
|
|
144
|
+
const varName = left.object.name;
|
|
145
|
+
|
|
146
|
+
if (reactiveDeclarations.has(varName) && templateVars.has(varName)) {
|
|
147
|
+
const loc = node.loc;
|
|
148
|
+
const line = loc ? loc.start.line : 1;
|
|
149
|
+
const column = loc ? loc.start.column : 0;
|
|
150
|
+
|
|
151
|
+
const astSource = lines.slice(line - 1, loc ? loc.end.line : line)
|
|
152
|
+
.join('\n')
|
|
153
|
+
.substring(0, 200);
|
|
154
|
+
|
|
155
|
+
const context = buildContext(path);
|
|
156
|
+
const propName = left.property.name || '<property>';
|
|
157
|
+
|
|
158
|
+
promises.push({
|
|
159
|
+
type: 'state',
|
|
160
|
+
promise: {
|
|
161
|
+
kind: 'state-change',
|
|
162
|
+
value: `${varName}.${propName}`,
|
|
163
|
+
stateVar: varName,
|
|
164
|
+
},
|
|
165
|
+
source: {
|
|
166
|
+
file: relPath,
|
|
167
|
+
line,
|
|
168
|
+
column,
|
|
169
|
+
context,
|
|
170
|
+
astSource,
|
|
171
|
+
},
|
|
172
|
+
confidence: 0.9,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
} catch (error) {
|
|
179
|
+
// Parse error - skip
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return promises;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Build context chain from AST path
|
|
187
|
+
*/
|
|
188
|
+
function buildContext(path) {
|
|
189
|
+
const context = [];
|
|
190
|
+
let current = path;
|
|
191
|
+
|
|
192
|
+
while (current) {
|
|
193
|
+
if (current.isFunctionDeclaration()) {
|
|
194
|
+
context.push({
|
|
195
|
+
type: 'function',
|
|
196
|
+
name: current.node.id?.name || '<anonymous>',
|
|
197
|
+
});
|
|
198
|
+
} else if (current.isArrowFunctionExpression()) {
|
|
199
|
+
context.push({
|
|
200
|
+
type: 'arrow-function',
|
|
201
|
+
name: '<arrow>',
|
|
202
|
+
});
|
|
203
|
+
} else if (current.isMethodDefinition()) {
|
|
204
|
+
context.push({
|
|
205
|
+
type: 'method',
|
|
206
|
+
name: current.node.key?.name || '<method>',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
current = current.parentPath;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return context.reverse().map(c => `${c.type}:${c.name}`).join(' > ');
|
|
214
|
+
}
|
|
215
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type augmentation for Node.js fs module
|
|
3
|
+
* Provides more precise return types for readFileSync with encoding
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
declare module 'fs' {
|
|
7
|
+
import { PathLike } from 'fs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Augment readFileSync to return string when encoding is specified
|
|
11
|
+
*/
|
|
12
|
+
export function readFileSync(
|
|
13
|
+
path: PathLike | number,
|
|
14
|
+
options?: { encoding?: null; flag?: string } | null
|
|
15
|
+
): Buffer;
|
|
16
|
+
|
|
17
|
+
export function readFileSync(
|
|
18
|
+
path: PathLike | number,
|
|
19
|
+
options: { encoding: BufferEncoding; flag?: string } | BufferEncoding
|
|
20
|
+
): string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export {};
|
package/src/types/global.d.ts
CHANGED
|
@@ -24,5 +24,142 @@ import type { Page as PlaywrightPage } from 'playwright';
|
|
|
24
24
|
// Re-export for use in JS files
|
|
25
25
|
export type Page = PlaywrightPage;
|
|
26
26
|
|
|
27
|
+
// Node.js built-in module declarations
|
|
28
|
+
declare module 'fs' {
|
|
29
|
+
export interface Stats {
|
|
30
|
+
isDirectory(): boolean;
|
|
31
|
+
isFile(): boolean;
|
|
32
|
+
size: number;
|
|
33
|
+
mtime: Date;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface WriteFileOptions {
|
|
37
|
+
encoding?: BufferEncoding;
|
|
38
|
+
mode?: number;
|
|
39
|
+
flag?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ReadFileOptions {
|
|
43
|
+
encoding?: BufferEncoding | string;
|
|
44
|
+
flag?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface RmOptions {
|
|
48
|
+
force?: boolean;
|
|
49
|
+
recursive?: boolean;
|
|
50
|
+
maxRetries?: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface MkdirOptions {
|
|
54
|
+
recursive?: boolean;
|
|
55
|
+
mode?: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ReaddirOptions {
|
|
59
|
+
encoding?: BufferEncoding | string;
|
|
60
|
+
withFileTypes?: boolean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function readFileSync(path: string | Buffer, encoding?: string | ReadFileOptions): string | Buffer;
|
|
64
|
+
export function writeFileSync(path: string, data: string | Buffer, options?: WriteFileOptions | string): void;
|
|
65
|
+
export function existsSync(path: string | Buffer): boolean;
|
|
66
|
+
export function mkdirSync(path: string, options?: MkdirOptions): string | undefined;
|
|
67
|
+
export function rmSync(path: string, options?: RmOptions): void;
|
|
68
|
+
export function readdirSync(path: string, options?: ReaddirOptions | string): string[] | any[];
|
|
69
|
+
export function statSync(path: string): Stats;
|
|
70
|
+
export function renameSync(oldPath: string, newPath: string): void;
|
|
71
|
+
export function unlinkSync(path: string): void;
|
|
72
|
+
export function mkdtempSync(prefix: string): string;
|
|
73
|
+
export function appendFileSync(path: string, data: string | Buffer, options?: WriteFileOptions | string): void;
|
|
74
|
+
export function createWriteStream(path: string, options?: any): any;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
declare module 'path' {
|
|
78
|
+
export function resolve(...paths: string[]): string;
|
|
79
|
+
export function join(...paths: string[]): string;
|
|
80
|
+
export function dirname(p: string): string;
|
|
81
|
+
export function basename(p: string, ext?: string): string;
|
|
82
|
+
export function extname(p: string): string;
|
|
83
|
+
export function relative(from: string, to: string): string;
|
|
84
|
+
export function normalize(p: string): string;
|
|
85
|
+
export const sep: string;
|
|
86
|
+
export const delimiter: string;
|
|
87
|
+
export const posix: {
|
|
88
|
+
resolve: typeof resolve;
|
|
89
|
+
join: typeof join;
|
|
90
|
+
dirname: typeof dirname;
|
|
91
|
+
basename: typeof basename;
|
|
92
|
+
};
|
|
93
|
+
export const win32: {
|
|
94
|
+
resolve: typeof resolve;
|
|
95
|
+
join: typeof join;
|
|
96
|
+
dirname: typeof dirname;
|
|
97
|
+
basename: typeof basename;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
declare module 'crypto' {
|
|
102
|
+
export interface Hash {
|
|
103
|
+
update(data: string | Buffer, encoding?: string): Hash;
|
|
104
|
+
digest(encoding?: string): string | Buffer;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function createHash(algorithm: string): Hash;
|
|
108
|
+
export function randomBytes(size: number): Buffer;
|
|
109
|
+
export function createHmac(algorithm: string, key: string | Buffer): {
|
|
110
|
+
update(data: string | Buffer, encoding?: string): any;
|
|
111
|
+
digest(encoding?: string): string;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
declare module 'os' {
|
|
116
|
+
export function tmpdir(): string;
|
|
117
|
+
export function cwd(): string;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
declare module 'url' {
|
|
121
|
+
export function fileURLToPath(url: string | URL): string;
|
|
122
|
+
export class URL {
|
|
123
|
+
constructor(input: string, base?: string | URL);
|
|
124
|
+
href: string;
|
|
125
|
+
protocol: string;
|
|
126
|
+
host: string;
|
|
127
|
+
pathname: string;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
declare module 'http' {
|
|
132
|
+
export interface Server {
|
|
133
|
+
close(callback?: () => void): void;
|
|
134
|
+
listen(port?: number, host?: string, callback?: () => void): void;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function createServer(requestListener?: (req: any, res: any) => void): Server;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
declare global {
|
|
141
|
+
class Buffer {
|
|
142
|
+
static from(data: string, encoding?: string): Buffer;
|
|
143
|
+
static isBuffer(obj: any): obj is Buffer;
|
|
144
|
+
toString(encoding?: string): string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
namespace NodeJS {
|
|
148
|
+
interface ProcessEnv {
|
|
149
|
+
[key: string]: string | undefined;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
interface Process {
|
|
153
|
+
env: ProcessEnv;
|
|
154
|
+
argv: string[];
|
|
155
|
+
cwd(): string;
|
|
156
|
+
exit(code?: number): never;
|
|
157
|
+
on(event: string, listener: (...args: any[]) => void): void;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const process: NodeJS.Process;
|
|
162
|
+
}
|
|
163
|
+
|
|
27
164
|
export {};
|
|
28
165
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal type definitions for VERAX
|
|
3
|
+
* Minimal types to satisfy TypeScript checking
|
|
4
|
+
*
|
|
5
|
+
* @typedef {Object} ObserveContext
|
|
6
|
+
* @property {string} url
|
|
7
|
+
* @property {string} projectDir
|
|
8
|
+
* @property {string} runId
|
|
9
|
+
* @property {SilenceTracker} silenceTracker
|
|
10
|
+
* @property {*} decisionRecorder
|
|
11
|
+
* @property {*} scanBudget
|
|
12
|
+
*
|
|
13
|
+
* @typedef {Object} RunState
|
|
14
|
+
* @property {number} totalInteractions
|
|
15
|
+
* @property {number} totalPages
|
|
16
|
+
* @property {number} startTime
|
|
17
|
+
*
|
|
18
|
+
* @typedef {Object} SilenceTracker
|
|
19
|
+
* @property {function(*): void} record
|
|
20
|
+
* @property {function(): *} getSilenceReport
|
|
21
|
+
*
|
|
22
|
+
* @typedef {Object} PageFrontier
|
|
23
|
+
* @property {function(string, *=): void} addPage
|
|
24
|
+
* @property {function(): *} getNextPage
|
|
25
|
+
* @property {function(): boolean} hasPages
|
|
26
|
+
*
|
|
27
|
+
* @typedef {Object} Observation
|
|
28
|
+
* @property {string} type
|
|
29
|
+
* @property {*} data
|
|
30
|
+
* @property {number=} timestamp
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
// Export as module
|
|
34
|
+
export {};
|
|
35
|
+
|
package/src/verax/cli/init.js
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
import { existsSync, writeFileSync, mkdirSync } from 'fs';
|
|
8
8
|
import { resolve } from 'path';
|
|
9
|
-
import { getDefaultConfig } from '../shared/config-loader.js';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* Initialize VERAX configuration
|
|
@@ -27,16 +26,8 @@ export async function runInit(options = {}) {
|
|
|
27
26
|
// Create .verax directory if needed
|
|
28
27
|
const veraxDir = resolve(projectRoot, '.verax');
|
|
29
28
|
mkdirSync(veraxDir, { recursive: true });
|
|
30
|
-
|
|
31
|
-
//
|
|
32
|
-
const configPath = resolve(veraxDir, 'config.json');
|
|
33
|
-
if (existsSync(configPath) && !yes) {
|
|
34
|
-
skipped.push('config.json');
|
|
35
|
-
} else {
|
|
36
|
-
const defaultConfig = getDefaultConfig();
|
|
37
|
-
writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2) + '\n');
|
|
38
|
-
created.push('config.json');
|
|
39
|
-
}
|
|
29
|
+
|
|
30
|
+
// Zero-config enforcement: do not scaffold config files
|
|
40
31
|
|
|
41
32
|
// Create CI template if requested
|
|
42
33
|
if (ciTemplate === 'github') {
|
|
@@ -75,7 +66,7 @@ jobs:
|
|
|
75
66
|
- name: Start fixture server
|
|
76
67
|
id: fixture-server
|
|
77
68
|
run: |
|
|
78
|
-
node test/
|
|
69
|
+
node test/infrastructure/fixture-server.js &
|
|
79
70
|
SERVER_PID=$!
|
|
80
71
|
echo "SERVER_PID=$SERVER_PID" >> $GITHUB_ENV
|
|
81
72
|
sleep 3
|
|
@@ -211,12 +202,7 @@ export function printInitResults(results) {
|
|
|
211
202
|
});
|
|
212
203
|
}
|
|
213
204
|
|
|
214
|
-
|
|
215
|
-
console.error('\n📝 Next Steps:');
|
|
216
|
-
console.error(' 1. Review .verax/config.json and adjust settings');
|
|
217
|
-
console.error(' 2. Run: verax doctor (to verify setup)');
|
|
218
|
-
console.error(' 3. Run: verax run --url <your-url>');
|
|
219
|
-
}
|
|
205
|
+
// No config scaffolding in zero-config mode
|
|
220
206
|
|
|
221
207
|
if (results.created.includes('.github/workflows/verax-ci.yml')) {
|
|
222
208
|
console.error('\n🔧 CI Setup:');
|
|
@@ -67,18 +67,19 @@ export function classifyAction(interaction) {
|
|
|
67
67
|
/**
|
|
68
68
|
* Check if action should be blocked based on safety mode and flags
|
|
69
69
|
* @param {Object} interaction - Interaction to check
|
|
70
|
-
* @param {Object} flags - Safety flags {
|
|
70
|
+
* @param {Object} flags - Safety flags { allowRiskyActions: boolean }
|
|
71
71
|
* @returns {Object} { shouldBlock: boolean, classification: string, reason: string }
|
|
72
72
|
*/
|
|
73
73
|
export function shouldBlockAction(interaction, flags = {}) {
|
|
74
|
-
const {
|
|
74
|
+
const { allowRiskyActions = false } = flags;
|
|
75
75
|
const { classification, reason } = classifyAction(interaction);
|
|
76
76
|
|
|
77
77
|
if (classification === 'RISKY' && !allowRiskyActions) {
|
|
78
78
|
return { shouldBlock: true, classification, reason };
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
// CONSTITUTIONAL: Always block write intents (read-only mode enforced)
|
|
82
|
+
if (classification === 'WRITE_INTENT') {
|
|
82
83
|
return { shouldBlock: true, classification, reason };
|
|
83
84
|
}
|
|
84
85
|
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
|
|
3
|
+
export const ARTIFACT_REGISTRY = {
|
|
4
|
+
runStatus: {
|
|
5
|
+
key: 'runStatus',
|
|
6
|
+
filename: 'run.status.json',
|
|
7
|
+
stage: 'init',
|
|
8
|
+
contractVersion: 1,
|
|
9
|
+
type: 'file'
|
|
10
|
+
},
|
|
11
|
+
runMeta: {
|
|
12
|
+
key: 'runMeta',
|
|
13
|
+
filename: 'run.meta.json',
|
|
14
|
+
stage: 'init',
|
|
15
|
+
contractVersion: 1,
|
|
16
|
+
type: 'file'
|
|
17
|
+
},
|
|
18
|
+
summary: {
|
|
19
|
+
key: 'summary',
|
|
20
|
+
filename: 'summary.json',
|
|
21
|
+
stage: 'finalize',
|
|
22
|
+
contractVersion: 1,
|
|
23
|
+
type: 'file'
|
|
24
|
+
},
|
|
25
|
+
findings: {
|
|
26
|
+
key: 'findings',
|
|
27
|
+
filename: 'findings.json',
|
|
28
|
+
stage: 'detect',
|
|
29
|
+
contractVersion: 1,
|
|
30
|
+
type: 'file'
|
|
31
|
+
},
|
|
32
|
+
learn: {
|
|
33
|
+
key: 'learn',
|
|
34
|
+
filename: 'learn.json',
|
|
35
|
+
stage: 'learn',
|
|
36
|
+
contractVersion: 1,
|
|
37
|
+
type: 'file'
|
|
38
|
+
},
|
|
39
|
+
observe: {
|
|
40
|
+
key: 'observe',
|
|
41
|
+
filename: 'observe.json',
|
|
42
|
+
stage: 'observe',
|
|
43
|
+
contractVersion: 1,
|
|
44
|
+
type: 'file'
|
|
45
|
+
},
|
|
46
|
+
project: {
|
|
47
|
+
key: 'project',
|
|
48
|
+
filename: 'project.json',
|
|
49
|
+
stage: 'init',
|
|
50
|
+
contractVersion: 1,
|
|
51
|
+
type: 'file'
|
|
52
|
+
},
|
|
53
|
+
traces: {
|
|
54
|
+
key: 'traces',
|
|
55
|
+
filename: 'traces.jsonl',
|
|
56
|
+
stage: 'finalize',
|
|
57
|
+
contractVersion: 1,
|
|
58
|
+
type: 'file'
|
|
59
|
+
},
|
|
60
|
+
evidence: {
|
|
61
|
+
key: 'evidence',
|
|
62
|
+
filename: 'evidence',
|
|
63
|
+
stage: 'observe',
|
|
64
|
+
contractVersion: 1,
|
|
65
|
+
type: 'directory'
|
|
66
|
+
},
|
|
67
|
+
scanSummary: {
|
|
68
|
+
key: 'scanSummary',
|
|
69
|
+
filename: 'scan-summary.json',
|
|
70
|
+
stage: 'finalize',
|
|
71
|
+
contractVersion: 1,
|
|
72
|
+
type: 'file'
|
|
73
|
+
},
|
|
74
|
+
determinismReport: {
|
|
75
|
+
key: 'determinismReport',
|
|
76
|
+
filename: 'determinism.report.json',
|
|
77
|
+
stage: 'finalize',
|
|
78
|
+
contractVersion: 1,
|
|
79
|
+
type: 'file'
|
|
80
|
+
},
|
|
81
|
+
evidenceIntent: {
|
|
82
|
+
key: 'evidenceIntent',
|
|
83
|
+
filename: 'evidence.intent.json',
|
|
84
|
+
stage: 'detect',
|
|
85
|
+
contractVersion: 1,
|
|
86
|
+
type: 'file'
|
|
87
|
+
},
|
|
88
|
+
guardrailsReport: {
|
|
89
|
+
key: 'guardrailsReport',
|
|
90
|
+
filename: 'guardrails.report.json',
|
|
91
|
+
stage: 'detect',
|
|
92
|
+
contractVersion: 1,
|
|
93
|
+
type: 'file'
|
|
94
|
+
},
|
|
95
|
+
confidenceReport: {
|
|
96
|
+
key: 'confidenceReport',
|
|
97
|
+
filename: 'confidence.report.json',
|
|
98
|
+
stage: 'detect',
|
|
99
|
+
contractVersion: 1,
|
|
100
|
+
type: 'file'
|
|
101
|
+
},
|
|
102
|
+
determinismContract: {
|
|
103
|
+
key: 'determinismContract',
|
|
104
|
+
filename: 'determinism.contract.json',
|
|
105
|
+
stage: 'observe',
|
|
106
|
+
contractVersion: 1,
|
|
107
|
+
type: 'file'
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export function getArtifactVersions() {
|
|
112
|
+
const versions = {};
|
|
113
|
+
for (const [key, def] of Object.entries(ARTIFACT_REGISTRY)) {
|
|
114
|
+
versions[key] = def.contractVersion;
|
|
115
|
+
}
|
|
116
|
+
return versions;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function buildRunArtifactPaths(baseDir) {
|
|
120
|
+
return {
|
|
121
|
+
baseDir,
|
|
122
|
+
runStatusJson: join(baseDir, ARTIFACT_REGISTRY.runStatus.filename),
|
|
123
|
+
runMetaJson: join(baseDir, ARTIFACT_REGISTRY.runMeta.filename),
|
|
124
|
+
summaryJson: join(baseDir, ARTIFACT_REGISTRY.summary.filename),
|
|
125
|
+
findingsJson: join(baseDir, ARTIFACT_REGISTRY.findings.filename),
|
|
126
|
+
tracesJsonl: join(baseDir, ARTIFACT_REGISTRY.traces.filename),
|
|
127
|
+
evidenceDir: join(baseDir, ARTIFACT_REGISTRY.evidence.filename),
|
|
128
|
+
learnJson: join(baseDir, ARTIFACT_REGISTRY.learn.filename),
|
|
129
|
+
observeJson: join(baseDir, ARTIFACT_REGISTRY.observe.filename),
|
|
130
|
+
projectJson: join(baseDir, ARTIFACT_REGISTRY.project.filename),
|
|
131
|
+
scanSummaryJson: join(baseDir, ARTIFACT_REGISTRY.scanSummary.filename),
|
|
132
|
+
evidenceIntentJson: join(baseDir, ARTIFACT_REGISTRY.evidenceIntent.filename),
|
|
133
|
+
guardrailsReportJson: join(baseDir, ARTIFACT_REGISTRY.guardrailsReport.filename),
|
|
134
|
+
confidenceReportJson: join(baseDir, ARTIFACT_REGISTRY.confidenceReport.filename),
|
|
135
|
+
determinismContractJson: join(baseDir, ARTIFACT_REGISTRY.determinismContract.filename),
|
|
136
|
+
determinismReportJson: join(baseDir, ARTIFACT_REGISTRY.determinismReport.filename),
|
|
137
|
+
artifactVersions: getArtifactVersions()
|
|
138
|
+
};
|
|
139
|
+
}
|