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,645 @@
1
+ // bin/runners/lib/missions/safety-gates.js
2
+ // ═══════════════════════════════════════════════════════════════════════════════
3
+ // SAFETY GATES - Pre-flight and post-flight checks for mission safety
4
+ // Gates must pass before missions run, and verify success after
5
+ // ═══════════════════════════════════════════════════════════════════════════════
6
+
7
+ const { execSync } = require('child_process');
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const { RISK_LEVEL, BLAST_RADIUS } = require('./schema');
11
+ const {
12
+ SafetyGateError,
13
+ ValidationError,
14
+ isValidConfidence,
15
+ validateOptions,
16
+ getAuditTrail,
17
+ } = require('./hardening');
18
+
19
+ /**
20
+ * Gate result structure
21
+ * @typedef {object} GateResult
22
+ * @property {string} gate - Gate name
23
+ * @property {boolean} pass - Whether gate passed
24
+ * @property {string} reason - Human-readable reason
25
+ * @property {string} [remedy] - Suggested fix if gate failed
26
+ * @property {string} [severity] - Gate severity (error, warning, info)
27
+ */
28
+
29
+ /**
30
+ * Default thresholds for safety gates
31
+ */
32
+ const DEFAULT_THRESHOLDS = {
33
+ minConfidence: 0.6,
34
+ maxBlastRadius: 10,
35
+ maxFilesPerMission: 6,
36
+ maxLinesChanged: 400,
37
+ };
38
+
39
+ // ═══════════════════════════════════════════════════════════════════════════════
40
+ // PRE-FLIGHT GATES - Must pass before mission execution
41
+ // ═══════════════════════════════════════════════════════════════════════════════
42
+
43
+ /**
44
+ * Check if mission confidence meets threshold
45
+ * @param {object} mission - Mission object
46
+ * @param {object} options - Gate options
47
+ * @returns {GateResult}
48
+ */
49
+ function gateConfidence(mission, options = {}) {
50
+ const threshold = options.minConfidence ?? DEFAULT_THRESHOLDS.minConfidence;
51
+ const confidence = mission.safety?.confidence ?? 0.5;
52
+
53
+ const pass = confidence >= threshold;
54
+
55
+ return {
56
+ gate: 'confidence',
57
+ pass,
58
+ reason: pass
59
+ ? `Confidence ${(confidence * 100).toFixed(0)}% >= ${(threshold * 100).toFixed(0)}% threshold`
60
+ : `Confidence ${(confidence * 100).toFixed(0)}% < ${(threshold * 100).toFixed(0)}% threshold`,
61
+ remedy: pass ? null : 'Use --force to override or --min-confidence to adjust threshold',
62
+ severity: pass ? 'info' : 'error',
63
+ value: confidence,
64
+ threshold,
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Check if blast radius is acceptable
70
+ * @param {object} mission - Mission object
71
+ * @param {object} options - Gate options
72
+ * @returns {GateResult}
73
+ */
74
+ function gateBlastRadius(mission, options = {}) {
75
+ const maxFiles = options.maxBlastRadius ?? DEFAULT_THRESHOLDS.maxBlastRadius;
76
+ const files = mission.scope?.allowedFiles?.length ?? 0;
77
+ const blastRadius = mission.scope?.blastRadius ?? BLAST_RADIUS.MEDIUM;
78
+
79
+ const pass = files <= maxFiles;
80
+
81
+ return {
82
+ gate: 'blast_radius',
83
+ pass,
84
+ reason: pass
85
+ ? `Blast radius: ${files} files (${blastRadius}) <= ${maxFiles} max`
86
+ : `Blast radius: ${files} files (${blastRadius}) > ${maxFiles} max`,
87
+ remedy: pass ? null : 'Use --max-blast to increase limit or --force to override',
88
+ severity: pass ? 'info' : 'error',
89
+ value: files,
90
+ threshold: maxFiles,
91
+ };
92
+ }
93
+
94
+ /**
95
+ * Check if risk level is acceptable for auto-apply
96
+ * @param {object} mission - Mission object
97
+ * @param {object} options - Gate options
98
+ * @returns {GateResult}
99
+ */
100
+ function gateRiskLevel(mission, options = {}) {
101
+ const riskLevel = mission.safety?.riskLevel ?? RISK_LEVEL.MEDIUM;
102
+ const requiresApproval = mission.safety?.requiresApproval ?? false;
103
+ const forceMode = options.force ?? false;
104
+
105
+ // Critical missions require --force unless explicitly approved
106
+ const isCritical = riskLevel === RISK_LEVEL.CRITICAL;
107
+ const pass = !isCritical || forceMode || !requiresApproval;
108
+
109
+ return {
110
+ gate: 'risk_level',
111
+ pass,
112
+ reason: pass
113
+ ? `Risk level: ${riskLevel.toUpperCase()} ${isCritical ? '(approved with --force)' : ''}`
114
+ : `Risk level: ${riskLevel.toUpperCase()} requires explicit approval`,
115
+ remedy: pass ? null : 'Use --force to approve critical mission execution',
116
+ severity: pass ? (isCritical ? 'warning' : 'info') : 'error',
117
+ value: riskLevel,
118
+ };
119
+ }
120
+
121
+ /**
122
+ * Check for uncommitted changes in git
123
+ * @param {string} repoRoot - Repository root
124
+ * @param {object} options - Gate options
125
+ * @returns {GateResult}
126
+ */
127
+ function gateOpenChanges(repoRoot, options = {}) {
128
+ const allowDirty = options.allowDirty ?? false;
129
+
130
+ let isDirty = false;
131
+ let changes = 0;
132
+
133
+ try {
134
+ const status = execSync('git status --porcelain', {
135
+ cwd: repoRoot,
136
+ encoding: 'utf8',
137
+ stdio: ['pipe', 'pipe', 'pipe'],
138
+ }).trim();
139
+
140
+ isDirty = status.length > 0;
141
+ changes = status.split('\n').filter(Boolean).length;
142
+ } catch (e) {
143
+ // Not a git repo or git not available
144
+ return {
145
+ gate: 'open_changes',
146
+ pass: true,
147
+ reason: 'Not a git repository',
148
+ severity: 'info',
149
+ };
150
+ }
151
+
152
+ const pass = !isDirty || allowDirty;
153
+
154
+ return {
155
+ gate: 'open_changes',
156
+ pass,
157
+ reason: pass
158
+ ? isDirty
159
+ ? `${changes} uncommitted changes (allowed)`
160
+ : 'Working directory clean'
161
+ : `${changes} uncommitted changes - commit or stash before fixing`,
162
+ remedy: pass ? null : 'Commit or stash changes before running fix, or use --allow-dirty',
163
+ severity: pass ? 'info' : 'error',
164
+ value: changes,
165
+ };
166
+ }
167
+
168
+ /**
169
+ * Check if target files exist and are readable
170
+ * @param {string} repoRoot - Repository root
171
+ * @param {object} mission - Mission object
172
+ * @returns {GateResult}
173
+ */
174
+ function gateFilesExist(repoRoot, mission) {
175
+ const allowedFiles = mission.scope?.allowedFiles ?? [];
176
+ const missing = [];
177
+
178
+ for (const file of allowedFiles) {
179
+ const absPath = path.join(repoRoot, file);
180
+ if (!fs.existsSync(absPath)) {
181
+ missing.push(file);
182
+ }
183
+ }
184
+
185
+ const pass = missing.length === 0;
186
+
187
+ return {
188
+ gate: 'files_exist',
189
+ pass,
190
+ reason: pass
191
+ ? `All ${allowedFiles.length} target files exist`
192
+ : `${missing.length} target files missing: ${missing.slice(0, 3).join(', ')}${missing.length > 3 ? '...' : ''}`,
193
+ remedy: pass ? null : 'Ensure target files exist or re-run scan to update findings',
194
+ severity: pass ? 'info' : 'warning',
195
+ value: allowedFiles.length - missing.length,
196
+ missing,
197
+ };
198
+ }
199
+
200
+ /**
201
+ * Run all pre-flight gates
202
+ * @param {string} repoRoot - Repository root
203
+ * @param {object} mission - Mission object
204
+ * @param {object} options - Gate options
205
+ * @returns {object} Combined gate results
206
+ */
207
+ function runPreFlightGates(repoRoot, mission, options = {}) {
208
+ const audit = getAuditTrail();
209
+ const missionId = mission?.id || 'unknown';
210
+
211
+ audit.debug('preflight_gates_start', { missionId, options });
212
+
213
+ // Validate inputs
214
+ if (!mission || typeof mission !== 'object') {
215
+ audit.error('preflight_gates_invalid_mission', { mission });
216
+ return {
217
+ ok: false,
218
+ results: [{
219
+ gate: 'validation',
220
+ pass: false,
221
+ reason: 'Mission object is required',
222
+ severity: 'error',
223
+ }],
224
+ passed: 0,
225
+ failed: 1,
226
+ warnings: 0,
227
+ summary: 'Mission validation failed',
228
+ };
229
+ }
230
+
231
+ // Sanitize options with defaults
232
+ const safeOptions = {
233
+ minConfidence: options.minConfidence ?? DEFAULT_THRESHOLDS.minConfidence,
234
+ maxBlastRadius: options.maxBlastRadius ?? DEFAULT_THRESHOLDS.maxBlastRadius,
235
+ force: options.force ?? false,
236
+ allowDirty: options.allowDirty ?? false,
237
+ };
238
+
239
+ // Run all gates
240
+ const results = [];
241
+
242
+ try {
243
+ results.push(gateConfidence(mission, safeOptions));
244
+ } catch (e) {
245
+ results.push({ gate: 'confidence', pass: false, reason: `Gate error: ${e.message}`, severity: 'error' });
246
+ }
247
+
248
+ try {
249
+ results.push(gateBlastRadius(mission, safeOptions));
250
+ } catch (e) {
251
+ results.push({ gate: 'blast_radius', pass: false, reason: `Gate error: ${e.message}`, severity: 'error' });
252
+ }
253
+
254
+ try {
255
+ results.push(gateRiskLevel(mission, safeOptions));
256
+ } catch (e) {
257
+ results.push({ gate: 'risk_level', pass: false, reason: `Gate error: ${e.message}`, severity: 'error' });
258
+ }
259
+
260
+ try {
261
+ results.push(gateOpenChanges(repoRoot, safeOptions));
262
+ } catch (e) {
263
+ results.push({ gate: 'open_changes', pass: false, reason: `Gate error: ${e.message}`, severity: 'error' });
264
+ }
265
+
266
+ try {
267
+ results.push(gateFilesExist(repoRoot, mission));
268
+ } catch (e) {
269
+ results.push({ gate: 'files_exist', pass: false, reason: `Gate error: ${e.message}`, severity: 'error' });
270
+ }
271
+
272
+ const passed = results.filter(r => r.pass);
273
+ const failed = results.filter(r => !r.pass);
274
+ const warnings = results.filter(r => r.severity === 'warning');
275
+
276
+ const gateResults = {
277
+ ok: failed.length === 0,
278
+ results,
279
+ passed: passed.length,
280
+ failed: failed.length,
281
+ warnings: warnings.length,
282
+ summary: failed.length === 0
283
+ ? `All ${results.length} pre-flight gates passed`
284
+ : `${failed.length} gate(s) failed: ${failed.map(f => f.gate).join(', ')}`,
285
+ };
286
+
287
+ audit.info('preflight_gates_complete', {
288
+ missionId,
289
+ ok: gateResults.ok,
290
+ passed: passed.length,
291
+ failed: failed.length,
292
+ failedGates: failed.map(f => f.gate),
293
+ });
294
+
295
+ return gateResults;
296
+ }
297
+
298
+ // ═══════════════════════════════════════════════════════════════════════════════
299
+ // POST-FLIGHT GATES - Verify success after mission execution
300
+ // ═══════════════════════════════════════════════════════════════════════════════
301
+
302
+ /**
303
+ * Check if findings were reduced
304
+ * @param {object} before - Ship results before fix
305
+ * @param {object} after - Ship results after fix
306
+ * @param {object} mission - Mission object
307
+ * @returns {GateResult}
308
+ */
309
+ function gateFindingsReduced(before, after, mission) {
310
+ const beforeFindings = before?.report?.findings ?? before?.findings ?? [];
311
+ const afterFindings = after?.report?.findings ?? after?.findings ?? [];
312
+
313
+ const targetIds = new Set(mission.objective?.targetFindingIds ?? []);
314
+
315
+ // Count target findings before and after
316
+ const targetsBefore = beforeFindings.filter(f => targetIds.has(f.id)).length;
317
+ const targetsAfter = afterFindings.filter(f => targetIds.has(f.id)).length;
318
+
319
+ const reduced = targetsAfter < targetsBefore;
320
+ const eliminated = targetsAfter === 0;
321
+
322
+ return {
323
+ gate: 'findings_reduced',
324
+ pass: reduced,
325
+ reason: reduced
326
+ ? eliminated
327
+ ? `All ${targetsBefore} target findings eliminated`
328
+ : `Target findings reduced: ${targetsBefore} → ${targetsAfter}`
329
+ : `Target findings not reduced: ${targetsBefore} → ${targetsAfter}`,
330
+ remedy: reduced ? null : 'Fix did not address target findings - rollback recommended',
331
+ severity: reduced ? 'info' : 'error',
332
+ value: { before: targetsBefore, after: targetsAfter },
333
+ };
334
+ }
335
+
336
+ /**
337
+ * Check for regressions (new findings introduced)
338
+ * @param {object} before - Ship results before fix
339
+ * @param {object} after - Ship results after fix
340
+ * @returns {GateResult}
341
+ */
342
+ function gateNoRegressions(before, after) {
343
+ const beforeFindings = before?.report?.findings ?? before?.findings ?? [];
344
+ const afterFindings = after?.report?.findings ?? after?.findings ?? [];
345
+
346
+ const beforeIds = new Set(beforeFindings.map(f => f.id));
347
+ const newFindings = afterFindings.filter(f => !beforeIds.has(f.id));
348
+
349
+ // Only count new BLOCK findings as regressions
350
+ const newBlocks = newFindings.filter(f => f.severity === 'BLOCK');
351
+
352
+ const pass = newBlocks.length === 0;
353
+
354
+ return {
355
+ gate: 'no_regressions',
356
+ pass,
357
+ reason: pass
358
+ ? newFindings.length === 0
359
+ ? 'No new findings introduced'
360
+ : `${newFindings.length} new non-blocking findings (acceptable)`
361
+ : `${newBlocks.length} new BLOCK findings introduced`,
362
+ remedy: pass ? null : 'Fix introduced new blocking issues - rollback recommended',
363
+ severity: pass ? 'info' : 'error',
364
+ value: { newTotal: newFindings.length, newBlocks: newBlocks.length },
365
+ newFindings: newBlocks,
366
+ };
367
+ }
368
+
369
+ /**
370
+ * Check if overall score decreased
371
+ * @param {object} before - Ship results before fix
372
+ * @param {object} after - Ship results after fix
373
+ * @returns {GateResult}
374
+ */
375
+ function gateScoreDecrease(before, after) {
376
+ const beforeFindings = before?.report?.findings ?? before?.findings ?? [];
377
+ const afterFindings = after?.report?.findings ?? after?.findings ?? [];
378
+
379
+ // Calculate scores
380
+ const score = (findings) => {
381
+ let s = 0;
382
+ for (const f of findings) {
383
+ if (f.severity === 'BLOCK') s += 10;
384
+ else if (f.severity === 'WARN') s += 3;
385
+ else s += 1;
386
+ }
387
+ return s;
388
+ };
389
+
390
+ const beforeScore = score(beforeFindings);
391
+ const afterScore = score(afterFindings);
392
+
393
+ const decreased = afterScore < beforeScore;
394
+ const delta = beforeScore - afterScore;
395
+
396
+ return {
397
+ gate: 'score_decrease',
398
+ pass: decreased,
399
+ reason: decreased
400
+ ? `Score decreased: ${beforeScore} → ${afterScore} (${delta > 0 ? '-' : '+'}${Math.abs(delta)})`
401
+ : `Score not decreased: ${beforeScore} → ${afterScore}`,
402
+ remedy: decreased ? null : 'Fix did not improve overall score',
403
+ severity: decreased ? 'info' : 'warning',
404
+ value: { before: beforeScore, after: afterScore, delta },
405
+ };
406
+ }
407
+
408
+ /**
409
+ * Check if tests pass (optional - requires test runner config)
410
+ * @param {string} repoRoot - Repository root
411
+ * @param {object} options - Test options
412
+ * @returns {GateResult}
413
+ */
414
+ function gateTestsPass(repoRoot, options = {}) {
415
+ const testCommand = options.testCommand ?? null;
416
+ const skipTests = options.skipTests ?? true;
417
+
418
+ if (skipTests || !testCommand) {
419
+ return {
420
+ gate: 'tests_pass',
421
+ pass: true,
422
+ reason: 'Tests skipped (not configured)',
423
+ severity: 'info',
424
+ skipped: true,
425
+ };
426
+ }
427
+
428
+ try {
429
+ execSync(testCommand, {
430
+ cwd: repoRoot,
431
+ encoding: 'utf8',
432
+ stdio: ['pipe', 'pipe', 'pipe'],
433
+ timeout: options.testTimeout ?? 60000,
434
+ });
435
+
436
+ return {
437
+ gate: 'tests_pass',
438
+ pass: true,
439
+ reason: 'All tests passed',
440
+ severity: 'info',
441
+ };
442
+ } catch (e) {
443
+ return {
444
+ gate: 'tests_pass',
445
+ pass: false,
446
+ reason: `Tests failed: ${e.message?.slice(0, 100) ?? 'Unknown error'}`,
447
+ remedy: 'Fix test failures or use --skip-tests to bypass',
448
+ severity: 'error',
449
+ };
450
+ }
451
+ }
452
+
453
+ /**
454
+ * Run all post-flight gates
455
+ * @param {string} repoRoot - Repository root
456
+ * @param {object} mission - Mission object
457
+ * @param {object} before - Ship results before fix
458
+ * @param {object} after - Ship results after fix
459
+ * @param {object} options - Gate options
460
+ * @returns {object} Combined gate results
461
+ */
462
+ function runPostFlightGates(repoRoot, mission, before, after, options = {}) {
463
+ const audit = getAuditTrail();
464
+ const missionId = mission?.id || 'unknown';
465
+
466
+ audit.debug('postflight_gates_start', { missionId });
467
+
468
+ // Validate inputs
469
+ if (!before || !after) {
470
+ audit.error('postflight_gates_missing_results', { missionId, hasBefore: !!before, hasAfter: !!after });
471
+ return {
472
+ ok: false,
473
+ results: [{
474
+ gate: 'validation',
475
+ pass: false,
476
+ reason: 'Before and after ship results are required',
477
+ severity: 'error',
478
+ }],
479
+ passed: 0,
480
+ failed: 1,
481
+ warnings: 0,
482
+ shouldRollback: true,
483
+ summary: 'Post-flight validation failed',
484
+ };
485
+ }
486
+
487
+ const results = [];
488
+
489
+ // Run gates with error handling
490
+ try {
491
+ results.push(gateFindingsReduced(before, after, mission));
492
+ } catch (e) {
493
+ results.push({ gate: 'findings_reduced', pass: false, reason: `Gate error: ${e.message}`, severity: 'error' });
494
+ }
495
+
496
+ try {
497
+ results.push(gateNoRegressions(before, after));
498
+ } catch (e) {
499
+ results.push({ gate: 'no_regressions', pass: false, reason: `Gate error: ${e.message}`, severity: 'error' });
500
+ }
501
+
502
+ try {
503
+ results.push(gateScoreDecrease(before, after));
504
+ } catch (e) {
505
+ results.push({ gate: 'score_decrease', pass: false, reason: `Gate error: ${e.message}`, severity: 'error' });
506
+ }
507
+
508
+ // Optionally run tests
509
+ if (options.runTests) {
510
+ try {
511
+ results.push(gateTestsPass(repoRoot, options));
512
+ } catch (e) {
513
+ results.push({ gate: 'tests_pass', pass: false, reason: `Gate error: ${e.message}`, severity: 'error' });
514
+ }
515
+ }
516
+
517
+ const passed = results.filter(r => r.pass);
518
+ const failed = results.filter(r => !r.pass);
519
+ const warnings = results.filter(r => r.severity === 'warning');
520
+
521
+ // Determine if rollback is recommended
522
+ const shouldRollback = failed.some(f =>
523
+ f.gate === 'findings_reduced' ||
524
+ f.gate === 'no_regressions' ||
525
+ f.gate === 'tests_pass'
526
+ );
527
+
528
+ const gateResults = {
529
+ ok: failed.length === 0,
530
+ results,
531
+ passed: passed.length,
532
+ failed: failed.length,
533
+ warnings: warnings.length,
534
+ shouldRollback,
535
+ summary: failed.length === 0
536
+ ? `All ${results.length} post-flight gates passed`
537
+ : `${failed.length} gate(s) failed: ${failed.map(f => f.gate).join(', ')}`,
538
+ };
539
+
540
+ audit.info('postflight_gates_complete', {
541
+ missionId,
542
+ ok: gateResults.ok,
543
+ passed: passed.length,
544
+ failed: failed.length,
545
+ shouldRollback,
546
+ failedGates: failed.map(f => f.gate),
547
+ });
548
+
549
+ return gateResults;
550
+ }
551
+
552
+ // ═══════════════════════════════════════════════════════════════════════════════
553
+ // COMBINED GATE RUNNER
554
+ // ═══════════════════════════════════════════════════════════════════════════════
555
+
556
+ /**
557
+ * Format gate results for display
558
+ * @param {object[]} results - Array of gate results
559
+ * @returns {string[]} Formatted lines
560
+ */
561
+ function formatGateResults(results) {
562
+ const lines = [];
563
+
564
+ for (const r of results) {
565
+ const icon = r.pass
566
+ ? (r.severity === 'warning' ? '⚠' : '✓')
567
+ : '✗';
568
+ const color = r.pass
569
+ ? (r.severity === 'warning' ? 'yellow' : 'green')
570
+ : 'red';
571
+
572
+ lines.push({
573
+ icon,
574
+ color,
575
+ gate: r.gate,
576
+ reason: r.reason,
577
+ remedy: r.remedy,
578
+ });
579
+ }
580
+
581
+ return lines;
582
+ }
583
+
584
+ /**
585
+ * Check if mission should auto-apply based on gates
586
+ * @param {string} repoRoot - Repository root
587
+ * @param {object} mission - Mission object
588
+ * @param {object} options - Gate options
589
+ * @returns {object} Decision result
590
+ */
591
+ function shouldAutoApply(repoRoot, mission, options = {}) {
592
+ const preFlightResults = runPreFlightGates(repoRoot, mission, options);
593
+
594
+ if (!preFlightResults.ok) {
595
+ return {
596
+ shouldApply: false,
597
+ reason: 'Pre-flight gates failed',
598
+ preFlightResults,
599
+ };
600
+ }
601
+
602
+ // Check mission-level safety
603
+ const isSafe =
604
+ mission.safety?.reversible !== false &&
605
+ mission.safety?.riskLevel !== RISK_LEVEL.CRITICAL &&
606
+ mission.safety?.confidence >= (options.minConfidence ?? DEFAULT_THRESHOLDS.minConfidence);
607
+
608
+ if (!isSafe && !options.force) {
609
+ return {
610
+ shouldApply: false,
611
+ reason: 'Mission does not meet auto-apply criteria',
612
+ preFlightResults,
613
+ };
614
+ }
615
+
616
+ return {
617
+ shouldApply: true,
618
+ reason: 'All safety checks passed',
619
+ preFlightResults,
620
+ };
621
+ }
622
+
623
+ module.exports = {
624
+ // Pre-flight gates
625
+ gateConfidence,
626
+ gateBlastRadius,
627
+ gateRiskLevel,
628
+ gateOpenChanges,
629
+ gateFilesExist,
630
+ runPreFlightGates,
631
+
632
+ // Post-flight gates
633
+ gateFindingsReduced,
634
+ gateNoRegressions,
635
+ gateScoreDecrease,
636
+ gateTestsPass,
637
+ runPostFlightGates,
638
+
639
+ // Utilities
640
+ formatGateResults,
641
+ shouldAutoApply,
642
+
643
+ // Constants
644
+ DEFAULT_THRESHOLDS,
645
+ };