vibecheck-ai 2.0.1 → 5.0.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 (456) hide show
  1. package/bin/.generated +25 -0
  2. package/bin/_deprecations.js +463 -0
  3. package/bin/_router.js +46 -0
  4. package/bin/cli-hygiene.js +241 -0
  5. package/bin/dev/run-v2-torture.js +30 -0
  6. package/bin/registry.js +656 -0
  7. package/bin/runners/CLI_REFACTOR_SUMMARY.md +229 -0
  8. package/bin/runners/ENHANCEMENT_GUIDE.md +121 -0
  9. package/bin/runners/REPORT_AUDIT.md +64 -0
  10. package/bin/runners/cli-utils.js +1070 -0
  11. package/bin/runners/context/ai-task-decomposer.js +337 -0
  12. package/bin/runners/context/analyzer.js +513 -0
  13. package/bin/runners/context/api-contracts.js +427 -0
  14. package/bin/runners/context/context-diff.js +342 -0
  15. package/bin/runners/context/context-pruner.js +291 -0
  16. package/bin/runners/context/dependency-graph.js +414 -0
  17. package/bin/runners/context/generators/claude.js +107 -0
  18. package/bin/runners/context/generators/codex.js +108 -0
  19. package/bin/runners/context/generators/copilot.js +119 -0
  20. package/bin/runners/context/generators/cursor-enhanced.js +2525 -0
  21. package/bin/runners/context/generators/cursor.js +514 -0
  22. package/bin/runners/context/generators/mcp.js +169 -0
  23. package/bin/runners/context/generators/windsurf.js +180 -0
  24. package/bin/runners/context/git-context.js +304 -0
  25. package/bin/runners/context/index.js +1110 -0
  26. package/bin/runners/context/insights.js +173 -0
  27. package/bin/runners/context/mcp-server/generate-rules.js +337 -0
  28. package/bin/runners/context/mcp-server/index.js +1176 -0
  29. package/bin/runners/context/mcp-server/package.json +24 -0
  30. package/bin/runners/context/memory.js +200 -0
  31. package/bin/runners/context/monorepo.js +215 -0
  32. package/bin/runners/context/multi-repo-federation.js +404 -0
  33. package/bin/runners/context/patterns.js +253 -0
  34. package/bin/runners/context/proof-context.js +1264 -0
  35. package/bin/runners/context/security-scanner.js +541 -0
  36. package/bin/runners/context/semantic-search.js +350 -0
  37. package/bin/runners/context/shared.js +264 -0
  38. package/bin/runners/context/team-conventions.js +336 -0
  39. package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -0
  40. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +474 -0
  41. package/bin/runners/lib/agent-firewall/change-packet/builder.js +488 -0
  42. package/bin/runners/lib/agent-firewall/change-packet/schema.json +228 -0
  43. package/bin/runners/lib/agent-firewall/change-packet/store.js +200 -0
  44. package/bin/runners/lib/agent-firewall/claims/claim-types.js +21 -0
  45. package/bin/runners/lib/agent-firewall/claims/extractor.js +303 -0
  46. package/bin/runners/lib/agent-firewall/claims/patterns.js +24 -0
  47. package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
  48. package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
  49. package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
  50. package/bin/runners/lib/agent-firewall/enforcement/gateway.js +1059 -0
  51. package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -0
  52. package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -0
  53. package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -0
  54. package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -0
  55. package/bin/runners/lib/agent-firewall/enforcement/schemas/change-event.schema.json +173 -0
  56. package/bin/runners/lib/agent-firewall/enforcement/schemas/intent.schema.json +181 -0
  57. package/bin/runners/lib/agent-firewall/enforcement/schemas/verdict.schema.json +222 -0
  58. package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -0
  59. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +88 -0
  60. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +75 -0
  61. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +127 -0
  62. package/bin/runners/lib/agent-firewall/evidence/resolver.js +102 -0
  63. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +213 -0
  64. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +145 -0
  65. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +19 -0
  66. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +87 -0
  67. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +184 -0
  68. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +163 -0
  69. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +107 -0
  70. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +68 -0
  71. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +66 -0
  72. package/bin/runners/lib/agent-firewall/index.js +200 -0
  73. package/bin/runners/lib/agent-firewall/integration/index.js +20 -0
  74. package/bin/runners/lib/agent-firewall/integration/ship-gate.js +437 -0
  75. package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +634 -0
  76. package/bin/runners/lib/agent-firewall/intent/auto-detect.js +426 -0
  77. package/bin/runners/lib/agent-firewall/intent/index.js +102 -0
  78. package/bin/runners/lib/agent-firewall/intent/schema.js +352 -0
  79. package/bin/runners/lib/agent-firewall/intent/store.js +283 -0
  80. package/bin/runners/lib/agent-firewall/interception/fs-interceptor.js +502 -0
  81. package/bin/runners/lib/agent-firewall/interception/index.js +23 -0
  82. package/bin/runners/lib/agent-firewall/interceptor/base.js +308 -0
  83. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +35 -0
  84. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +35 -0
  85. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +34 -0
  86. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
  87. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
  88. package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
  89. package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
  90. package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
  91. package/bin/runners/lib/agent-firewall/logger.js +141 -0
  92. package/bin/runners/lib/agent-firewall/policy/default-policy.json +90 -0
  93. package/bin/runners/lib/agent-firewall/policy/engine.js +103 -0
  94. package/bin/runners/lib/agent-firewall/policy/loader.js +451 -0
  95. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +50 -0
  96. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +50 -0
  97. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +79 -0
  98. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +227 -0
  99. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +191 -0
  100. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +93 -0
  101. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +57 -0
  102. package/bin/runners/lib/agent-firewall/policy/schema.json +183 -0
  103. package/bin/runners/lib/agent-firewall/policy/verdict.js +54 -0
  104. package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
  105. package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
  106. package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
  107. package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
  108. package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
  109. package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
  110. package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
  111. package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
  112. package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
  113. package/bin/runners/lib/agent-firewall/risk/thresholds.js +322 -0
  114. package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
  115. package/bin/runners/lib/agent-firewall/session/collector.js +451 -0
  116. package/bin/runners/lib/agent-firewall/session/index.js +26 -0
  117. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
  118. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
  119. package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
  120. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
  121. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
  122. package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
  123. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
  124. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
  125. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
  126. package/bin/runners/lib/agent-firewall/truthpack/index.js +67 -0
  127. package/bin/runners/lib/agent-firewall/truthpack/loader.js +137 -0
  128. package/bin/runners/lib/agent-firewall/unblock/planner.js +337 -0
  129. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +118 -0
  130. package/bin/runners/lib/ai-bridge.js +416 -0
  131. package/bin/runners/lib/analysis-core.js +309 -0
  132. package/bin/runners/lib/analyzers.js +2500 -0
  133. package/bin/runners/lib/api-client.js +269 -0
  134. package/bin/runners/lib/approve-output.js +235 -0
  135. package/bin/runners/lib/artifact-envelope.js +540 -0
  136. package/bin/runners/lib/assets/vibecheck-logo.png +0 -0
  137. package/bin/runners/lib/audit-bridge.js +391 -0
  138. package/bin/runners/lib/auth-shared.js +977 -0
  139. package/bin/runners/lib/auth-truth.js +193 -0
  140. package/bin/runners/lib/auth.js +215 -0
  141. package/bin/runners/lib/authority-badge.js +425 -0
  142. package/bin/runners/lib/backup.js +62 -0
  143. package/bin/runners/lib/billing.js +107 -0
  144. package/bin/runners/lib/checkpoint.js +941 -0
  145. package/bin/runners/lib/claims.js +118 -0
  146. package/bin/runners/lib/classify-output.js +204 -0
  147. package/bin/runners/lib/cleanup/engine.js +571 -0
  148. package/bin/runners/lib/cleanup/index.js +53 -0
  149. package/bin/runners/lib/cleanup/output.js +375 -0
  150. package/bin/runners/lib/cleanup/rules.js +1060 -0
  151. package/bin/runners/lib/cli-output.js +400 -0
  152. package/bin/runners/lib/cli-ui.js +540 -0
  153. package/bin/runners/lib/compliance-bridge-new.js +0 -0
  154. package/bin/runners/lib/compliance-bridge.js +165 -0
  155. package/bin/runners/lib/contracts/auth-contract.js +202 -0
  156. package/bin/runners/lib/contracts/env-contract.js +181 -0
  157. package/bin/runners/lib/contracts/external-contract.js +206 -0
  158. package/bin/runners/lib/contracts/guard.js +168 -0
  159. package/bin/runners/lib/contracts/index.js +89 -0
  160. package/bin/runners/lib/contracts/plan-validator.js +311 -0
  161. package/bin/runners/lib/contracts/route-contract.js +199 -0
  162. package/bin/runners/lib/contracts.js +804 -0
  163. package/bin/runners/lib/default-config.js +127 -0
  164. package/bin/runners/lib/detect.js +89 -0
  165. package/bin/runners/lib/detectors-v2.js +622 -0
  166. package/bin/runners/lib/doctor/autofix.js +254 -0
  167. package/bin/runners/lib/doctor/diagnosis-receipt.js +454 -0
  168. package/bin/runners/lib/doctor/failure-signatures.js +526 -0
  169. package/bin/runners/lib/doctor/fix-script.js +336 -0
  170. package/bin/runners/lib/doctor/index.js +37 -0
  171. package/bin/runners/lib/doctor/modules/build-tools.js +453 -0
  172. package/bin/runners/lib/doctor/modules/dependencies.js +325 -0
  173. package/bin/runners/lib/doctor/modules/index.js +105 -0
  174. package/bin/runners/lib/doctor/modules/network.js +250 -0
  175. package/bin/runners/lib/doctor/modules/os-quirks.js +706 -0
  176. package/bin/runners/lib/doctor/modules/project.js +312 -0
  177. package/bin/runners/lib/doctor/modules/repo-integrity.js +485 -0
  178. package/bin/runners/lib/doctor/modules/runtime.js +224 -0
  179. package/bin/runners/lib/doctor/modules/security.js +350 -0
  180. package/bin/runners/lib/doctor/modules/system.js +213 -0
  181. package/bin/runners/lib/doctor/modules/vibecheck.js +394 -0
  182. package/bin/runners/lib/doctor/reporter.js +262 -0
  183. package/bin/runners/lib/doctor/safe-repair.js +384 -0
  184. package/bin/runners/lib/doctor/service.js +262 -0
  185. package/bin/runners/lib/doctor/types.js +113 -0
  186. package/bin/runners/lib/doctor/ui.js +263 -0
  187. package/bin/runners/lib/doctor-enhanced.js +233 -0
  188. package/bin/runners/lib/doctor-output.js +226 -0
  189. package/bin/runners/lib/doctor-v2.js +608 -0
  190. package/bin/runners/lib/drift.js +425 -0
  191. package/bin/runners/lib/enforcement.js +72 -0
  192. package/bin/runners/lib/engine/ast-cache.js +210 -0
  193. package/bin/runners/lib/engine/auth-extractor.js +211 -0
  194. package/bin/runners/lib/engine/billing-extractor.js +112 -0
  195. package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
  196. package/bin/runners/lib/engine/env-extractor.js +207 -0
  197. package/bin/runners/lib/engine/express-extractor.js +208 -0
  198. package/bin/runners/lib/engine/extractors.js +849 -0
  199. package/bin/runners/lib/engine/index.js +207 -0
  200. package/bin/runners/lib/engine/repo-index.js +514 -0
  201. package/bin/runners/lib/engine/types.js +124 -0
  202. package/bin/runners/lib/engines/accessibility-engine.js +190 -0
  203. package/bin/runners/lib/engines/api-consistency-engine.js +162 -0
  204. package/bin/runners/lib/engines/ast-cache.js +99 -0
  205. package/bin/runners/lib/engines/attack-detector.js +1192 -0
  206. package/bin/runners/lib/engines/code-quality-engine.js +255 -0
  207. package/bin/runners/lib/engines/console-logs-engine.js +115 -0
  208. package/bin/runners/lib/engines/cross-file-analysis-engine.js +268 -0
  209. package/bin/runners/lib/engines/dead-code-engine.js +198 -0
  210. package/bin/runners/lib/engines/deprecated-api-engine.js +226 -0
  211. package/bin/runners/lib/engines/empty-catch-engine.js +150 -0
  212. package/bin/runners/lib/engines/file-filter.js +131 -0
  213. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +251 -0
  214. package/bin/runners/lib/engines/mock-data-engine.js +272 -0
  215. package/bin/runners/lib/engines/parallel-processor.js +71 -0
  216. package/bin/runners/lib/engines/performance-issues-engine.js +265 -0
  217. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +243 -0
  218. package/bin/runners/lib/engines/todo-fixme-engine.js +115 -0
  219. package/bin/runners/lib/engines/type-aware-engine.js +152 -0
  220. package/bin/runners/lib/engines/unsafe-regex-engine.js +225 -0
  221. package/bin/runners/lib/engines/vibecheck-engines/README.md +53 -0
  222. package/bin/runners/lib/engines/vibecheck-engines/index.js +15 -0
  223. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
  224. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
  225. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
  226. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
  227. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
  228. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
  229. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
  230. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +139 -0
  231. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
  232. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
  233. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
  234. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
  235. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
  236. package/bin/runners/lib/engines/vibecheck-engines/package.json +13 -0
  237. package/bin/runners/lib/enterprise-detect.js +603 -0
  238. package/bin/runners/lib/enterprise-init.js +942 -0
  239. package/bin/runners/lib/entitlements-v2.js +265 -0
  240. package/bin/runners/lib/entitlements.generated.js +0 -0
  241. package/bin/runners/lib/entitlements.js +340 -0
  242. package/bin/runners/lib/env-resolver.js +417 -0
  243. package/bin/runners/lib/env-template.js +66 -0
  244. package/bin/runners/lib/env.js +189 -0
  245. package/bin/runners/lib/error-handler.js +368 -0
  246. package/bin/runners/lib/error-messages.js +289 -0
  247. package/bin/runners/lib/evidence-pack.js +684 -0
  248. package/bin/runners/lib/exit-codes.js +275 -0
  249. package/bin/runners/lib/extractors/client-calls.js +990 -0
  250. package/bin/runners/lib/extractors/fastify-route-dump.js +573 -0
  251. package/bin/runners/lib/extractors/fastify-routes.js +426 -0
  252. package/bin/runners/lib/extractors/index.js +363 -0
  253. package/bin/runners/lib/extractors/next-routes.js +524 -0
  254. package/bin/runners/lib/extractors/proof-graph.js +431 -0
  255. package/bin/runners/lib/extractors/route-matcher.js +451 -0
  256. package/bin/runners/lib/extractors/truthpack-v2.js +377 -0
  257. package/bin/runners/lib/extractors/ui-bindings.js +547 -0
  258. package/bin/runners/lib/finding-id.js +69 -0
  259. package/bin/runners/lib/finding-sorter.js +89 -0
  260. package/bin/runners/lib/findings-schema.js +281 -0
  261. package/bin/runners/lib/fingerprint.js +377 -0
  262. package/bin/runners/lib/firewall-prompt.js +50 -0
  263. package/bin/runners/lib/fix-output.js +228 -0
  264. package/bin/runners/lib/global-flags.js +250 -0
  265. package/bin/runners/lib/graph/graph-builder.js +265 -0
  266. package/bin/runners/lib/graph/html-renderer.js +413 -0
  267. package/bin/runners/lib/graph/index.js +32 -0
  268. package/bin/runners/lib/graph/runtime-collector.js +215 -0
  269. package/bin/runners/lib/graph/static-extractor.js +518 -0
  270. package/bin/runners/lib/help-formatter.js +413 -0
  271. package/bin/runners/lib/html-proof-report.js +913 -0
  272. package/bin/runners/lib/html-report.js +650 -0
  273. package/bin/runners/lib/init-wizard.js +601 -0
  274. package/bin/runners/lib/interactive-menu.js +1496 -0
  275. package/bin/runners/lib/json-output.js +76 -0
  276. package/bin/runners/lib/llm.js +75 -0
  277. package/bin/runners/lib/logger.js +38 -0
  278. package/bin/runners/lib/meter.js +61 -0
  279. package/bin/runners/lib/missions/briefing.js +427 -0
  280. package/bin/runners/lib/missions/checkpoint.js +753 -0
  281. package/bin/runners/lib/missions/evidence.js +126 -0
  282. package/bin/runners/lib/missions/hardening.js +851 -0
  283. package/bin/runners/lib/missions/plan.js +648 -0
  284. package/bin/runners/lib/missions/safety-gates.js +645 -0
  285. package/bin/runners/lib/missions/schema.js +478 -0
  286. package/bin/runners/lib/missions/templates.js +317 -0
  287. package/bin/runners/lib/next-action.js +560 -0
  288. package/bin/runners/lib/packs/bundle.js +675 -0
  289. package/bin/runners/lib/packs/evidence-pack.js +671 -0
  290. package/bin/runners/lib/packs/pack-factory.js +837 -0
  291. package/bin/runners/lib/packs/permissions-pack.js +686 -0
  292. package/bin/runners/lib/packs/proof-graph-pack.js +779 -0
  293. package/bin/runners/lib/patch.js +40 -0
  294. package/bin/runners/lib/permissions/auth-model.js +213 -0
  295. package/bin/runners/lib/permissions/idor-prover.js +205 -0
  296. package/bin/runners/lib/permissions/index.js +45 -0
  297. package/bin/runners/lib/permissions/matrix-builder.js +198 -0
  298. package/bin/runners/lib/pkgjson.js +28 -0
  299. package/bin/runners/lib/policy.js +295 -0
  300. package/bin/runners/lib/polish/accessibility.js +62 -0
  301. package/bin/runners/lib/polish/analyzer.js +93 -0
  302. package/bin/runners/lib/polish/backend.js +87 -0
  303. package/bin/runners/lib/polish/configuration.js +83 -0
  304. package/bin/runners/lib/polish/documentation.js +83 -0
  305. package/bin/runners/lib/polish/frontend.js +817 -0
  306. package/bin/runners/lib/polish/index.js +27 -0
  307. package/bin/runners/lib/polish/infrastructure.js +80 -0
  308. package/bin/runners/lib/polish/internationalization.js +85 -0
  309. package/bin/runners/lib/polish/libraries.js +180 -0
  310. package/bin/runners/lib/polish/observability.js +75 -0
  311. package/bin/runners/lib/polish/performance.js +64 -0
  312. package/bin/runners/lib/polish/privacy.js +110 -0
  313. package/bin/runners/lib/polish/resilience.js +92 -0
  314. package/bin/runners/lib/polish/security.js +78 -0
  315. package/bin/runners/lib/polish/seo.js +71 -0
  316. package/bin/runners/lib/polish/styles.js +62 -0
  317. package/bin/runners/lib/polish/utils.js +104 -0
  318. package/bin/runners/lib/preflight.js +142 -0
  319. package/bin/runners/lib/prerequisites.js +149 -0
  320. package/bin/runners/lib/prove-output.js +220 -0
  321. package/bin/runners/lib/reality/correlation-detectors.js +359 -0
  322. package/bin/runners/lib/reality/index.js +318 -0
  323. package/bin/runners/lib/reality/request-hashing.js +416 -0
  324. package/bin/runners/lib/reality/request-mapper.js +453 -0
  325. package/bin/runners/lib/reality/safety-rails.js +463 -0
  326. package/bin/runners/lib/reality/semantic-snapshot.js +408 -0
  327. package/bin/runners/lib/reality/toast-detector.js +393 -0
  328. package/bin/runners/lib/reality-findings.js +84 -0
  329. package/bin/runners/lib/reality-output.js +231 -0
  330. package/bin/runners/lib/receipts.js +179 -0
  331. package/bin/runners/lib/redact.js +29 -0
  332. package/bin/runners/lib/replay/capsule-manager.js +154 -0
  333. package/bin/runners/lib/replay/index.js +263 -0
  334. package/bin/runners/lib/replay/player.js +348 -0
  335. package/bin/runners/lib/replay/recorder.js +331 -0
  336. package/bin/runners/lib/report-engine.js +626 -0
  337. package/bin/runners/lib/report-html.js +1233 -0
  338. package/bin/runners/lib/report-output.js +366 -0
  339. package/bin/runners/lib/report-templates.js +967 -0
  340. package/bin/runners/lib/report.js +135 -0
  341. package/bin/runners/lib/route-detection.js +1209 -0
  342. package/bin/runners/lib/route-truth.js +1322 -0
  343. package/bin/runners/lib/safelist/index.js +96 -0
  344. package/bin/runners/lib/safelist/integration.js +334 -0
  345. package/bin/runners/lib/safelist/matcher.js +696 -0
  346. package/bin/runners/lib/safelist/schema.js +948 -0
  347. package/bin/runners/lib/safelist/store.js +438 -0
  348. package/bin/runners/lib/sandbox/index.js +59 -0
  349. package/bin/runners/lib/sandbox/proof-chain.js +399 -0
  350. package/bin/runners/lib/sandbox/sandbox-runner.js +205 -0
  351. package/bin/runners/lib/sandbox/worktree.js +174 -0
  352. package/bin/runners/lib/scan-cache.js +330 -0
  353. package/bin/runners/lib/scan-output-schema.js +344 -0
  354. package/bin/runners/lib/scan-output.js +631 -0
  355. package/bin/runners/lib/scan-runner.js +135 -0
  356. package/bin/runners/lib/schema-validator.js +350 -0
  357. package/bin/runners/lib/schemas/ajv-validator.js +464 -0
  358. package/bin/runners/lib/schemas/contracts.schema.json +160 -0
  359. package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
  360. package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
  361. package/bin/runners/lib/schemas/finding.schema.json +100 -0
  362. package/bin/runners/lib/schemas/mission-pack.schema.json +206 -0
  363. package/bin/runners/lib/schemas/proof-graph.schema.json +176 -0
  364. package/bin/runners/lib/schemas/reality-report.schema.json +162 -0
  365. package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
  366. package/bin/runners/lib/schemas/run-request.schema.json +108 -0
  367. package/bin/runners/lib/schemas/share-pack.schema.json +180 -0
  368. package/bin/runners/lib/schemas/ship-manifest.schema.json +251 -0
  369. package/bin/runners/lib/schemas/ship-report.schema.json +117 -0
  370. package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -0
  371. package/bin/runners/lib/schemas/validator.js +465 -0
  372. package/bin/runners/lib/schemas/verdict.schema.json +140 -0
  373. package/bin/runners/lib/score-history.js +282 -0
  374. package/bin/runners/lib/security-bridge.js +249 -0
  375. package/bin/runners/lib/server-usage.js +513 -0
  376. package/bin/runners/lib/share-pack.js +239 -0
  377. package/bin/runners/lib/ship-gate.js +832 -0
  378. package/bin/runners/lib/ship-manifest.js +1153 -0
  379. package/bin/runners/lib/ship-output-enterprise.js +239 -0
  380. package/bin/runners/lib/ship-output.js +1128 -0
  381. package/bin/runners/lib/snippets.js +67 -0
  382. package/bin/runners/lib/status-output.js +340 -0
  383. package/bin/runners/lib/terminal-ui.js +356 -0
  384. package/bin/runners/lib/truth.js +1691 -0
  385. package/bin/runners/lib/ui.js +562 -0
  386. package/bin/runners/lib/unified-cli-output.js +947 -0
  387. package/bin/runners/lib/unified-output.js +197 -0
  388. package/bin/runners/lib/upsell.js +410 -0
  389. package/bin/runners/lib/usage.js +153 -0
  390. package/bin/runners/lib/validate-patch.js +156 -0
  391. package/bin/runners/lib/verdict-engine.js +628 -0
  392. package/bin/runners/lib/verification.js +345 -0
  393. package/bin/runners/lib/why-tree.js +650 -0
  394. package/bin/runners/reality/engine.js +917 -0
  395. package/bin/runners/reality/flows.js +122 -0
  396. package/bin/runners/reality/report.js +378 -0
  397. package/bin/runners/reality/session.js +193 -0
  398. package/bin/runners/runAIAgent.js +229 -0
  399. package/bin/runners/runAgent.d.ts +5 -0
  400. package/bin/runners/runAgent.js +161 -0
  401. package/bin/runners/runAllowlist.js +418 -0
  402. package/bin/runners/runApprove.js +320 -0
  403. package/bin/runners/runAudit.js +692 -0
  404. package/bin/runners/runAuth.js +731 -0
  405. package/bin/runners/runCI.js +353 -0
  406. package/bin/runners/runCheckpoint.js +530 -0
  407. package/bin/runners/runClassify.js +928 -0
  408. package/bin/runners/runCleanup.js +343 -0
  409. package/bin/runners/runContext.d.ts +4 -0
  410. package/bin/runners/runContext.js +175 -0
  411. package/bin/runners/runDoctor.js +877 -0
  412. package/bin/runners/runEvidencePack.js +362 -0
  413. package/bin/runners/runFirewall.d.ts +5 -0
  414. package/bin/runners/runFirewall.js +134 -0
  415. package/bin/runners/runFirewallHook.d.ts +5 -0
  416. package/bin/runners/runFirewallHook.js +56 -0
  417. package/bin/runners/runFix.js +1355 -0
  418. package/bin/runners/runForge.js +451 -0
  419. package/bin/runners/runGuard.js +262 -0
  420. package/bin/runners/runInit.js +1927 -0
  421. package/bin/runners/runIntent.js +906 -0
  422. package/bin/runners/runKickoff.js +878 -0
  423. package/bin/runners/runLabs.js +424 -0
  424. package/bin/runners/runLaunch.js +2000 -0
  425. package/bin/runners/runLink.js +785 -0
  426. package/bin/runners/runMcp.js +1875 -0
  427. package/bin/runners/runPacks.js +2089 -0
  428. package/bin/runners/runPolish.d.ts +4 -0
  429. package/bin/runners/runPolish.js +390 -0
  430. package/bin/runners/runPromptFirewall.js +211 -0
  431. package/bin/runners/runProve.js +1411 -0
  432. package/bin/runners/runQuickstart.js +531 -0
  433. package/bin/runners/runReality.js +2260 -0
  434. package/bin/runners/runReport.js +726 -0
  435. package/bin/runners/runRuntime.js +110 -0
  436. package/bin/runners/runSafelist.js +1190 -0
  437. package/bin/runners/runScan.js +688 -0
  438. package/bin/runners/runShield.js +1282 -0
  439. package/bin/runners/runShip.js +1660 -0
  440. package/bin/runners/runTruth.d.ts +5 -0
  441. package/bin/runners/runTruth.js +101 -0
  442. package/bin/runners/runValidate.js +179 -0
  443. package/bin/runners/runWatch.js +478 -0
  444. package/bin/runners/utils.js +360 -0
  445. package/bin/scan.js +617 -0
  446. package/bin/vibecheck.js +1617 -0
  447. package/dist/guardrail/index.d.ts +2405 -0
  448. package/dist/guardrail/index.js +9747 -0
  449. package/dist/guardrail/index.js.map +1 -0
  450. package/dist/scanner/index.d.ts +282 -0
  451. package/dist/scanner/index.js +3395 -0
  452. package/dist/scanner/index.js.map +1 -0
  453. package/package.json +123 -104
  454. package/README.md +0 -491
  455. package/dist/index.js +0 -99711
  456. package/dist/index.js.map +0 -1
