@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,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VIEW SWITCH CORRELATOR
|
|
3
|
+
*
|
|
4
|
+
* Correlates view switch promises with observed UI changes (no URL change).
|
|
5
|
+
* Requires at least 2 independent signals for CONFIRMED.
|
|
6
|
+
*
|
|
7
|
+
* TRUTH BOUNDARY:
|
|
8
|
+
* - CONFIRMED: 2+ independent signals (DOM signature + landmark/focus/aria-live)
|
|
9
|
+
* - SUSPECTED: 1 signal only
|
|
10
|
+
* - INFORMATIONAL: Interaction blocked/disabled/prevented
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Reason codes for correlation decisions
|
|
15
|
+
*/
|
|
16
|
+
export const VIEW_SWITCH_REASON_CODES = {
|
|
17
|
+
CONFIRMED_TWO_SIGNALS: 'CONFIRMED_TWO_SIGNALS',
|
|
18
|
+
CONFIRMED_THREE_SIGNALS: 'CONFIRMED_THREE_SIGNALS',
|
|
19
|
+
SUSPECTED_ONE_SIGNAL: 'SUSPECTED_ONE_SIGNAL',
|
|
20
|
+
INFORMATIONAL_BLOCKED: 'INFORMATIONAL_BLOCKED',
|
|
21
|
+
INFORMATIONAL_DISABLED: 'INFORMATIONAL_DISABLED',
|
|
22
|
+
INFORMATIONAL_PREVENTED: 'INFORMATIONAL_PREVENTED',
|
|
23
|
+
NO_SIGNALS: 'NO_SIGNALS'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Correlate view switch promise with observed UI changes.
|
|
28
|
+
*
|
|
29
|
+
* @param {Object} expectation - View switch promise expectation
|
|
30
|
+
* @param {Object} trace - Interaction trace with sensors
|
|
31
|
+
* @param {string} beforeUrl - URL before interaction
|
|
32
|
+
* @param {string} afterUrl - URL after interaction
|
|
33
|
+
* @returns {Object} - { outcome, severity, reasonCode, signals }
|
|
34
|
+
*/
|
|
35
|
+
export function correlateViewSwitch(expectation, trace, beforeUrl, afterUrl) {
|
|
36
|
+
if (!expectation || expectation.kind !== 'VIEW_SWITCH_PROMISE') {
|
|
37
|
+
return { outcome: null, severity: null, reasonCode: null, signals: [] };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const sensors = trace.sensors || {};
|
|
41
|
+
const navigation = sensors.navigation || {};
|
|
42
|
+
const uiSignals = sensors.uiSignals || {};
|
|
43
|
+
const stateUi = sensors.stateUi || {};
|
|
44
|
+
const uiFeedback = sensors.uiFeedback || {};
|
|
45
|
+
|
|
46
|
+
// Check if URL changed (if so, this is not a state-driven navigation)
|
|
47
|
+
const urlChanged = navigation.urlChanged === true || (beforeUrl !== afterUrl);
|
|
48
|
+
if (urlChanged) {
|
|
49
|
+
return { outcome: null, severity: null, reasonCode: 'URL_CHANGED', signals: [] };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Check if interaction was blocked/disabled/prevented
|
|
53
|
+
const interaction = trace.interaction || {};
|
|
54
|
+
const isDisabled = interaction.disabled === true;
|
|
55
|
+
const isBlocked = interaction.blocked === true;
|
|
56
|
+
const isPrevented = interaction.prevented === true;
|
|
57
|
+
|
|
58
|
+
if (isDisabled) {
|
|
59
|
+
return {
|
|
60
|
+
outcome: 'INFORMATIONAL',
|
|
61
|
+
severity: 'INFORMATIONAL',
|
|
62
|
+
reasonCode: VIEW_SWITCH_REASON_CODES.INFORMATIONAL_DISABLED,
|
|
63
|
+
signals: []
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (isBlocked) {
|
|
68
|
+
return {
|
|
69
|
+
outcome: 'INFORMATIONAL',
|
|
70
|
+
severity: 'INFORMATIONAL',
|
|
71
|
+
reasonCode: VIEW_SWITCH_REASON_CODES.INFORMATIONAL_BLOCKED,
|
|
72
|
+
signals: []
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (isPrevented) {
|
|
77
|
+
return {
|
|
78
|
+
outcome: 'INFORMATIONAL',
|
|
79
|
+
severity: 'INFORMATIONAL',
|
|
80
|
+
reasonCode: VIEW_SWITCH_REASON_CODES.INFORMATIONAL_PREVENTED,
|
|
81
|
+
signals: []
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Collect independent signals
|
|
86
|
+
const signals = [];
|
|
87
|
+
|
|
88
|
+
// Signal 1: DOM signature change (stable hash)
|
|
89
|
+
const beforeDom = trace.before?.domSignature || trace.before?.domHash;
|
|
90
|
+
const afterDom = trace.after?.domSignature || trace.after?.domHash;
|
|
91
|
+
if (beforeDom && afterDom && beforeDom !== afterDom) {
|
|
92
|
+
signals.push({
|
|
93
|
+
type: 'DOM_SIGNATURE_CHANGE',
|
|
94
|
+
before: beforeDom,
|
|
95
|
+
after: afterDom
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Signal 2: Visible landmark change (heading/main role change)
|
|
100
|
+
const beforeLandmarks = extractLandmarks(trace.before);
|
|
101
|
+
const afterLandmarks = extractLandmarks(trace.after);
|
|
102
|
+
if (beforeLandmarks.length > 0 && afterLandmarks.length > 0) {
|
|
103
|
+
const landmarksChanged = JSON.stringify(beforeLandmarks) !== JSON.stringify(afterLandmarks);
|
|
104
|
+
if (landmarksChanged) {
|
|
105
|
+
signals.push({
|
|
106
|
+
type: 'LANDMARK_CHANGE',
|
|
107
|
+
before: beforeLandmarks,
|
|
108
|
+
after: afterLandmarks
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Signal 3: Focus moved to new container
|
|
114
|
+
const beforeFocus = trace.before?.focus || {};
|
|
115
|
+
const afterFocus = trace.after?.focus || {};
|
|
116
|
+
if (beforeFocus.selector && afterFocus.selector && beforeFocus.selector !== afterFocus.selector) {
|
|
117
|
+
const beforeContainer = getContainerSelector(beforeFocus.selector);
|
|
118
|
+
const afterContainer = getContainerSelector(afterFocus.selector);
|
|
119
|
+
if (beforeContainer !== afterContainer) {
|
|
120
|
+
signals.push({
|
|
121
|
+
type: 'FOCUS_CONTAINER_CHANGE',
|
|
122
|
+
before: beforeContainer,
|
|
123
|
+
after: afterContainer
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Signal 4: aria-live message
|
|
129
|
+
const ariaLiveBefore = extractAriaLive(trace.before);
|
|
130
|
+
const ariaLiveAfter = extractAriaLive(trace.after);
|
|
131
|
+
if (ariaLiveAfter.length > ariaLiveBefore.length) {
|
|
132
|
+
signals.push({
|
|
133
|
+
type: 'ARIA_LIVE_MESSAGE',
|
|
134
|
+
messages: ariaLiveAfter.slice(ariaLiveBefore.length)
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Signal 5: UI feedback signals (optional but counts)
|
|
139
|
+
if (uiFeedback.signals) {
|
|
140
|
+
const feedbackSignals = uiFeedback.signals;
|
|
141
|
+
if (feedbackSignals.domChange?.happened === true) {
|
|
142
|
+
signals.push({
|
|
143
|
+
type: 'UI_FEEDBACK_DOM_CHANGE',
|
|
144
|
+
details: feedbackSignals.domChange
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
if (feedbackSignals.focusChange?.happened === true) {
|
|
148
|
+
signals.push({
|
|
149
|
+
type: 'UI_FEEDBACK_FOCUS_CHANGE',
|
|
150
|
+
details: feedbackSignals.focusChange
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Determine outcome based on signal count
|
|
156
|
+
if (signals.length >= 2) {
|
|
157
|
+
return {
|
|
158
|
+
outcome: 'CONFIRMED',
|
|
159
|
+
severity: 'CONFIRMED',
|
|
160
|
+
reasonCode: signals.length >= 3
|
|
161
|
+
? VIEW_SWITCH_REASON_CODES.CONFIRMED_THREE_SIGNALS
|
|
162
|
+
: VIEW_SWITCH_REASON_CODES.CONFIRMED_TWO_SIGNALS,
|
|
163
|
+
signals
|
|
164
|
+
};
|
|
165
|
+
} else if (signals.length === 1) {
|
|
166
|
+
return {
|
|
167
|
+
outcome: 'SUSPECTED',
|
|
168
|
+
severity: 'SUSPECTED',
|
|
169
|
+
reasonCode: VIEW_SWITCH_REASON_CODES.SUSPECTED_ONE_SIGNAL,
|
|
170
|
+
signals
|
|
171
|
+
};
|
|
172
|
+
} else {
|
|
173
|
+
return {
|
|
174
|
+
outcome: 'NO_SIGNALS',
|
|
175
|
+
severity: 'SUSPECTED',
|
|
176
|
+
reasonCode: VIEW_SWITCH_REASON_CODES.NO_SIGNALS,
|
|
177
|
+
signals: []
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Extract landmarks (headings, main role) from trace snapshot
|
|
184
|
+
*/
|
|
185
|
+
function extractLandmarks(snapshot) {
|
|
186
|
+
if (!snapshot) return [];
|
|
187
|
+
|
|
188
|
+
const landmarks = [];
|
|
189
|
+
|
|
190
|
+
// Extract headings (h1-h6)
|
|
191
|
+
if (snapshot.headings) {
|
|
192
|
+
landmarks.push(...snapshot.headings.map(h => ({ type: 'heading', level: h.level, text: h.text?.slice(0, 50) })));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Extract main role elements
|
|
196
|
+
if (snapshot.mainElements) {
|
|
197
|
+
landmarks.push(...snapshot.mainElements.map(m => ({ type: 'main', text: m.text?.slice(0, 50) })));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return landmarks;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Get container selector from element selector
|
|
205
|
+
*/
|
|
206
|
+
function getContainerSelector(selector) {
|
|
207
|
+
if (!selector) return null;
|
|
208
|
+
|
|
209
|
+
// Extract parent container (simplified - assumes common patterns)
|
|
210
|
+
const parts = selector.split(' > ');
|
|
211
|
+
if (parts.length > 1) {
|
|
212
|
+
return parts[parts.length - 2]; // Second to last part
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Try to extract container from selector
|
|
216
|
+
const match = selector.match(/([^>]+) > [^>]+$/);
|
|
217
|
+
if (match) {
|
|
218
|
+
return match[1].trim();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return selector; // Fallback to full selector
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Extract aria-live messages from trace snapshot
|
|
226
|
+
*/
|
|
227
|
+
function extractAriaLive(snapshot) {
|
|
228
|
+
if (!snapshot) return [];
|
|
229
|
+
|
|
230
|
+
const messages = [];
|
|
231
|
+
|
|
232
|
+
if (snapshot.ariaLiveRegions) {
|
|
233
|
+
snapshot.ariaLiveRegions.forEach(region => {
|
|
234
|
+
if (region.text) {
|
|
235
|
+
messages.push(region.text.slice(0, 100));
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return messages;
|
|
241
|
+
}
|
|
242
|
+
|