@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.
Files changed (191) hide show
  1. package/README.md +28 -20
  2. package/bin/verax.js +11 -18
  3. package/package.json +28 -7
  4. package/src/cli/commands/baseline.js +1 -2
  5. package/src/cli/commands/default.js +72 -81
  6. package/src/cli/commands/doctor.js +29 -0
  7. package/src/cli/commands/ga.js +3 -0
  8. package/src/cli/commands/gates.js +1 -1
  9. package/src/cli/commands/inspect.js +6 -133
  10. package/src/cli/commands/release-check.js +2 -0
  11. package/src/cli/commands/run.js +74 -246
  12. package/src/cli/commands/security-check.js +2 -1
  13. package/src/cli/commands/truth.js +0 -1
  14. package/src/cli/entry.js +82 -309
  15. package/src/cli/util/angular-component-extractor.js +2 -2
  16. package/src/cli/util/angular-navigation-detector.js +2 -2
  17. package/src/cli/util/ast-interactive-detector.js +4 -6
  18. package/src/cli/util/ast-network-detector.js +3 -3
  19. package/src/cli/util/ast-promise-extractor.js +581 -0
  20. package/src/cli/util/ast-usestate-detector.js +3 -3
  21. package/src/cli/util/atomic-write.js +12 -1
  22. package/src/cli/util/console-reporter.js +72 -0
  23. package/src/cli/util/detection-engine.js +105 -41
  24. package/src/cli/util/determinism-runner.js +2 -1
  25. package/src/cli/util/determinism-writer.js +1 -1
  26. package/src/cli/util/digest-engine.js +359 -0
  27. package/src/cli/util/dom-diff.js +226 -0
  28. package/src/cli/util/env-url.js +0 -4
  29. package/src/cli/util/evidence-engine.js +287 -0
  30. package/src/cli/util/expectation-extractor.js +217 -367
  31. package/src/cli/util/findings-writer.js +19 -126
  32. package/src/cli/util/framework-detector.js +572 -0
  33. package/src/cli/util/idgen.js +1 -1
  34. package/src/cli/util/interaction-planner.js +529 -0
  35. package/src/cli/util/learn-writer.js +2 -2
  36. package/src/cli/util/ledger-writer.js +110 -0
  37. package/src/cli/util/monorepo-resolver.js +162 -0
  38. package/src/cli/util/observation-engine.js +127 -278
  39. package/src/cli/util/observe-writer.js +2 -2
  40. package/src/cli/util/paths.js +12 -3
  41. package/src/cli/util/project-discovery.js +284 -3
  42. package/src/cli/util/project-writer.js +2 -2
  43. package/src/cli/util/run-id.js +23 -27
  44. package/src/cli/util/run-result.js +778 -0
  45. package/src/cli/util/selector-resolver.js +235 -0
  46. package/src/cli/util/summary-writer.js +2 -1
  47. package/src/cli/util/svelte-navigation-detector.js +3 -3
  48. package/src/cli/util/svelte-sfc-extractor.js +0 -1
  49. package/src/cli/util/svelte-state-detector.js +1 -2
  50. package/src/cli/util/trust-activation-integration.js +496 -0
  51. package/src/cli/util/trust-activation-wrapper.js +85 -0
  52. package/src/cli/util/trust-integration-hooks.js +164 -0
  53. package/src/cli/util/types.js +153 -0
  54. package/src/cli/util/url-validation.js +40 -0
  55. package/src/cli/util/vue-navigation-detector.js +4 -3
  56. package/src/cli/util/vue-sfc-extractor.js +1 -2
  57. package/src/cli/util/vue-state-detector.js +1 -1
  58. package/src/types/fs-augment.d.ts +23 -0
  59. package/src/types/global.d.ts +137 -0
  60. package/src/types/internal-types.d.ts +35 -0
  61. package/src/verax/cli/finding-explainer.js +3 -56
  62. package/src/verax/cli/init.js +4 -18
  63. package/src/verax/core/action-classifier.js +4 -3
  64. package/src/verax/core/artifacts/registry.js +0 -15
  65. package/src/verax/core/artifacts/verifier.js +18 -8
  66. package/src/verax/core/baseline/baseline.snapshot.js +2 -0
  67. package/src/verax/core/capabilities/gates.js +7 -1
  68. package/src/verax/core/confidence/confidence-compute.js +14 -7
  69. package/src/verax/core/confidence/confidence.loader.js +1 -0
  70. package/src/verax/core/confidence-engine-refactor.js +8 -3
  71. package/src/verax/core/confidence-engine.js +162 -23
  72. package/src/verax/core/contracts/types.js +1 -0
  73. package/src/verax/core/contracts/validators.js +79 -4
  74. package/src/verax/core/decision-snapshot.js +3 -30
  75. package/src/verax/core/decisions/decision.trace.js +2 -0
  76. package/src/verax/core/determinism/contract-writer.js +2 -2
  77. package/src/verax/core/determinism/contract.js +1 -1
  78. package/src/verax/core/determinism/diff.js +42 -1
  79. package/src/verax/core/determinism/engine.js +7 -6
  80. package/src/verax/core/determinism/finding-identity.js +3 -2
  81. package/src/verax/core/determinism/normalize.js +32 -4
  82. package/src/verax/core/determinism/report-writer.js +1 -0
  83. package/src/verax/core/determinism/run-fingerprint.js +7 -2
  84. package/src/verax/core/dynamic-route-intelligence.js +8 -7
  85. package/src/verax/core/evidence/evidence-capture-service.js +1 -0
  86. package/src/verax/core/evidence/evidence-intent-ledger.js +2 -1
  87. package/src/verax/core/evidence-builder.js +2 -2
  88. package/src/verax/core/execution-mode-context.js +1 -1
  89. package/src/verax/core/execution-mode-detector.js +5 -3
  90. package/src/verax/core/failures/exit-codes.js +39 -37
  91. package/src/verax/core/failures/failure-summary.js +1 -1
  92. package/src/verax/core/failures/failure.factory.js +3 -3
  93. package/src/verax/core/failures/failure.ledger.js +3 -2
  94. package/src/verax/core/ga/ga.artifact.js +1 -1
  95. package/src/verax/core/ga/ga.contract.js +3 -2
  96. package/src/verax/core/ga/ga.enforcer.js +1 -0
  97. package/src/verax/core/guardrails/policy.loader.js +1 -0
  98. package/src/verax/core/guardrails/truth-reconciliation.js +1 -1
  99. package/src/verax/core/guardrails-engine.js +2 -2
  100. package/src/verax/core/incremental-store.js +1 -0
  101. package/src/verax/core/integrity/budget.js +138 -0
  102. package/src/verax/core/integrity/determinism.js +342 -0
  103. package/src/verax/core/integrity/integrity.js +208 -0
  104. package/src/verax/core/integrity/poisoning.js +108 -0
  105. package/src/verax/core/integrity/transaction.js +140 -0
  106. package/src/verax/core/observe/run-timeline.js +2 -0
  107. package/src/verax/core/perf/perf.report.js +2 -0
  108. package/src/verax/core/pipeline-tracker.js +5 -0
  109. package/src/verax/core/release/provenance.builder.js +73 -214
  110. package/src/verax/core/release/release.enforcer.js +14 -9
  111. package/src/verax/core/release/reproducibility.check.js +1 -0
  112. package/src/verax/core/release/sbom.builder.js +32 -23
  113. package/src/verax/core/replay-validator.js +2 -0
  114. package/src/verax/core/replay.js +4 -0
  115. package/src/verax/core/report/cross-index.js +6 -3
  116. package/src/verax/core/report/human-summary.js +141 -1
  117. package/src/verax/core/route-intelligence.js +4 -3
  118. package/src/verax/core/run-id.js +6 -3
  119. package/src/verax/core/run-manifest.js +4 -3
  120. package/src/verax/core/security/secrets.scan.js +10 -7
  121. package/src/verax/core/security/security.enforcer.js +4 -0
  122. package/src/verax/core/security/supplychain.policy.js +9 -1
  123. package/src/verax/core/security/vuln.scan.js +2 -2
  124. package/src/verax/core/truth/truth.certificate.js +3 -1
  125. package/src/verax/core/ui-feedback-intelligence.js +12 -46
  126. package/src/verax/detect/conditional-ui-silent-failure.js +84 -0
  127. package/src/verax/detect/confidence-engine.js +100 -660
  128. package/src/verax/detect/confidence-helper.js +1 -0
  129. package/src/verax/detect/detection-engine.js +1 -18
  130. package/src/verax/detect/dynamic-route-findings.js +17 -14
  131. package/src/verax/detect/expectation-chain-detector.js +1 -1
  132. package/src/verax/detect/expectation-model.js +3 -5
  133. package/src/verax/detect/failure-cause-inference.js +293 -0
  134. package/src/verax/detect/findings-writer.js +126 -166
  135. package/src/verax/detect/flow-detector.js +2 -2
  136. package/src/verax/detect/form-silent-failure.js +98 -0
  137. package/src/verax/detect/index.js +51 -234
  138. package/src/verax/detect/invariants-enforcer.js +147 -0
  139. package/src/verax/detect/journey-stall-detector.js +4 -4
  140. package/src/verax/detect/navigation-silent-failure.js +82 -0
  141. package/src/verax/detect/problem-aggregator.js +361 -0
  142. package/src/verax/detect/route-findings.js +7 -6
  143. package/src/verax/detect/summary-writer.js +477 -0
  144. package/src/verax/detect/test-failure-cause-inference.js +314 -0
  145. package/src/verax/detect/ui-feedback-findings.js +18 -18
  146. package/src/verax/detect/verdict-engine.js +3 -57
  147. package/src/verax/detect/view-switch-correlator.js +2 -2
  148. package/src/verax/flow/flow-engine.js +2 -1
  149. package/src/verax/flow/flow-spec.js +0 -6
  150. package/src/verax/index.js +48 -412
  151. package/src/verax/intel/ts-program.js +1 -0
  152. package/src/verax/intel/vue-navigation-extractor.js +3 -0
  153. package/src/verax/learn/action-contract-extractor.js +67 -682
  154. package/src/verax/learn/ast-contract-extractor.js +1 -1
  155. package/src/verax/learn/flow-extractor.js +1 -0
  156. package/src/verax/learn/project-detector.js +5 -0
  157. package/src/verax/learn/react-router-extractor.js +2 -0
  158. package/src/verax/learn/route-validator.js +1 -4
  159. package/src/verax/learn/source-instrumenter.js +1 -0
  160. package/src/verax/learn/state-extractor.js +2 -1
  161. package/src/verax/learn/static-extractor.js +1 -0
  162. package/src/verax/observe/coverage-gaps.js +132 -0
  163. package/src/verax/observe/expectation-handler.js +126 -0
  164. package/src/verax/observe/incremental-skip.js +46 -0
  165. package/src/verax/observe/index.js +735 -84
  166. package/src/verax/observe/interaction-executor.js +192 -0
  167. package/src/verax/observe/interaction-runner.js +782 -530
  168. package/src/verax/observe/network-firewall.js +86 -0
  169. package/src/verax/observe/observation-builder.js +169 -0
  170. package/src/verax/observe/observe-context.js +1 -1
  171. package/src/verax/observe/observe-helpers.js +2 -1
  172. package/src/verax/observe/observe-runner.js +28 -24
  173. package/src/verax/observe/observers/budget-observer.js +3 -3
  174. package/src/verax/observe/observers/console-observer.js +4 -4
  175. package/src/verax/observe/observers/coverage-observer.js +4 -4
  176. package/src/verax/observe/observers/interaction-observer.js +3 -3
  177. package/src/verax/observe/observers/navigation-observer.js +4 -4
  178. package/src/verax/observe/observers/network-observer.js +4 -4
  179. package/src/verax/observe/observers/safety-observer.js +1 -1
  180. package/src/verax/observe/observers/ui-feedback-observer.js +4 -4
  181. package/src/verax/observe/page-traversal.js +138 -0
  182. package/src/verax/observe/snapshot-ops.js +94 -0
  183. package/src/verax/observe/ui-signal-sensor.js +2 -148
  184. package/src/verax/scan-summary-writer.js +10 -42
  185. package/src/verax/shared/artifact-manager.js +30 -13
  186. package/src/verax/shared/caching.js +1 -0
  187. package/src/verax/shared/expectation-tracker.js +1 -0
  188. package/src/verax/shared/zip-artifacts.js +6 -0
  189. package/src/verax/core/confidence-engine.js.backup +0 -471
  190. package/src/verax/shared/config-loader.js +0 -169
  191. /package/src/verax/shared/{expectation-proof.js → expectation-validation.js} +0 -0
