@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.
Files changed (213) hide show
  1. package/README.md +10 -6
  2. package/bin/verax.js +11 -11
  3. package/package.json +29 -8
  4. package/src/cli/commands/baseline.js +103 -0
  5. package/src/cli/commands/default.js +51 -6
  6. package/src/cli/commands/doctor.js +29 -0
  7. package/src/cli/commands/ga.js +246 -0
  8. package/src/cli/commands/gates.js +95 -0
  9. package/src/cli/commands/inspect.js +4 -2
  10. package/src/cli/commands/release-check.js +215 -0
  11. package/src/cli/commands/run.js +45 -6
  12. package/src/cli/commands/security-check.js +212 -0
  13. package/src/cli/commands/truth.js +113 -0
  14. package/src/cli/entry.js +30 -20
  15. package/src/cli/util/angular-component-extractor.js +179 -0
  16. package/src/cli/util/angular-navigation-detector.js +141 -0
  17. package/src/cli/util/angular-network-detector.js +161 -0
  18. package/src/cli/util/angular-state-detector.js +162 -0
  19. package/src/cli/util/ast-interactive-detector.js +544 -0
  20. package/src/cli/util/ast-network-detector.js +603 -0
  21. package/src/cli/util/ast-promise-extractor.js +581 -0
  22. package/src/cli/util/ast-usestate-detector.js +602 -0
  23. package/src/cli/util/atomic-write.js +12 -1
  24. package/src/cli/util/bootstrap-guard.js +86 -0
  25. package/src/cli/util/console-reporter.js +72 -0
  26. package/src/cli/util/detection-engine.js +105 -41
  27. package/src/cli/util/determinism-runner.js +124 -0
  28. package/src/cli/util/determinism-writer.js +129 -0
  29. package/src/cli/util/digest-engine.js +359 -0
  30. package/src/cli/util/dom-diff.js +226 -0
  31. package/src/cli/util/evidence-engine.js +287 -0
  32. package/src/cli/util/expectation-extractor.js +151 -5
  33. package/src/cli/util/findings-writer.js +3 -0
  34. package/src/cli/util/framework-detector.js +572 -0
  35. package/src/cli/util/idgen.js +1 -1
  36. package/src/cli/util/interaction-planner.js +529 -0
  37. package/src/cli/util/learn-writer.js +2 -0
  38. package/src/cli/util/ledger-writer.js +110 -0
  39. package/src/cli/util/monorepo-resolver.js +162 -0
  40. package/src/cli/util/observation-engine.js +127 -278
  41. package/src/cli/util/observe-writer.js +2 -0
  42. package/src/cli/util/project-discovery.js +284 -0
  43. package/src/cli/util/project-writer.js +2 -0
  44. package/src/cli/util/run-id.js +23 -27
  45. package/src/cli/util/run-resolver.js +64 -0
  46. package/src/cli/util/run-result.js +778 -0
  47. package/src/cli/util/selector-resolver.js +235 -0
  48. package/src/cli/util/source-requirement.js +55 -0
  49. package/src/cli/util/summary-writer.js +2 -0
  50. package/src/cli/util/svelte-navigation-detector.js +163 -0
  51. package/src/cli/util/svelte-network-detector.js +80 -0
  52. package/src/cli/util/svelte-sfc-extractor.js +146 -0
  53. package/src/cli/util/svelte-state-detector.js +242 -0
  54. package/src/cli/util/trust-activation-integration.js +496 -0
  55. package/src/cli/util/trust-activation-wrapper.js +85 -0
  56. package/src/cli/util/trust-integration-hooks.js +164 -0
  57. package/src/cli/util/types.js +153 -0
  58. package/src/cli/util/url-validation.js +40 -0
  59. package/src/cli/util/vue-navigation-detector.js +178 -0
  60. package/src/cli/util/vue-sfc-extractor.js +161 -0
  61. package/src/cli/util/vue-state-detector.js +215 -0
  62. package/src/types/fs-augment.d.ts +23 -0
  63. package/src/types/global.d.ts +137 -0
  64. package/src/types/internal-types.d.ts +35 -0
  65. package/src/verax/cli/init.js +4 -18
  66. package/src/verax/core/action-classifier.js +4 -3
  67. package/src/verax/core/artifacts/registry.js +139 -0
  68. package/src/verax/core/artifacts/verifier.js +990 -0
  69. package/src/verax/core/baseline/baseline.enforcer.js +137 -0
  70. package/src/verax/core/baseline/baseline.snapshot.js +233 -0
  71. package/src/verax/core/capabilities/gates.js +505 -0
  72. package/src/verax/core/capabilities/registry.js +475 -0
  73. package/src/verax/core/confidence/confidence-compute.js +144 -0
  74. package/src/verax/core/confidence/confidence-invariants.js +234 -0
  75. package/src/verax/core/confidence/confidence-report-writer.js +112 -0
  76. package/src/verax/core/confidence/confidence-weights.js +44 -0
  77. package/src/verax/core/confidence/confidence.defaults.js +65 -0
  78. package/src/verax/core/confidence/confidence.loader.js +80 -0
  79. package/src/verax/core/confidence/confidence.schema.js +94 -0
  80. package/src/verax/core/confidence-engine-refactor.js +489 -0
  81. package/src/verax/core/confidence-engine.js +625 -0
  82. package/src/verax/core/contracts/index.js +29 -0
  83. package/src/verax/core/contracts/types.js +186 -0
  84. package/src/verax/core/contracts/validators.js +456 -0
  85. package/src/verax/core/decisions/decision.trace.js +278 -0
  86. package/src/verax/core/determinism/contract-writer.js +89 -0
  87. package/src/verax/core/determinism/contract.js +139 -0
  88. package/src/verax/core/determinism/diff.js +405 -0
  89. package/src/verax/core/determinism/engine.js +222 -0
  90. package/src/verax/core/determinism/finding-identity.js +149 -0
  91. package/src/verax/core/determinism/normalize.js +466 -0
  92. package/src/verax/core/determinism/report-writer.js +93 -0
  93. package/src/verax/core/determinism/run-fingerprint.js +123 -0
  94. package/src/verax/core/dynamic-route-intelligence.js +529 -0
  95. package/src/verax/core/evidence/evidence-capture-service.js +308 -0
  96. package/src/verax/core/evidence/evidence-intent-ledger.js +166 -0
  97. package/src/verax/core/evidence-builder.js +487 -0
  98. package/src/verax/core/execution-mode-context.js +77 -0
  99. package/src/verax/core/execution-mode-detector.js +192 -0
  100. package/src/verax/core/failures/exit-codes.js +88 -0
  101. package/src/verax/core/failures/failure-summary.js +76 -0
  102. package/src/verax/core/failures/failure.factory.js +225 -0
  103. package/src/verax/core/failures/failure.ledger.js +133 -0
  104. package/src/verax/core/failures/failure.types.js +196 -0
  105. package/src/verax/core/failures/index.js +10 -0
  106. package/src/verax/core/ga/ga-report-writer.js +43 -0
  107. package/src/verax/core/ga/ga.artifact.js +49 -0
  108. package/src/verax/core/ga/ga.contract.js +435 -0
  109. package/src/verax/core/ga/ga.enforcer.js +87 -0
  110. package/src/verax/core/guardrails/guardrails-report-writer.js +109 -0
  111. package/src/verax/core/guardrails/policy.defaults.js +210 -0
  112. package/src/verax/core/guardrails/policy.loader.js +84 -0
  113. package/src/verax/core/guardrails/policy.schema.js +110 -0
  114. package/src/verax/core/guardrails/truth-reconciliation.js +136 -0
  115. package/src/verax/core/guardrails-engine.js +505 -0
  116. package/src/verax/core/incremental-store.js +1 -0
  117. package/src/verax/core/integrity/budget.js +138 -0
  118. package/src/verax/core/integrity/determinism.js +342 -0
  119. package/src/verax/core/integrity/integrity.js +208 -0
  120. package/src/verax/core/integrity/poisoning.js +108 -0
  121. package/src/verax/core/integrity/transaction.js +140 -0
  122. package/src/verax/core/observe/run-timeline.js +318 -0
  123. package/src/verax/core/perf/perf.contract.js +186 -0
  124. package/src/verax/core/perf/perf.display.js +65 -0
  125. package/src/verax/core/perf/perf.enforcer.js +91 -0
  126. package/src/verax/core/perf/perf.monitor.js +209 -0
  127. package/src/verax/core/perf/perf.report.js +200 -0
  128. package/src/verax/core/pipeline-tracker.js +243 -0
  129. package/src/verax/core/product-definition.js +127 -0
  130. package/src/verax/core/release/provenance.builder.js +130 -0
  131. package/src/verax/core/release/release-report-writer.js +40 -0
  132. package/src/verax/core/release/release.enforcer.js +164 -0
  133. package/src/verax/core/release/reproducibility.check.js +222 -0
  134. package/src/verax/core/release/sbom.builder.js +292 -0
  135. package/src/verax/core/replay-validator.js +2 -0
  136. package/src/verax/core/replay.js +4 -0
  137. package/src/verax/core/report/cross-index.js +195 -0
  138. package/src/verax/core/report/human-summary.js +362 -0
  139. package/src/verax/core/route-intelligence.js +420 -0
  140. package/src/verax/core/run-id.js +6 -3
  141. package/src/verax/core/run-manifest.js +4 -3
  142. package/src/verax/core/security/secrets.scan.js +329 -0
  143. package/src/verax/core/security/security-report.js +50 -0
  144. package/src/verax/core/security/security.enforcer.js +128 -0
  145. package/src/verax/core/security/supplychain.defaults.json +38 -0
  146. package/src/verax/core/security/supplychain.policy.js +334 -0
  147. package/src/verax/core/security/vuln.scan.js +265 -0
  148. package/src/verax/core/truth/truth.certificate.js +252 -0
  149. package/src/verax/core/ui-feedback-intelligence.js +481 -0
  150. package/src/verax/detect/conditional-ui-silent-failure.js +84 -0
  151. package/src/verax/detect/confidence-engine.js +62 -34
  152. package/src/verax/detect/confidence-helper.js +34 -0
  153. package/src/verax/detect/dynamic-route-findings.js +338 -0
  154. package/src/verax/detect/expectation-chain-detector.js +417 -0
  155. package/src/verax/detect/expectation-model.js +2 -2
  156. package/src/verax/detect/failure-cause-inference.js +293 -0
  157. package/src/verax/detect/findings-writer.js +131 -35
  158. package/src/verax/detect/flow-detector.js +2 -2
  159. package/src/verax/detect/form-silent-failure.js +98 -0
  160. package/src/verax/detect/index.js +46 -5
  161. package/src/verax/detect/invariants-enforcer.js +147 -0
  162. package/src/verax/detect/journey-stall-detector.js +558 -0
  163. package/src/verax/detect/navigation-silent-failure.js +82 -0
  164. package/src/verax/detect/problem-aggregator.js +361 -0
  165. package/src/verax/detect/route-findings.js +219 -0
  166. package/src/verax/detect/summary-writer.js +477 -0
  167. package/src/verax/detect/test-failure-cause-inference.js +314 -0
  168. package/src/verax/detect/ui-feedback-findings.js +207 -0
  169. package/src/verax/detect/view-switch-correlator.js +242 -0
  170. package/src/verax/flow/flow-engine.js +2 -1
  171. package/src/verax/flow/flow-spec.js +0 -6
  172. package/src/verax/index.js +4 -0
  173. package/src/verax/intel/ts-program.js +1 -0
  174. package/src/verax/intel/vue-navigation-extractor.js +3 -0
  175. package/src/verax/learn/action-contract-extractor.js +3 -0
  176. package/src/verax/learn/ast-contract-extractor.js +1 -1
  177. package/src/verax/learn/flow-extractor.js +1 -0
  178. package/src/verax/learn/project-detector.js +5 -0
  179. package/src/verax/learn/react-router-extractor.js +2 -0
  180. package/src/verax/learn/source-instrumenter.js +1 -0
  181. package/src/verax/learn/state-extractor.js +2 -1
  182. package/src/verax/learn/static-extractor.js +1 -0
  183. package/src/verax/observe/coverage-gaps.js +132 -0
  184. package/src/verax/observe/expectation-handler.js +126 -0
  185. package/src/verax/observe/incremental-skip.js +46 -0
  186. package/src/verax/observe/index.js +51 -155
  187. package/src/verax/observe/interaction-executor.js +192 -0
  188. package/src/verax/observe/interaction-runner.js +782 -513
  189. package/src/verax/observe/network-firewall.js +86 -0
  190. package/src/verax/observe/observation-builder.js +169 -0
  191. package/src/verax/observe/observe-context.js +205 -0
  192. package/src/verax/observe/observe-helpers.js +192 -0
  193. package/src/verax/observe/observe-runner.js +230 -0
  194. package/src/verax/observe/observers/budget-observer.js +185 -0
  195. package/src/verax/observe/observers/console-observer.js +102 -0
  196. package/src/verax/observe/observers/coverage-observer.js +107 -0
  197. package/src/verax/observe/observers/interaction-observer.js +471 -0
  198. package/src/verax/observe/observers/navigation-observer.js +132 -0
  199. package/src/verax/observe/observers/network-observer.js +87 -0
  200. package/src/verax/observe/observers/safety-observer.js +82 -0
  201. package/src/verax/observe/observers/ui-feedback-observer.js +99 -0
  202. package/src/verax/observe/page-traversal.js +138 -0
  203. package/src/verax/observe/snapshot-ops.js +94 -0
  204. package/src/verax/observe/ui-feedback-detector.js +742 -0
  205. package/src/verax/scan-summary-writer.js +2 -0
  206. package/src/verax/shared/artifact-manager.js +25 -5
  207. package/src/verax/shared/caching.js +1 -0
  208. package/src/verax/shared/css-spinner-rules.js +204 -0
  209. package/src/verax/shared/expectation-tracker.js +1 -0
  210. package/src/verax/shared/view-switch-rules.js +208 -0
  211. package/src/verax/shared/zip-artifacts.js +6 -0
  212. package/src/verax/shared/config-loader.js +0 -169
  213. /package/src/verax/shared/{expectation-proof.js → expectation-validation.js} +0 -0