@@ -0,0 +1,851 @@
1
+ // bin/runners/lib/missions/hardening.js
2
+ // ═══════════════════════════════════════════════════════════════════════════════
3
+ // MISSION HARDENING - Bulletproof error handling, validation, and recovery
4
+ // ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+
9
+ // ═══════════════════════════════════════════════════════════════════════════════
10
+ // CUSTOM ERROR TYPES
11
+ // ═══════════════════════════════════════════════════════════════════════════════
12
+
13
+ /**
14
+ * Base error class for mission system
15
+ */
16
+ class MissionError extends Error {
17
+ constructor(message, code, context = {}) {
18
+ super(message);
19
+ this.name = 'MissionError';
20
+ this.code = code;
21
+ this.context = context;
22
+ this.timestamp = new Date().toISOString();
23
+ Error.captureStackTrace(this, this.constructor);
24
+ }
25
+
26
+ toJSON() {
27
+ return {
28
+ name: this.name,
29
+ code: this.code,
30
+ message: this.message,
31
+ context: this.context,
32
+ timestamp: this.timestamp,
33
+ stack: this.stack,
34
+ };
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Validation error - input doesn't meet requirements
40
+ */
41
+ class ValidationError extends MissionError {
42
+ constructor(message, field, value, context = {}) {
43
+ super(message, 'VALIDATION_ERROR', { field, value, ...context });
44
+ this.name = 'ValidationError';
45
+ this.field = field;
46
+ this.value = value;
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Checkpoint error - checkpoint operations failed
52
+ */
53
+ class CheckpointError extends MissionError {
54
+ constructor(message, operation, checkpointId, context = {}) {
55
+ super(message, 'CHECKPOINT_ERROR', { operation, checkpointId, ...context });
56
+ this.name = 'CheckpointError';
57
+ this.operation = operation;
58
+ this.checkpointId = checkpointId;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Safety gate error - gate check failed
64
+ */
65
+ class SafetyGateError extends MissionError {
66
+ constructor(message, gate, reason, context = {}) {
67
+ super(message, 'SAFETY_GATE_ERROR', { gate, reason, ...context });
68
+ this.name = 'SafetyGateError';
69
+ this.gate = gate;
70
+ this.reason = reason;
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Execution error - mission execution failed
76
+ */
77
+ class ExecutionError extends MissionError {
78
+ constructor(message, missionId, phase, context = {}) {
79
+ super(message, 'EXECUTION_ERROR', { missionId, phase, ...context });
80
+ this.name = 'ExecutionError';
81
+ this.missionId = missionId;
82
+ this.phase = phase;
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Rollback error - rollback operation failed
88
+ */
89
+ class RollbackError extends MissionError {
90
+ constructor(message, missionId, reason, context = {}) {
91
+ super(message, 'ROLLBACK_ERROR', { missionId, reason, ...context });
92
+ this.name = 'RollbackError';
93
+ this.missionId = missionId;
94
+ this.reason = reason;
95
+ }
96
+ }
97
+
98
+ // ═══════════════════════════════════════════════════════════════════════════════
99
+ // ERROR CODES
100
+ // ═══════════════════════════════════════════════════════════════════════════════
101
+
102
+ const ERROR_CODES = {
103
+ // Validation errors (1xxx)
104
+ INVALID_MISSION_ID: 1001,
105
+ INVALID_FINDING: 1002,
106
+ INVALID_FILE_PATH: 1003,
107
+ INVALID_CONFIDENCE: 1004,
108
+ INVALID_THRESHOLD: 1005,
109
+ MISSING_REQUIRED_FIELD: 1006,
110
+
111
+ // Checkpoint errors (2xxx)
112
+ CHECKPOINT_NOT_FOUND: 2001,
113
+ CHECKPOINT_CORRUPTED: 2002,
114
+ CHECKPOINT_CREATE_FAILED: 2003,
115
+ CHECKPOINT_RESTORE_FAILED: 2004,
116
+ SNAPSHOT_MISSING: 2005,
117
+
118
+ // Safety gate errors (3xxx)
119
+ PREFLIGHT_FAILED: 3001,
120
+ POSTFLIGHT_FAILED: 3002,
121
+ CONFIDENCE_TOO_LOW: 3003,
122
+ BLAST_RADIUS_EXCEEDED: 3004,
123
+ RISK_TOO_HIGH: 3005,
124
+ DIRTY_WORKING_TREE: 3006,
125
+
126
+ // Execution errors (4xxx)
127
+ MISSION_NOT_FOUND: 4001,
128
+ PATCH_FAILED: 4002,
129
+ VERIFICATION_FAILED: 4003,
130
+ TIMEOUT: 4004,
131
+ STAGNATION: 4005,
132
+
133
+ // System errors (5xxx)
134
+ FILE_NOT_FOUND: 5001,
135
+ FILE_READ_ERROR: 5002,
136
+ FILE_WRITE_ERROR: 5003,
137
+ GIT_ERROR: 5004,
138
+ UNKNOWN_ERROR: 5999,
139
+ };
140
+
141
+ // ═══════════════════════════════════════════════════════════════════════════════
142
+ // INPUT VALIDATION
143
+ // ═══════════════════════════════════════════════════════════════════════════════
144
+
145
+ /**
146
+ * Validate mission ID format
147
+ * @param {string} id - Mission ID
148
+ * @returns {boolean}
149
+ */
150
+ function isValidMissionId(id) {
151
+ if (!id || typeof id !== 'string') return false;
152
+ return /^M_[a-f0-9]{8,}$/i.test(id);
153
+ }
154
+
155
+ /**
156
+ * Validate checkpoint ID format
157
+ * @param {string} id - Checkpoint ID
158
+ * @returns {boolean}
159
+ */
160
+ function isValidCheckpointId(id) {
161
+ if (!id || typeof id !== 'string') return false;
162
+ return /^cp_M_[a-f0-9]+_[a-z0-9]+$/i.test(id);
163
+ }
164
+
165
+ /**
166
+ * Validate file path (no path traversal, valid characters)
167
+ * @param {string} filePath - File path to validate
168
+ * @returns {boolean}
169
+ */
170
+ function isValidFilePath(filePath) {
171
+ if (!filePath || typeof filePath !== 'string') return false;
172
+
173
+ // Check for path traversal
174
+ if (filePath.includes('..')) return false;
175
+
176
+ // Check for null bytes
177
+ if (filePath.includes('\0')) return false;
178
+
179
+ // Check for suspicious patterns
180
+ if (/[<>:"|?*]/.test(filePath)) return false;
181
+
182
+ return true;
183
+ }
184
+
185
+ /**
186
+ * Validate confidence value
187
+ * @param {number} confidence - Confidence value
188
+ * @returns {boolean}
189
+ */
190
+ function isValidConfidence(confidence) {
191
+ if (typeof confidence !== 'number') return false;
192
+ if (isNaN(confidence)) return false;
193
+ return confidence >= 0 && confidence <= 1;
194
+ }
195
+
196
+ /**
197
+ * Validate finding object
198
+ * @param {object} finding - Finding object
199
+ * @returns {{ valid: boolean, errors: string[] }}
200
+ */
201
+ function validateFinding(finding) {
202
+ const errors = [];
203
+
204
+ if (!finding || typeof finding !== 'object') {
205
+ return { valid: false, errors: ['Finding must be an object'] };
206
+ }
207
+
208
+ if (!finding.id) {
209
+ errors.push('Finding must have an id');
210
+ }
211
+
212
+ if (!finding.category) {
213
+ errors.push('Finding must have a category');
214
+ }
215
+
216
+ if (!finding.severity) {
217
+ errors.push('Finding must have a severity');
218
+ } else if (!['BLOCK', 'WARN', 'INFO', 'critical', 'high', 'medium', 'low', 'info'].includes(finding.severity)) {
219
+ errors.push(`Invalid severity: ${finding.severity}`);
220
+ }
221
+
222
+ if (finding.confidence !== undefined && !isValidConfidence(finding.confidence)) {
223
+ errors.push(`Invalid confidence: ${finding.confidence}`);
224
+ }
225
+
226
+ return { valid: errors.length === 0, errors };
227
+ }
228
+
229
+ /**
230
+ * Validate mission object
231
+ * @param {object} mission - Mission object
232
+ * @returns {{ valid: boolean, errors: string[] }}
233
+ */
234
+ function validateMission(mission) {
235
+ const errors = [];
236
+
237
+ if (!mission || typeof mission !== 'object') {
238
+ return { valid: false, errors: ['Mission must be an object'] };
239
+ }
240
+
241
+ // ID validation
242
+ if (!mission.id) {
243
+ errors.push('Mission must have an id');
244
+ } else if (!isValidMissionId(mission.id)) {
245
+ errors.push(`Invalid mission ID format: ${mission.id}`);
246
+ }
247
+
248
+ // Type validation
249
+ if (!mission.type) {
250
+ errors.push('Mission must have a type');
251
+ }
252
+
253
+ // Objective validation
254
+ if (!mission.objective) {
255
+ errors.push('Mission must have an objective');
256
+ } else {
257
+ if (!mission.objective.targetFindingIds || !Array.isArray(mission.objective.targetFindingIds)) {
258
+ errors.push('Mission objective must have targetFindingIds array');
259
+ } else if (mission.objective.targetFindingIds.length === 0) {
260
+ errors.push('Mission must target at least one finding');
261
+ }
262
+ }
263
+
264
+ // Scope validation
265
+ if (mission.scope) {
266
+ if (mission.scope.allowedFiles && !Array.isArray(mission.scope.allowedFiles)) {
267
+ errors.push('allowedFiles must be an array');
268
+ }
269
+
270
+ if (mission.scope.allowedFiles) {
271
+ for (const file of mission.scope.allowedFiles) {
272
+ if (!isValidFilePath(file)) {
273
+ errors.push(`Invalid file path: ${file}`);
274
+ }
275
+ }
276
+ }
277
+ }
278
+
279
+ // Safety validation
280
+ if (mission.safety) {
281
+ if (mission.safety.confidence !== undefined && !isValidConfidence(mission.safety.confidence)) {
282
+ errors.push(`Invalid safety confidence: ${mission.safety.confidence}`);
283
+ }
284
+ }
285
+
286
+ return { valid: errors.length === 0, errors };
287
+ }
288
+
289
+ /**
290
+ * Validate options object
291
+ * @param {object} options - Options object
292
+ * @param {object} schema - Schema defining expected options
293
+ * @returns {{ valid: boolean, errors: string[], sanitized: object }}
294
+ */
295
+ function validateOptions(options, schema) {
296
+ const errors = [];
297
+ const sanitized = {};
298
+
299
+ for (const [key, spec] of Object.entries(schema)) {
300
+ const value = options?.[key];
301
+
302
+ // Check required fields
303
+ if (spec.required && (value === undefined || value === null)) {
304
+ errors.push(`Required option missing: ${key}`);
305
+ continue;
306
+ }
307
+
308
+ // Apply default if not provided
309
+ if (value === undefined || value === null) {
310
+ sanitized[key] = spec.default;
311
+ continue;
312
+ }
313
+
314
+ // Type validation
315
+ if (spec.type && typeof value !== spec.type) {
316
+ errors.push(`Invalid type for ${key}: expected ${spec.type}, got ${typeof value}`);
317
+ sanitized[key] = spec.default;
318
+ continue;
319
+ }
320
+
321
+ // Range validation for numbers
322
+ if (spec.type === 'number') {
323
+ if (spec.min !== undefined && value < spec.min) {
324
+ errors.push(`${key} must be >= ${spec.min}`);
325
+ sanitized[key] = spec.min;
326
+ continue;
327
+ }
328
+ if (spec.max !== undefined && value > spec.max) {
329
+ errors.push(`${key} must be <= ${spec.max}`);
330
+ sanitized[key] = spec.max;
331
+ continue;
332
+ }
333
+ }
334
+
335
+ // Enum validation
336
+ if (spec.enum && !spec.enum.includes(value)) {
337
+ errors.push(`Invalid value for ${key}: must be one of ${spec.enum.join(', ')}`);
338
+ sanitized[key] = spec.default;
339
+ continue;
340
+ }
341
+
342
+ sanitized[key] = value;
343
+ }
344
+
345
+ return { valid: errors.length === 0, errors, sanitized };
346
+ }
347
+
348
+ // ═══════════════════════════════════════════════════════════════════════════════
349
+ // SAFE FILE OPERATIONS
350
+ // ═══════════════════════════════════════════════════════════════════════════════
351
+
352
+ /**
353
+ * Safely read a file with error handling
354
+ * @param {string} filePath - Absolute file path
355
+ * @returns {{ ok: boolean, content?: string, error?: string }}
356
+ */
357
+ function safeReadFile(filePath) {
358
+ try {
359
+ if (!fs.existsSync(filePath)) {
360
+ return { ok: false, error: `File not found: ${filePath}` };
361
+ }
362
+
363
+ const stats = fs.statSync(filePath);
364
+ if (stats.isDirectory()) {
365
+ return { ok: false, error: `Path is a directory: ${filePath}` };
366
+ }
367
+
368
+ // Limit file size (10MB max)
369
+ const MAX_SIZE = 10 * 1024 * 1024;
370
+ if (stats.size > MAX_SIZE) {
371
+ return { ok: false, error: `File too large: ${stats.size} bytes (max ${MAX_SIZE})` };
372
+ }
373
+
374
+ const content = fs.readFileSync(filePath, 'utf8');
375
+ return { ok: true, content };
376
+ } catch (e) {
377
+ return { ok: false, error: `Failed to read file: ${e.message}` };
378
+ }
379
+ }
380
+
381
+ /**
382
+ * Safely write a file with error handling
383
+ * @param {string} filePath - Absolute file path
384
+ * @param {string} content - Content to write
385
+ * @returns {{ ok: boolean, error?: string }}
386
+ */
387
+ function safeWriteFile(filePath, content) {
388
+ try {
389
+ // Ensure parent directory exists
390
+ const dir = path.dirname(filePath);
391
+ if (!fs.existsSync(dir)) {
392
+ fs.mkdirSync(dir, { recursive: true });
393
+ }
394
+
395
+ fs.writeFileSync(filePath, content, 'utf8');
396
+ return { ok: true };
397
+ } catch (e) {
398
+ return { ok: false, error: `Failed to write file: ${e.message}` };
399
+ }
400
+ }
401
+
402
+ /**
403
+ * Safely read JSON file
404
+ * @param {string} filePath - Absolute file path
405
+ * @returns {{ ok: boolean, data?: any, error?: string }}
406
+ */
407
+ function safeReadJson(filePath) {
408
+ const result = safeReadFile(filePath);
409
+ if (!result.ok) return result;
410
+
411
+ try {
412
+ const data = JSON.parse(result.content);
413
+ return { ok: true, data };
414
+ } catch (e) {
415
+ return { ok: false, error: `Invalid JSON: ${e.message}` };
416
+ }
417
+ }
418
+
419
+ /**
420
+ * Safely write JSON file
421
+ * @param {string} filePath - Absolute file path
422
+ * @param {any} data - Data to write
423
+ * @returns {{ ok: boolean, error?: string }}
424
+ */
425
+ function safeWriteJson(filePath, data) {
426
+ try {
427
+ const content = JSON.stringify(data, null, 2);
428
+ return safeWriteFile(filePath, content);
429
+ } catch (e) {
430
+ return { ok: false, error: `Failed to serialize JSON: ${e.message}` };
431
+ }
432
+ }
433
+
434
+ // ═══════════════════════════════════════════════════════════════════════════════
435
+ // CIRCUIT BREAKER
436
+ // ═══════════════════════════════════════════════════════════════════════════════
437
+
438
+ /**
439
+ * Circuit breaker state
440
+ */
441
+ const circuitBreakerState = {
442
+ failures: 0,
443
+ lastFailure: null,
444
+ state: 'CLOSED', // CLOSED, OPEN, HALF_OPEN
445
+ threshold: 5,
446
+ resetTimeout: 60000, // 1 minute
447
+ };
448
+
449
+ /**
450
+ * Check if circuit breaker allows operation
451
+ * @returns {boolean}
452
+ */
453
+ function circuitBreakerAllows() {
454
+ const now = Date.now();
455
+
456
+ if (circuitBreakerState.state === 'OPEN') {
457
+ // Check if reset timeout has passed
458
+ if (now - circuitBreakerState.lastFailure > circuitBreakerState.resetTimeout) {
459
+ circuitBreakerState.state = 'HALF_OPEN';
460
+ return true;
461
+ }
462
+ return false;
463
+ }
464
+
465
+ return true;
466
+ }
467
+
468
+ /**
469
+ * Record circuit breaker success
470
+ */
471
+ function circuitBreakerSuccess() {
472
+ if (circuitBreakerState.state === 'HALF_OPEN') {
473
+ circuitBreakerState.state = 'CLOSED';
474
+ circuitBreakerState.failures = 0;
475
+ }
476
+ }
477
+
478
+ /**
479
+ * Record circuit breaker failure
480
+ */
481
+ function circuitBreakerFailure() {
482
+ circuitBreakerState.failures++;
483
+ circuitBreakerState.lastFailure = Date.now();
484
+
485
+ if (circuitBreakerState.failures >= circuitBreakerState.threshold) {
486
+ circuitBreakerState.state = 'OPEN';
487
+ }
488
+ }
489
+
490
+ /**
491
+ * Reset circuit breaker
492
+ */
493
+ function circuitBreakerReset() {
494
+ circuitBreakerState.failures = 0;
495
+ circuitBreakerState.lastFailure = null;
496
+ circuitBreakerState.state = 'CLOSED';
497
+ }
498
+
499
+ /**
500
+ * Get circuit breaker status
501
+ * @returns {object}
502
+ */
503
+ function circuitBreakerStatus() {
504
+ return { ...circuitBreakerState };
505
+ }
506
+
507
+ // ═══════════════════════════════════════════════════════════════════════════════
508
+ // RETRY LOGIC
509
+ // ═══════════════════════════════════════════════════════════════════════════════
510
+
511
+ /**
512
+ * Retry configuration
513
+ * @typedef {object} RetryConfig
514
+ * @property {number} maxAttempts - Maximum retry attempts
515
+ * @property {number} baseDelay - Base delay in ms
516
+ * @property {number} maxDelay - Maximum delay in ms
517
+ * @property {boolean} exponential - Use exponential backoff
518
+ */
519
+
520
+ const DEFAULT_RETRY_CONFIG = {
521
+ maxAttempts: 3,
522
+ baseDelay: 1000,
523
+ maxDelay: 10000,
524
+ exponential: true,
525
+ };
526
+
527
+ /**
528
+ * Execute function with retry logic
529
+ * @param {Function} fn - Async function to execute
530
+ * @param {RetryConfig} config - Retry configuration
531
+ * @returns {Promise<any>}
532
+ */
533
+ async function withRetry(fn, config = {}) {
534
+ const opts = { ...DEFAULT_RETRY_CONFIG, ...config };
535
+ let lastError;
536
+
537
+ for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {
538
+ try {
539
+ return await fn(attempt);
540
+ } catch (error) {
541
+ lastError = error;
542
+
543
+ // Don't retry on validation errors
544
+ if (error instanceof ValidationError) {
545
+ throw error;
546
+ }
547
+
548
+ if (attempt < opts.maxAttempts) {
549
+ const delay = opts.exponential
550
+ ? Math.min(opts.baseDelay * Math.pow(2, attempt - 1), opts.maxDelay)
551
+ : opts.baseDelay;
552
+
553
+ await new Promise(resolve => setTimeout(resolve, delay));
554
+ }
555
+ }
556
+ }
557
+
558
+ throw lastError;
559
+ }
560
+
561
+ // ═══════════════════════════════════════════════════════════════════════════════
562
+ // AUDIT TRAIL
563
+ // ═══════════════════════════════════════════════════════════════════════════════
564
+
565
+ /**
566
+ * Audit log levels
567
+ */
568
+ const AUDIT_LEVEL = {
569
+ DEBUG: 'DEBUG',
570
+ INFO: 'INFO',
571
+ WARN: 'WARN',
572
+ ERROR: 'ERROR',
573
+ CRITICAL: 'CRITICAL',
574
+ };
575
+
576
+ /**
577
+ * Audit log entry
578
+ */
579
+ class AuditEntry {
580
+ constructor(level, operation, details = {}) {
581
+ this.timestamp = new Date().toISOString();
582
+ this.level = level;
583
+ this.operation = operation;
584
+ this.details = details;
585
+ this.sessionId = process.env.VIBECHECK_SESSION_ID || 'unknown';
586
+ }
587
+
588
+ toJSON() {
589
+ return {
590
+ timestamp: this.timestamp,
591
+ level: this.level,
592
+ operation: this.operation,
593
+ details: this.details,
594
+ sessionId: this.sessionId,
595
+ };
596
+ }
597
+
598
+ toString() {
599
+ return `[${this.timestamp}] [${this.level}] ${this.operation}: ${JSON.stringify(this.details)}`;
600
+ }
601
+ }
602
+
603
+ /**
604
+ * Audit trail manager
605
+ */
606
+ class AuditTrail {
607
+ constructor(logDir) {
608
+ this.logDir = logDir;
609
+ this.entries = [];
610
+ this.maxEntries = 1000;
611
+ }
612
+
613
+ log(level, operation, details = {}) {
614
+ const entry = new AuditEntry(level, operation, details);
615
+ this.entries.push(entry);
616
+
617
+ // Trim if too many entries
618
+ if (this.entries.length > this.maxEntries) {
619
+ this.entries = this.entries.slice(-this.maxEntries);
620
+ }
621
+
622
+ // Also write to file if log dir is set
623
+ if (this.logDir) {
624
+ this._writeToFile(entry);
625
+ }
626
+
627
+ return entry;
628
+ }
629
+
630
+ debug(operation, details) {
631
+ return this.log(AUDIT_LEVEL.DEBUG, operation, details);
632
+ }
633
+
634
+ info(operation, details) {
635
+ return this.log(AUDIT_LEVEL.INFO, operation, details);
636
+ }
637
+
638
+ warn(operation, details) {
639
+ return this.log(AUDIT_LEVEL.WARN, operation, details);
640
+ }
641
+
642
+ error(operation, details) {
643
+ return this.log(AUDIT_LEVEL.ERROR, operation, details);
644
+ }
645
+
646
+ critical(operation, details) {
647
+ return this.log(AUDIT_LEVEL.CRITICAL, operation, details);
648
+ }
649
+
650
+ getEntries(filter = {}) {
651
+ let result = [...this.entries];
652
+
653
+ if (filter.level) {
654
+ result = result.filter(e => e.level === filter.level);
655
+ }
656
+
657
+ if (filter.operation) {
658
+ result = result.filter(e => e.operation.includes(filter.operation));
659
+ }
660
+
661
+ if (filter.since) {
662
+ const since = new Date(filter.since);
663
+ result = result.filter(e => new Date(e.timestamp) >= since);
664
+ }
665
+
666
+ return result;
667
+ }
668
+
669
+ _writeToFile(entry) {
670
+ try {
671
+ if (!fs.existsSync(this.logDir)) {
672
+ fs.mkdirSync(this.logDir, { recursive: true });
673
+ }
674
+
675
+ const date = new Date().toISOString().split('T')[0];
676
+ const logFile = path.join(this.logDir, `mission-audit-${date}.log`);
677
+
678
+ fs.appendFileSync(logFile, entry.toString() + '\n', 'utf8');
679
+ } catch (e) {
680
+ // Silently fail - don't break operations due to logging failures
681
+ }
682
+ }
683
+
684
+ flush() {
685
+ if (!this.logDir) return;
686
+
687
+ try {
688
+ const logFile = path.join(this.logDir, 'mission-audit-summary.json');
689
+ fs.writeFileSync(logFile, JSON.stringify(this.entries, null, 2), 'utf8');
690
+ } catch (e) {
691
+ // Silently fail
692
+ }
693
+ }
694
+ }
695
+
696
+ // Global audit trail instance
697
+ let globalAuditTrail = null;
698
+
699
+ /**
700
+ * Initialize global audit trail
701
+ * @param {string} logDir - Log directory
702
+ * @returns {AuditTrail}
703
+ */
704
+ function initAuditTrail(logDir) {
705
+ globalAuditTrail = new AuditTrail(logDir);
706
+ return globalAuditTrail;
707
+ }
708
+
709
+ /**
710
+ * Get global audit trail
711
+ * @returns {AuditTrail}
712
+ */
713
+ function getAuditTrail() {
714
+ if (!globalAuditTrail) {
715
+ globalAuditTrail = new AuditTrail(null);
716
+ }
717
+ return globalAuditTrail;
718
+ }
719
+
720
+ // ═══════════════════════════════════════════════════════════════════════════════
721
+ // TIMEOUT WRAPPER
722
+ // ═══════════════════════════════════════════════════════════════════════════════
723
+
724
+ /**
725
+ * Execute function with timeout
726
+ * @param {Function} fn - Async function to execute
727
+ * @param {number} timeoutMs - Timeout in milliseconds
728
+ * @param {string} operation - Operation name for error message
729
+ * @returns {Promise<any>}
730
+ */
731
+ async function withTimeout(fn, timeoutMs, operation = 'Operation') {
732
+ return Promise.race([
733
+ fn(),
734
+ new Promise((_, reject) => {
735
+ setTimeout(() => {
736
+ reject(new ExecutionError(`${operation} timed out after ${timeoutMs}ms`, null, 'timeout', { timeoutMs }));
737
+ }, timeoutMs);
738
+ }),
739
+ ]);
740
+ }
741
+
742
+ // ═══════════════════════════════════════════════════════════════════════════════
743
+ // SAFE EXECUTION WRAPPER
744
+ // ═══════════════════════════════════════════════════════════════════════════════
745
+
746
+ /**
747
+ * Safely execute a function with all hardening features
748
+ * @param {Function} fn - Async function to execute
749
+ * @param {object} options - Execution options
750
+ * @returns {Promise<{ ok: boolean, result?: any, error?: Error }>}
751
+ */
752
+ async function safeExecute(fn, options = {}) {
753
+ const {
754
+ timeout = 30000,
755
+ retry = false,
756
+ retryConfig = {},
757
+ operation = 'Unknown operation',
758
+ auditTrail = true,
759
+ } = options;
760
+
761
+ const audit = getAuditTrail();
762
+
763
+ // Check circuit breaker
764
+ if (!circuitBreakerAllows()) {
765
+ const error = new ExecutionError('Circuit breaker is open - too many recent failures', null, 'circuit_breaker');
766
+ if (auditTrail) audit.error('circuit_breaker_blocked', { operation });
767
+ return { ok: false, error };
768
+ }
769
+
770
+ try {
771
+ if (auditTrail) audit.debug('operation_start', { operation });
772
+
773
+ let result;
774
+
775
+ const wrappedFn = async () => {
776
+ return retry ? await withRetry(fn, retryConfig) : await fn();
777
+ };
778
+
779
+ result = await withTimeout(wrappedFn, timeout, operation);
780
+
781
+ circuitBreakerSuccess();
782
+ if (auditTrail) audit.info('operation_success', { operation });
783
+
784
+ return { ok: true, result };
785
+ } catch (error) {
786
+ circuitBreakerFailure();
787
+
788
+ if (auditTrail) {
789
+ audit.error('operation_failed', {
790
+ operation,
791
+ error: error.message,
792
+ code: error.code,
793
+ stack: error.stack,
794
+ });
795
+ }
796
+
797
+ return { ok: false, error };
798
+ }
799
+ }
800
+
801
+ // ═══════════════════════════════════════════════════════════════════════════════
802
+ // EXPORTS
803
+ // ═══════════════════════════════════════════════════════════════════════════════
804
+
805
+ module.exports = {
806
+ // Error types
807
+ MissionError,
808
+ ValidationError,
809
+ CheckpointError,
810
+ SafetyGateError,
811
+ ExecutionError,
812
+ RollbackError,
813
+ ERROR_CODES,
814
+
815
+ // Validation
816
+ isValidMissionId,
817
+ isValidCheckpointId,
818
+ isValidFilePath,
819
+ isValidConfidence,
820
+ validateFinding,
821
+ validateMission,
822
+ validateOptions,
823
+
824
+ // Safe file operations
825
+ safeReadFile,
826
+ safeWriteFile,
827
+ safeReadJson,
828
+ safeWriteJson,
829
+
830
+ // Circuit breaker
831
+ circuitBreakerAllows,
832
+ circuitBreakerSuccess,
833
+ circuitBreakerFailure,
834
+ circuitBreakerReset,
835
+ circuitBreakerStatus,
836
+
837
+ // Retry logic
838
+ withRetry,
839
+ DEFAULT_RETRY_CONFIG,
840
+
841
+ // Audit trail
842
+ AUDIT_LEVEL,
843
+ AuditEntry,
844
+ AuditTrail,
845
+ initAuditTrail,
846
+ getAuditTrail,
847
+
848
+ // Execution helpers
849
+ withTimeout,
850
+ safeExecute,
851
+ };