@@ -37,8 +37,8 @@ export function detectUIFeedbackSignals(trace) {
37
37
  const sensors = trace.sensors || {};
38
38
  const uiSignals = sensors.uiSignals || {};
39
39
  const uiFeedback = sensors.uiFeedback || {};
40
- const before = trace.before || {};
41
- const after = trace.after || {};
40
+ const _before = trace.before || {};
41
+ const _after = trace.after || {};
42
42
 
43
43
  const beforeSignals = uiSignals.before || {};
44
44
  const afterSignals = uiSignals.after || {};
@@ -169,8 +169,8 @@ export function scoreUIFeedback(signals, expectation, trace) {
169
169
  const networkSensor = sensors.network || {};
170
170
  const uiFeedback = sensors.uiFeedback || {};
171
171
 
172
- // Determine expected feedback type based on expectation
173
- const expectedFeedbackTypes = inferExpectedFeedbackTypes(expectation);
172
+ // Evidence-only: no inferred feedback expectations
173
+ const expectedFeedbackTypes = [];
174
174
 
175
175
  // Check if any expected feedback types are present
176
176
  const matchingSignals = signals.filter(s =>
@@ -190,7 +190,9 @@ export function scoreUIFeedback(signals, expectation, trace) {
190
190
  if (matchingSignals.length > 0 || overallScore > 0.5) {
191
191
  return {
192
192
  score: FEEDBACK_SCORE.CONFIRMED,
193
- confidence: Math.max(...matchingSignals.map(s => s.confidence), overallScore),
193
+ confidence: matchingSignals.length > 0
194
+ ? Math.max(...matchingSignals.map(s => s.confidence))
195
+ : overallScore,
194
196
  explanation: buildFeedbackExplanation(matchingSignals, overallScore, 'confirmed'),
195
197
  signals: matchingSignals,
196
198
  topSignals: matchingSignals.slice(0, 3).map(s => ({
@@ -240,42 +242,6 @@ export function scoreUIFeedback(signals, expectation, trace) {
240
242
  };
241
243
  }
242
244
 
243
- /**
244
- * Infer expected feedback types from expectation
245
- */
246
- function inferExpectedFeedbackTypes(expectation) {
247
- const types = [];
248
-
249
- if (!expectation) return types;
250
-
251
- // Network expectations → loading + toast/error
252
- if (expectation.type === 'network_action' || expectation.type === 'network') {
253
- types.push(FEEDBACK_TYPE.LOADING);
254
- types.push(FEEDBACK_TYPE.TOAST);
255
- types.push(FEEDBACK_TYPE.INLINE_MESSAGE);
256
- }
257
-
258
- // Navigation expectations → DOM change or modal
259
- if (expectation.type === 'navigation' || expectation.type === 'spa_navigation') {
260
- types.push(FEEDBACK_TYPE.DOM_CHANGE);
261
- types.push(FEEDBACK_TYPE.MODAL);
262
- }
263
-
264
- // State expectations → DOM change or disabled state
265
- if (expectation.type === 'state_action' || expectation.type === 'state') {
266
- types.push(FEEDBACK_TYPE.DOM_CHANGE);
267
- types.push(FEEDBACK_TYPE.DISABLED);
268
- }
269
-
270
- // Validation expectations → inline message
271
- if (expectation.type === 'validation' || expectation.type === 'form_submission') {
272
- types.push(FEEDBACK_TYPE.INLINE_MESSAGE);
273
- types.push(FEEDBACK_TYPE.TOAST);
274
- }
275
-
276
- return types;
277
- }
278
-
279
245
  /**
280
246
  * Build explanation for feedback score
281
247
  */
@@ -313,24 +279,24 @@ function buildFeedbackExplanation(signals, overallScore, outcome, context = {})
313
279
  /**
314
280
  * Helper functions to find selectors
315
281
  */
316
- function findLoadingSelector(signals) {
282
+ function findLoadingSelector(_signals) {
317
283
  // Return a generic selector hint
318
284
  return '[aria-busy="true"], [data-loading], [role="status"]';
319
285
  }
320
286
 
321
- function findDisabledSelector(signals) {
287
+ function findDisabledSelector(_signals) {
322
288
  return '[disabled], [aria-disabled="true"]';
323
289
  }
324
290
 
325
- function findToastSelector(signals) {
291
+ function findToastSelector(_signals) {
326
292
  return '[role="alert"], [role="status"], [aria-live], .toast, .snackbar';
327
293
  }
328
294
 
329
- function findDialogSelector(signals) {
295
+ function findDialogSelector(_signals) {
330
296
  return '[role="dialog"], [aria-modal="true"]';
331
297
  }
332
298
 
333
- function findInlineMessageSelector(signals) {
299
+ function findInlineMessageSelector(_signals) {
334
300
  return '[role="alert"], .error, .success, [class*="message"]';
335
301
  }
336
302
 
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Conditional UI Stale State Detection
3
+ *
4
+ * Detects UI elements that should update/disappear when state changes but don't:
5
+ * - State mutation observed (via state sensor or console logs)
6
+ * - Dependent UI element remains unchanged
7
+ * - Expected element missing or still visible
8
+ *
9
+ * CONFIDENCE: MEDIUM (heuristic-based)
10
+ * PARTIAL SUPPORT: Heuristic detection, not semantic analysis
11
+ *
12
+ * Note: Does NOT detect async race conditions (UNSUPPORTED - too many false positives)
13
+ */
14
+
15
+ import { hasDomChange } from './comparison.js';
16
+ import { enrichFindingWithExplanations } from './finding-detector.js';
17
+
18
+ export function detectConditionalUiSilentFailures(traces, manifest, findings) {
19
+ // Parameters:
20
+ // traces - array of interaction traces from observation
21
+ // manifest - project manifest (contains expectations)
22
+ // findings - array to append new findings to (mutated in-place)
23
+
24
+ for (const trace of traces) {
25
+ const sensors = trace.sensors || {};
26
+ const stateSignals = sensors.state || {};
27
+ const uiSignals = sensors.uiSignals || {};
28
+ const uiDiff = uiSignals.diff || {};
29
+ const domChanged = hasDomChange(trace);
30
+
31
+ // Heuristic: State changed but UI didn't
32
+ // This suggests a stale UI or conditional rendering bug
33
+ const stateChanged = stateSignals.changed === true ||
34
+ (stateSignals.changed && stateSignals.changed.length > 0);
35
+ const uiChanged = uiDiff.changed === true;
36
+
37
+ // Detection logic:
38
+ // State changed but UI did not
39
+ // This is a common pattern for stale UI bugs in React/Vue
40
+ if (stateChanged && !uiChanged && !domChanged) {
41
+ const interaction = trace.interaction || {};
42
+
43
+ // Skip if it's a form input (expected state-only change)
44
+ if (interaction.type === 'interaction' && interaction.category === 'button') {
45
+ const evidence = {
46
+ before: trace.before?.screenshot || trace.beforeScreenshot || '',
47
+ after: trace.after?.screenshot || trace.afterScreenshot || '',
48
+ beforeUrl: trace.before?.url || trace.beforeUrl || '',
49
+ afterUrl: trace.after?.url || trace.afterUrl || '',
50
+ stateChanged,
51
+ uiChanged,
52
+ domChanged,
53
+ reason: 'State updated but UI did not reflect the change (stale UI)'
54
+ };
55
+
56
+ const finding = {
57
+ type: 'conditional_ui_silent_failure',
58
+ description: `Conditional UI element did not update when state changed`,
59
+ summary: `Button/interaction caused state change but UI did not update (stale UI pattern)`,
60
+ explanation: `State mutation was detected but the UI elements dependent on that state did not update. This is a common pattern in React/Vue applications where conditional rendering or dynamic classes don't update properly.`,
61
+ evidence,
62
+ confidence: {
63
+ level: 0.60, // MEDIUM - heuristic-based
64
+ reasons: [
65
+ 'State mutation observed',
66
+ 'UI elements did not update to reflect new state',
67
+ 'Likely stale UI or conditional rendering bug'
68
+ ]
69
+ },
70
+ promise: {
71
+ type: 'conditional_ui_update',
72
+ expected: 'State change triggers UI update (conditional render, class change, etc.)',
73
+ actual: 'State changed but UI remained unchanged'
74
+ },
75
+ capabilityNote: 'PARTIAL SUPPORT: Detection based on state sensor data and heuristics. Does not perform semantic analysis of UI logic. Async race conditions are UNSUPPORTED due to high false positive rate.'
76
+ };
77
+
78
+ // Enrich with explanations
79
+ enrichFindingWithExplanations(finding, trace);
80
+ findings.push(finding);
81
+ }
82
+ }
83
+ }
84
+ }