@@ -0,0 +1,137 @@
1
+ /**
2
+ * PHASE 21.11 — Baseline Enforcer
3
+ *
4
+ * Enforces baseline integrity. Detects drift and blocks changes after GA.
5
+ */
6
+
7
+ import { loadBaselineSnapshot, buildBaselineSnapshot } from './baseline.snapshot.js';
8
+ import { FAILURE_CODE, createInternalFailure } from '../failures/index.js';
9
+
10
+ /**
11
+ * Compare two baseline snapshots
12
+ *
13
+ * @param {Object} current - Current baseline
14
+ * @param {Object} frozen - Frozen baseline (from GA)
15
+ * @returns {Object} Comparison result
16
+ */
17
+ export function compareBaselines(current, frozen) {
18
+ if (!frozen) {
19
+ return {
20
+ drifted: false,
21
+ message: 'No frozen baseline found (pre-GA)',
22
+ differences: []
23
+ };
24
+ }
25
+
26
+ if (!frozen.frozen) {
27
+ return {
28
+ drifted: false,
29
+ message: 'Baseline not frozen (pre-GA)',
30
+ differences: []
31
+ };
32
+ }
33
+
34
+ const differences = [];
35
+
36
+ // Compare baseline hash
37
+ if (current.baselineHash !== frozen.baselineHash) {
38
+ differences.push({
39
+ type: 'BASELINE_HASH_MISMATCH',
40
+ message: 'Baseline hash changed',
41
+ current: current.baselineHash,
42
+ frozen: frozen.baselineHash
43
+ });
44
+ }
45
+
46
+ // Compare individual hashes
47
+ for (const [key, frozenHash] of Object.entries(frozen.hashes || {})) {
48
+ const currentHash = current.hashes?.[key];
49
+ if (currentHash && currentHash !== frozenHash) {
50
+ differences.push({
51
+ type: 'HASH_MISMATCH',
52
+ component: key,
53
+ message: `${key} hash changed`,
54
+ current: currentHash,
55
+ frozen: frozenHash
56
+ });
57
+ }
58
+ }
59
+
60
+ return {
61
+ drifted: differences.length > 0,
62
+ message: differences.length > 0
63
+ ? `Baseline drift detected: ${differences.length} difference(s)`
64
+ : 'No baseline drift',
65
+ differences
66
+ };
67
+ }
68
+
69
+ /**
70
+ * Enforce baseline integrity
71
+ *
72
+ * @param {string} projectDir - Project directory
73
+ * @param {Object} failureLedger - Failure ledger instance
74
+ * @returns {Object} Enforcement result
75
+ */
76
+ export function enforceBaseline(projectDir, failureLedger) {
77
+ const frozen = loadBaselineSnapshot(projectDir);
78
+
79
+ // If no frozen baseline, allow (pre-GA)
80
+ if (!frozen || !frozen.frozen) {
81
+ return {
82
+ blocked: false,
83
+ message: 'No frozen baseline (pre-GA)',
84
+ drifted: false
85
+ };
86
+ }
87
+
88
+ // Build current baseline
89
+ const current = buildBaselineSnapshot(projectDir);
90
+
91
+ // Compare
92
+ const comparison = compareBaselines(current, frozen);
93
+
94
+ if (comparison.drifted) {
95
+ // Record BLOCKING failure
96
+ const failure = createInternalFailure(
97
+ FAILURE_CODE.BASELINE_DRIFT,
98
+ `BASELINE_DRIFT: ${comparison.message}. Changes to core contracts/policies after GA require MAJOR version bump and baseline regeneration.`,
99
+ 'baseline',
100
+ {
101
+ differences: comparison.differences,
102
+ frozenCommit: frozen.gitCommit,
103
+ currentCommit: current.gitCommit,
104
+ frozenVersion: frozen.veraxVersion,
105
+ currentVersion: current.veraxVersion
106
+ },
107
+ false // Not recoverable
108
+ );
109
+
110
+ failureLedger.record(failure);
111
+
112
+ return {
113
+ blocked: true,
114
+ message: comparison.message,
115
+ drifted: true,
116
+ differences: comparison.differences
117
+ };
118
+ }
119
+
120
+ return {
121
+ blocked: false,
122
+ message: 'Baseline integrity maintained',
123
+ drifted: false
124
+ };
125
+ }
126
+
127
+ /**
128
+ * Check if baseline is frozen
129
+ *
130
+ * @param {string} projectDir - Project directory
131
+ * @returns {boolean} True if frozen
132
+ */
133
+ export function isBaselineFrozen(projectDir) {
134
+ const snapshot = loadBaselineSnapshot(projectDir);
135
+ return snapshot?.frozen === true;
136
+ }
137
+
@@ -0,0 +1,233 @@
1
+ /**
2
+ * PHASE 21.11 — Immutable Baseline Snapshot
3
+ *
4
+ * Creates a snapshot of all core contracts, policies, and criteria.
5
+ * Any drift from this baseline after GA is BLOCKING.
6
+ */
7
+
8
+ import { readFileSync, existsSync, writeFileSync } from 'fs';
9
+ import { resolve } from 'path';
10
+ import { createHash } from 'crypto';
11
+ import { VERAX_PRODUCT_DEFINITION } from '../product-definition.js';
12
+
13
+ /**
14
+ * Compute SHA256 hash of content
15
+ */
16
+ function hashContent(content) {
17
+ return createHash('sha256').update(content).digest('hex');
18
+ }
19
+
20
+ /**
21
+ * Load and hash a file
22
+ */
23
+ function hashFile(filePath) {
24
+ if (!existsSync(filePath)) {
25
+ return null;
26
+ }
27
+ try {
28
+ const content = readFileSync(filePath, 'utf-8');
29
+ return hashContent(content);
30
+ } catch {
31
+ return null;
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Get git commit hash
37
+ */
38
+ function getGitCommit() {
39
+ try {
40
+ const { execSync } = require('child_process');
41
+ return execSync('git rev-parse HEAD', { encoding: 'utf-8' }).trim();
42
+ } catch {
43
+ return 'unknown';
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Check if git repo is dirty
49
+ */
50
+ function isGitDirty() {
51
+ try {
52
+ const { execSync } = require('child_process');
53
+ const status = execSync('git status --porcelain', { encoding: 'utf-8' });
54
+ return status.trim().length > 0;
55
+ } catch {
56
+ return false;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Get VERAX version
62
+ */
63
+ function getVeraxVersion() {
64
+ try {
65
+ // @ts-expect-error - readFileSync with encoding returns string
66
+ const packageJson = JSON.parse(readFileSync(resolve(process.cwd(), 'package.json'), 'utf-8'));
67
+ return packageJson.version || 'unknown';
68
+ } catch {
69
+ return 'unknown';
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Build baseline snapshot
75
+ *
76
+ * @param {string} projectDir - Project directory
77
+ * @returns {Object} Baseline snapshot
78
+ */
79
+ export function buildBaselineSnapshot(projectDir) {
80
+ const coreDir = resolve(projectDir, 'src', 'verax', 'core');
81
+
82
+ // Core contracts
83
+ const evidenceLaw = hashContent(JSON.stringify(VERAX_PRODUCT_DEFINITION.evidenceLaw));
84
+ const productDefinition = hashFile(resolve(coreDir, 'product-definition.js'));
85
+
86
+ // Confidence defaults
87
+ const confidenceEngine = hashFile(resolve(coreDir, 'confidence-engine.js'));
88
+ const confidenceDefaults = hashFile(resolve(coreDir, 'confidence-engine-refactor.js'));
89
+
90
+ // Guardrails defaults
91
+ const guardrailsDefaults = hashFile(resolve(coreDir, 'guardrails', 'defaults.json'));
92
+ const guardrailsContract = hashFile(resolve(coreDir, 'guardrails', 'contract.js'));
93
+
94
+ // GA criteria
95
+ const gaContract = hashFile(resolve(coreDir, 'ga', 'ga.contract.js'));
96
+
97
+ // Performance budgets
98
+ const perfContract = hashFile(resolve(coreDir, 'perf', 'perf.contract.js'));
99
+ const perfProfiles = hashFile(resolve(projectDir, 'src', 'verax', 'shared', 'budget-profiles.js'));
100
+
101
+ // Security policies
102
+ const supplychainPolicy = hashFile(resolve(coreDir, 'security', 'supplychain.policy.js'));
103
+ const supplychainDefaults = hashFile(resolve(coreDir, 'security', 'supplychain.defaults.json'));
104
+
105
+ // Failure taxonomy
106
+ const failureTypes = hashFile(resolve(coreDir, 'failures', 'failure.types.js'));
107
+ const failureLedger = hashFile(resolve(coreDir, 'failures', 'failure.ledger.js'));
108
+
109
+ // Contracts
110
+ const contractsIndex = hashFile(resolve(coreDir, 'contracts', 'index.js'));
111
+ const contractsValidators = hashFile(resolve(coreDir, 'contracts', 'validators.js'));
112
+ const contractsTypes = hashFile(resolve(coreDir, 'contracts', 'types.js'));
113
+
114
+ // Determinism
115
+ const determinismContract = hashFile(resolve(coreDir, 'determinism', 'contract.js'));
116
+
117
+ // Evidence builder
118
+ const evidenceBuilder = hashFile(resolve(coreDir, 'evidence-builder.js'));
119
+
120
+ const snapshot = {
121
+ version: 1,
122
+ timestamp: new Date().toISOString(),
123
+ veraxVersion: getVeraxVersion(),
124
+ gitCommit: getGitCommit(),
125
+ gitDirty: isGitDirty(),
126
+
127
+ hashes: {
128
+ // Core contracts
129
+ evidenceLaw,
130
+ productDefinition,
131
+
132
+ // Confidence
133
+ confidenceEngine,
134
+ confidenceDefaults,
135
+
136
+ // Guardrails
137
+ guardrailsDefaults,
138
+ guardrailsContract,
139
+
140
+ // GA
141
+ gaContract,
142
+
143
+ // Performance
144
+ perfContract,
145
+ perfProfiles,
146
+
147
+ // Security
148
+ supplychainPolicy,
149
+ supplychainDefaults,
150
+
151
+ // Failures
152
+ failureTypes,
153
+ failureLedger,
154
+
155
+ // Contracts
156
+ contractsIndex,
157
+ contractsValidators,
158
+ contractsTypes,
159
+
160
+ // Determinism
161
+ determinismContract,
162
+
163
+ // Evidence
164
+ evidenceBuilder
165
+ },
166
+
167
+ // Combined hash for quick comparison
168
+ baselineHash: hashContent(JSON.stringify({
169
+ evidenceLaw,
170
+ productDefinition,
171
+ confidenceEngine,
172
+ confidenceDefaults,
173
+ guardrailsDefaults,
174
+ guardrailsContract,
175
+ gaContract,
176
+ perfContract,
177
+ perfProfiles,
178
+ supplychainPolicy,
179
+ supplychainDefaults,
180
+ failureTypes,
181
+ failureLedger,
182
+ contractsIndex,
183
+ contractsValidators,
184
+ contractsTypes,
185
+ determinismContract,
186
+ evidenceBuilder
187
+ }))
188
+ };
189
+
190
+ return snapshot;
191
+ }
192
+
193
+ /**
194
+ * Write baseline snapshot to file
195
+ *
196
+ * @param {string} projectDir - Project directory
197
+ * @param {Object} snapshot - Baseline snapshot
198
+ * @param {boolean} gaStatus - GA status
199
+ * @returns {string} Path to written file
200
+ */
201
+ export function writeBaselineSnapshot(projectDir, snapshot, gaStatus = false) {
202
+ const snapshotWithGA = {
203
+ ...snapshot,
204
+ gaStatus: gaStatus ? 'GA-READY' : 'PRE-GA',
205
+ frozen: gaStatus // After GA, baseline is frozen
206
+ };
207
+
208
+ const outputPath = resolve(projectDir, 'baseline.snapshot.json');
209
+ writeFileSync(outputPath, JSON.stringify(snapshotWithGA, null, 2), 'utf-8');
210
+ return outputPath;
211
+ }
212
+
213
+ /**
214
+ * Load baseline snapshot from file
215
+ *
216
+ * @param {string} projectDir - Project directory
217
+ * @returns {Object|null} Baseline snapshot or null
218
+ */
219
+ export function loadBaselineSnapshot(projectDir) {
220
+ const snapshotPath = resolve(projectDir, 'baseline.snapshot.json');
221
+
222
+ if (!existsSync(snapshotPath)) {
223
+ return null;
224
+ }
225
+
226
+ try {
227
+ // @ts-expect-error - readFileSync with encoding returns string
228
+ return JSON.parse(readFileSync(snapshotPath, 'utf-8'));
229
+ } catch {
230
+ return null;
231
+ }
232
+ }
233
+