patchwarden 1.5.0 → 1.6.1

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 (597) hide show
  1. package/PatchWarden.cmd +32 -2
  2. package/README.en.md +194 -26
  3. package/README.md +160 -22
  4. package/dist/assessments/agentAssessor.d.ts +1 -1
  5. package/dist/assessments/agentAssessor.js +24 -15
  6. package/dist/assessments/assessmentStore.d.ts +1 -1
  7. package/dist/assessments/assessmentStore.js +44 -36
  8. package/dist/assessments/confirmCli.js +5 -4
  9. package/dist/config.d.ts +22 -0
  10. package/dist/config.js +98 -11
  11. package/dist/control/fileManager.d.ts +2 -0
  12. package/dist/control/fileManager.js +39 -0
  13. package/dist/control/middleware/auth.d.ts +16 -0
  14. package/dist/control/middleware/auth.js +17 -0
  15. package/dist/control/middleware/static.d.ts +3 -0
  16. package/dist/control/middleware/static.js +78 -0
  17. package/dist/control/routeTable.d.ts +24 -0
  18. package/dist/control/routeTable.js +263 -0
  19. package/dist/control/routes/audit.d.ts +15 -0
  20. package/dist/control/routes/audit.js +287 -0
  21. package/dist/control/routes/evidence.d.ts +4 -0
  22. package/dist/control/routes/evidence.js +96 -0
  23. package/dist/control/routes/lineage.d.ts +3 -0
  24. package/dist/control/routes/lineage.js +71 -0
  25. package/dist/control/routes/policy.d.ts +3 -0
  26. package/dist/control/routes/policy.js +81 -0
  27. package/dist/control/routes/process.d.ts +12 -0
  28. package/dist/control/routes/process.js +487 -0
  29. package/dist/control/routes/sessions.d.ts +30 -0
  30. package/dist/control/routes/sessions.js +287 -0
  31. package/dist/control/routes/status.d.ts +51 -0
  32. package/dist/control/routes/status.js +307 -0
  33. package/dist/control/routes/taskActions.d.ts +21 -0
  34. package/dist/control/routes/taskActions.js +197 -0
  35. package/dist/control/routes/tasks.d.ts +24 -0
  36. package/dist/control/routes/tasks.js +309 -0
  37. package/dist/control/routes/workspace.d.ts +15 -0
  38. package/dist/control/routes/workspace.js +220 -0
  39. package/dist/control/runtime.d.ts +92 -0
  40. package/dist/control/runtime.js +425 -0
  41. package/dist/control/server.d.ts +13 -0
  42. package/dist/control/server.js +150 -0
  43. package/dist/control/shared.d.ts +59 -0
  44. package/dist/control/shared.js +341 -0
  45. package/dist/controlCenter.d.ts +6 -0
  46. package/dist/controlCenter.js +7 -2197
  47. package/dist/direct/directAudit.js +234 -225
  48. package/dist/direct/directGuards.d.ts +2 -1
  49. package/dist/direct/directGuards.js +72 -37
  50. package/dist/direct/directPatch.d.ts +6 -1
  51. package/dist/direct/directPatch.js +55 -8
  52. package/dist/direct/directSessionStore.d.ts +16 -6
  53. package/dist/direct/directSessionStore.js +127 -35
  54. package/dist/direct/directVerification.js +8 -16
  55. package/dist/doctor.d.ts +18 -1
  56. package/dist/doctor.js +614 -373
  57. package/dist/goal/acceptanceEngine.d.ts +1 -1
  58. package/dist/goal/goalProgress.js +75 -69
  59. package/dist/goal/goalReport.d.ts +54 -0
  60. package/dist/goal/goalReport.js +197 -0
  61. package/dist/goal/goalStatus.d.ts +8 -0
  62. package/dist/goal/goalStatus.js +10 -3
  63. package/dist/goal/goalStore.d.ts +9 -2
  64. package/dist/goal/goalStore.js +152 -45
  65. package/dist/goal/handoffExport.js +6 -6
  66. package/dist/goal/specKitImport.d.ts +63 -0
  67. package/dist/goal/specKitImport.js +221 -0
  68. package/dist/goal/subgoalSync.js +13 -10
  69. package/dist/goal/worktreeManager.d.ts +2 -0
  70. package/dist/goal/worktreeManager.js +209 -136
  71. package/dist/httpServer.js +126 -44
  72. package/dist/index.js +7 -4
  73. package/dist/logging.d.ts +7 -1
  74. package/dist/logging.js +13 -3
  75. package/dist/policy/projectPolicy.js +5 -2
  76. package/dist/release/releaseGate.d.ts +1 -1
  77. package/dist/release/releaseGate.js +78 -25
  78. package/dist/runner/agentInvocation.d.ts +14 -0
  79. package/dist/runner/agentInvocation.js +96 -4
  80. package/dist/runner/changeCapture.d.ts +14 -6
  81. package/dist/runner/changeCapture.js +287 -81
  82. package/dist/runner/cli.js +7 -6
  83. package/dist/runner/postTaskCleanup.js +60 -7
  84. package/dist/runner/processSecurity.d.ts +56 -0
  85. package/dist/runner/processSecurity.js +373 -0
  86. package/dist/runner/runTask.d.ts +1 -1
  87. package/dist/runner/runTask.js +339 -287
  88. package/dist/runner/simpleProcess.d.ts +3 -0
  89. package/dist/runner/simpleProcess.js +52 -38
  90. package/dist/{taskProgress.d.ts → runner/taskProgress.d.ts} +1 -1
  91. package/dist/{taskProgress.js → runner/taskProgress.js} +2 -2
  92. package/dist/{taskRuntime.d.ts → runner/taskRuntime.d.ts} +1 -1
  93. package/dist/{taskRuntime.js → runner/taskRuntime.js} +3 -2
  94. package/dist/runner/taskStatusStore.d.ts +11 -0
  95. package/dist/runner/taskStatusStore.js +24 -0
  96. package/dist/runner/watch.d.ts +14 -1
  97. package/dist/runner/watch.js +265 -54
  98. package/dist/security/contentRedaction.d.ts +6 -0
  99. package/dist/security/contentRedaction.js +24 -2
  100. package/dist/security/discoveryTokenStore.d.ts +3 -2
  101. package/dist/security/discoveryTokenStore.js +17 -2
  102. package/dist/security/loopbackHost.d.ts +2 -0
  103. package/dist/security/loopbackHost.js +16 -0
  104. package/dist/security/pathGuard.js +32 -17
  105. package/dist/security/planGuard.js +2 -1
  106. package/dist/security/runtimeGuard.js +9 -6
  107. package/dist/security/secretComparison.d.ts +3 -0
  108. package/dist/security/secretComparison.js +11 -0
  109. package/dist/security/sensitiveGuard.d.ts +5 -0
  110. package/dist/security/sensitiveGuard.js +27 -8
  111. package/dist/security/toolInvocationGuard.d.ts +2 -2
  112. package/dist/security/toolInvocationGuard.js +1 -1
  113. package/dist/security/workspaceRootGuard.d.ts +8 -0
  114. package/dist/security/workspaceRootGuard.js +47 -0
  115. package/dist/smoke-test.js +280 -273
  116. package/dist/tools/catalog/index.d.ts +4 -0
  117. package/dist/tools/catalog/index.js +4 -0
  118. package/dist/tools/{toolCatalog.js → catalog/toolCatalog.js} +3 -12
  119. package/dist/tools/{toolRegistry.d.ts → catalog/toolRegistry.d.ts} +3 -3
  120. package/dist/tools/{toolRegistry.js → catalog/toolRegistry.js} +28 -15
  121. package/dist/tools/definitions/toolDefs.d.ts +18 -0
  122. package/dist/tools/definitions/toolDefs.js +1177 -0
  123. package/dist/tools/{auditSession.d.ts → diagnostics/auditSession.d.ts} +1 -1
  124. package/dist/tools/{auditSession.js → diagnostics/auditSession.js} +2 -2
  125. package/dist/tools/{auditTask.d.ts → diagnostics/auditTask.d.ts} +8 -63
  126. package/dist/tools/{auditTask.js → diagnostics/auditTask.js} +111 -37
  127. package/dist/tools/{healthCheck.d.ts → diagnostics/healthCheck.d.ts} +6 -6
  128. package/dist/tools/{healthCheck.js → diagnostics/healthCheck.js} +10 -10
  129. package/dist/tools/diagnostics/index.d.ts +6 -0
  130. package/dist/tools/diagnostics/index.js +6 -0
  131. package/dist/tools/{safeStatus.d.ts → diagnostics/safeStatus.d.ts} +3 -3
  132. package/dist/tools/{safeStatus.js → diagnostics/safeStatus.js} +6 -6
  133. package/dist/tools/{safeViews.d.ts → diagnostics/safeViews.d.ts} +14 -10
  134. package/dist/tools/{safeViews.js → diagnostics/safeViews.js} +25 -15
  135. package/dist/tools/{schemaDriftCheck.d.ts → diagnostics/schemaDriftCheck.d.ts} +1 -1
  136. package/dist/tools/{schemaDriftCheck.js → diagnostics/schemaDriftCheck.js} +2 -2
  137. package/dist/tools/{createDirectSession.d.ts → direct/createDirectSession.d.ts} +1 -1
  138. package/dist/tools/{createDirectSession.js → direct/createDirectSession.js} +8 -8
  139. package/dist/tools/{finalizeDirectSession.d.ts → direct/finalizeDirectSession.d.ts} +2 -2
  140. package/dist/tools/direct/finalizeDirectSession.js +86 -0
  141. package/dist/tools/direct/index.d.ts +3 -0
  142. package/dist/tools/direct/index.js +3 -0
  143. package/dist/tools/{runDirectVerificationBundle.js → direct/runDirectVerificationBundle.js} +2 -2
  144. package/dist/tools/{discoverTools.d.ts → discovery/discoverTools.d.ts} +2 -2
  145. package/dist/tools/{discoverTools.js → discovery/discoverTools.js} +5 -5
  146. package/dist/tools/{explainTool.d.ts → discovery/explainTool.d.ts} +2 -2
  147. package/dist/tools/{explainTool.js → discovery/explainTool.js} +2 -2
  148. package/dist/tools/discovery/index.d.ts +3 -0
  149. package/dist/tools/discovery/index.js +3 -0
  150. package/dist/tools/{invokeDiscoveredTool.d.ts → discovery/invokeDiscoveredTool.d.ts} +2 -2
  151. package/dist/tools/{invokeDiscoveredTool.js → discovery/invokeDiscoveredTool.js} +5 -5
  152. package/dist/tools/dispatch/coreDispatch.d.ts +9 -0
  153. package/dist/tools/dispatch/coreDispatch.js +283 -0
  154. package/dist/tools/dispatch/diagnosticDispatch.d.ts +12 -0
  155. package/dist/tools/dispatch/diagnosticDispatch.js +80 -0
  156. package/dist/tools/dispatch/directDispatch.d.ts +8 -0
  157. package/dist/tools/dispatch/directDispatch.js +116 -0
  158. package/dist/tools/dispatch/goalDispatch.d.ts +8 -0
  159. package/dist/tools/dispatch/goalDispatch.js +92 -0
  160. package/dist/tools/dispatch/releaseDispatch.d.ts +8 -0
  161. package/dist/tools/dispatch/releaseDispatch.js +46 -0
  162. package/dist/tools/dispatch/types.d.ts +23 -0
  163. package/dist/tools/dispatch/types.js +15 -0
  164. package/dist/tools/dispatch/validation.d.ts +7 -0
  165. package/dist/tools/dispatch/validation.js +71 -0
  166. package/dist/tools/{getPlan.js → goals/getPlan.js} +4 -4
  167. package/dist/tools/{goalSubgoalTask.d.ts → goals/goalSubgoalTask.d.ts} +2 -2
  168. package/dist/tools/goals/goalSubgoalTask.js +118 -0
  169. package/dist/tools/goals/index.d.ts +3 -0
  170. package/dist/tools/goals/index.js +3 -0
  171. package/dist/tools/{savePlan.js → goals/savePlan.js} +28 -8
  172. package/dist/tools/registry.d.ts +10 -14
  173. package/dist/tools/registry.js +47 -1651
  174. package/dist/tools/{checkReleaseGate.d.ts → release/checkReleaseGate.d.ts} +1 -1
  175. package/dist/tools/{checkReleaseGate.js → release/checkReleaseGate.js} +3 -3
  176. package/dist/tools/release/index.d.ts +2 -0
  177. package/dist/tools/release/index.js +2 -0
  178. package/dist/tools/{releaseMode.d.ts → release/releaseMode.d.ts} +2 -2
  179. package/dist/tools/{releaseMode.js → release/releaseMode.js} +46 -26
  180. package/dist/tools/tasks/cancelTask.d.ts +11 -0
  181. package/dist/tools/tasks/cancelTask.js +85 -0
  182. package/dist/tools/{createTask.d.ts → tasks/createTask.d.ts} +12 -4
  183. package/dist/tools/{createTask.js → tasks/createTask.js} +46 -31
  184. package/dist/tools/{diagnoseTask.d.ts → tasks/diagnoseTask.d.ts} +1 -1
  185. package/dist/tools/{diagnoseTask.js → tasks/diagnoseTask.js} +8 -8
  186. package/dist/tools/{evidencePack.d.ts → tasks/evidencePack.d.ts} +6 -0
  187. package/dist/tools/tasks/evidencePack.js +387 -0
  188. package/dist/tools/{getTaskFile.js → tasks/getTaskFile.js} +4 -4
  189. package/dist/tools/{getTaskStatus.d.ts → tasks/getTaskStatus.d.ts} +6 -1
  190. package/dist/tools/{getTaskStatus.js → tasks/getTaskStatus.js} +5 -5
  191. package/dist/tools/{getTaskStdoutTail.js → tasks/getTaskStdoutTail.js} +13 -11
  192. package/dist/tools/{getTaskSummary.js → tasks/getTaskSummary.js} +33 -26
  193. package/dist/tools/tasks/index.d.ts +18 -0
  194. package/dist/tools/tasks/index.js +18 -0
  195. package/dist/tools/tasks/killTask.d.ts +1 -0
  196. package/dist/tools/{listTasks.d.ts → tasks/listTasks.d.ts} +1 -1
  197. package/dist/tools/{listTasks.js → tasks/listTasks.js} +3 -3
  198. package/dist/tools/{reconcileTasks.d.ts → tasks/reconcileTasks.d.ts} +1 -1
  199. package/dist/tools/{reconcileTasks.js → tasks/reconcileTasks.js} +64 -66
  200. package/dist/tools/{retryTask.d.ts → tasks/retryTask.d.ts} +2 -2
  201. package/dist/tools/tasks/retryTask.js +60 -0
  202. package/dist/tools/{runTaskLoop.d.ts → tasks/runTaskLoop.d.ts} +6 -6
  203. package/dist/tools/{runTaskLoop.js → tasks/runTaskLoop.js} +59 -31
  204. package/dist/tools/tasks/runVerification.js +38 -0
  205. package/dist/tools/{taskLineage.js → tasks/taskLineage.js} +8 -7
  206. package/dist/tools/{taskOutputs.js → tasks/taskOutputs.js} +17 -16
  207. package/dist/tools/{androidDoctor.js → workspace/androidDoctor.js} +16 -10
  208. package/dist/tools/{applyPatch.d.ts → workspace/applyPatch.d.ts} +1 -1
  209. package/dist/tools/workspace/applyPatch.js +53 -0
  210. package/dist/tools/{discardWorktree.js → workspace/discardWorktree.js} +3 -3
  211. package/dist/tools/workspace/index.d.ts +10 -0
  212. package/dist/tools/workspace/index.js +10 -0
  213. package/dist/tools/{listAgents.d.ts → workspace/listAgents.d.ts} +5 -0
  214. package/dist/tools/{listAgents.js → workspace/listAgents.js} +8 -4
  215. package/dist/tools/{listWorkspace.js → workspace/listWorkspace.js} +3 -3
  216. package/dist/tools/{mergeWorktree.js → workspace/mergeWorktree.js} +3 -3
  217. package/dist/tools/{readWorkspaceFile.js → workspace/readWorkspaceFile.js} +8 -8
  218. package/dist/tools/{recommendAgentForTask.js → workspace/recommendAgentForTask.js} +3 -3
  219. package/dist/tools/{searchWorkspace.js → workspace/searchWorkspace.js} +5 -5
  220. package/dist/tools/{syncFile.d.ts → workspace/syncFile.d.ts} +1 -1
  221. package/dist/tools/workspace/syncFile.js +134 -0
  222. package/dist/utils/atomicFile.d.ts +7 -0
  223. package/dist/utils/atomicFile.js +48 -0
  224. package/dist/utils/boundedFile.d.ts +8 -0
  225. package/dist/utils/boundedFile.js +93 -0
  226. package/dist/utils/lockedJsonFile.d.ts +15 -0
  227. package/dist/utils/lockedJsonFile.js +224 -0
  228. package/dist/utils/platform.d.ts +11 -0
  229. package/dist/utils/platform.js +26 -0
  230. package/dist/utils/stableJson.d.ts +2 -0
  231. package/dist/utils/stableJson.js +12 -0
  232. package/dist/version.d.ts +3 -2
  233. package/dist/version.js +3 -2
  234. package/dist/watcherStatus.d.ts +2 -2
  235. package/dist/watcherStatus.js +18 -0
  236. package/docs/CODE_WIKI.md +1648 -0
  237. package/docs/agentseal-integration.md +150 -0
  238. package/docs/architecture.md +23 -0
  239. package/docs/assets/patchwarden-desktop-onboarding.png +0 -0
  240. package/docs/assets/patchwarden-oss-demo.gif +0 -0
  241. package/docs/control-center/README.md +4 -4
  242. package/docs/dashboard-overview.md +86 -0
  243. package/docs/demo.md +8 -0
  244. package/docs/desktop-app.md +175 -0
  245. package/docs/direct-session-workflow.md +98 -0
  246. package/docs/evidence-pack-schema.md +215 -0
  247. package/docs/lineage-evidence-pack-workflow.md +127 -0
  248. package/docs/mcp-inspector-testing.md +200 -0
  249. package/docs/open-source-application.md +168 -0
  250. package/docs/opencode-worker.md +151 -0
  251. package/docs/openhands-worker.md +181 -0
  252. package/docs/release-checklist.md +1 -1
  253. package/docs/release-evidence.md +82 -0
  254. package/docs/spec-kit-integration.md +131 -0
  255. package/docs/task-safe-review-workflow.md +98 -0
  256. package/docs/threat-model.md +97 -0
  257. package/docs/user-feedback.md +40 -0
  258. package/docs/why-patchwarden.md +110 -0
  259. package/examples/config.example.json +4 -2
  260. package/package.json +28 -11
  261. package/scripts/README.md +15 -6
  262. package/scripts/build.js +11 -0
  263. package/scripts/checks/brand-check.js +3 -0
  264. package/scripts/checks/build-output-check.js +37 -0
  265. package/scripts/checks/control-center-smoke.js +447 -6
  266. package/scripts/checks/control-smoke.js +19 -8
  267. package/scripts/checks/http-mcp-smoke.js +82 -4
  268. package/scripts/checks/lifecycle-smoke.js +39 -33
  269. package/scripts/checks/mcp-manifest-check.js +1 -1
  270. package/scripts/checks/mcp-smoke.js +30 -4
  271. package/scripts/checks/package-manifest-check.js +20 -7
  272. package/scripts/checks/unit-tests.js +3 -5
  273. package/scripts/checks/watcher-supervisor-smoke.js +9 -0
  274. package/scripts/control/get-patchwarden-health.ps1 +1 -1
  275. package/scripts/control/manage-patchwarden.ps1 +69 -4
  276. package/scripts/control/provision-patchwarden-tunnel.ps1 +127 -0
  277. package/scripts/control/run-background-supervisor.ps1 +41 -0
  278. package/scripts/control/start-patchwarden-tunnel.ps1 +126 -32
  279. package/scripts/generate-demo-gif.py +320 -0
  280. package/{PatchWarden-Control-Tray.cmd → scripts/launchers/PatchWarden-Control-Tray.cmd} +3 -3
  281. package/scripts/launchers/PatchWarden-Control.cmd +6 -0
  282. package/{PatchWarden-Desktop.cmd → scripts/launchers/PatchWarden-Desktop.cmd} +2 -2
  283. package/scripts/launchers/Restart-PatchWarden-Control.cmd +6 -0
  284. package/{Stop-PatchWarden.cmd → scripts/launchers/Stop-PatchWarden.cmd} +2 -2
  285. package/scripts/lib/clean-generated-output.js +11 -0
  286. package/scripts/lib/file-discovery.js +12 -0
  287. package/scripts/release/desktop-preflight.js +211 -0
  288. package/scripts/release/pack-clean.js +59 -14
  289. package/src/assessments/agentAssessor.ts +29 -15
  290. package/src/assessments/assessmentStore.ts +55 -43
  291. package/src/assessments/confirmCli.ts +5 -4
  292. package/src/config.ts +105 -11
  293. package/src/control/fileManager.ts +40 -0
  294. package/src/control/middleware/auth.ts +35 -0
  295. package/src/control/middleware/static.ts +84 -0
  296. package/src/control/routeTable.ts +301 -0
  297. package/src/control/routes/audit.ts +329 -0
  298. package/src/control/routes/evidence.ts +107 -0
  299. package/src/control/routes/lineage.ts +92 -0
  300. package/src/control/routes/policy.ts +81 -0
  301. package/src/control/routes/process.ts +505 -0
  302. package/src/control/routes/sessions.ts +314 -0
  303. package/src/control/routes/status.ts +405 -0
  304. package/src/control/routes/taskActions.ts +214 -0
  305. package/src/control/routes/tasks.ts +331 -0
  306. package/src/control/routes/workspace.ts +234 -0
  307. package/src/control/runtime.ts +508 -0
  308. package/src/control/server.ts +165 -0
  309. package/src/control/shared.ts +360 -0
  310. package/src/controlCenter.ts +7 -2347
  311. package/src/direct/directAudit.ts +17 -9
  312. package/src/direct/directGuards.ts +100 -51
  313. package/src/direct/directPatch.ts +95 -8
  314. package/src/direct/directSessionStore.ts +211 -55
  315. package/src/direct/directVerification.ts +9 -23
  316. package/src/doctor.ts +766 -492
  317. package/src/goal/acceptanceEngine.ts +1 -1
  318. package/src/goal/goalProgress.ts +17 -13
  319. package/src/goal/goalReport.ts +263 -0
  320. package/src/goal/goalStatus.ts +25 -3
  321. package/src/goal/goalStore.ts +241 -54
  322. package/src/goal/handoffExport.ts +6 -6
  323. package/src/goal/specKitImport.ts +355 -0
  324. package/src/goal/subgoalSync.ts +15 -10
  325. package/src/goal/worktreeManager.ts +139 -22
  326. package/src/httpServer.ts +130 -44
  327. package/src/index.ts +7 -4
  328. package/src/logging.ts +20 -4
  329. package/src/policy/projectPolicy.ts +5 -2
  330. package/src/release/releaseGate.ts +74 -27
  331. package/src/runner/agentInvocation.ts +126 -4
  332. package/src/runner/changeCapture.ts +342 -80
  333. package/src/runner/cli.ts +7 -6
  334. package/src/runner/postTaskCleanup.ts +55 -7
  335. package/src/runner/processSecurity.ts +433 -0
  336. package/src/runner/runTask.ts +441 -292
  337. package/src/runner/simpleProcess.ts +68 -33
  338. package/src/{taskProgress.ts → runner/taskProgress.ts} +3 -3
  339. package/src/{taskRuntime.ts → runner/taskRuntime.ts} +4 -3
  340. package/src/runner/taskStatusStore.ts +54 -0
  341. package/src/runner/watch.ts +290 -57
  342. package/src/security/contentRedaction.ts +31 -2
  343. package/src/security/discoveryTokenStore.ts +18 -4
  344. package/src/security/loopbackHost.ts +19 -0
  345. package/src/security/pathGuard.ts +35 -16
  346. package/src/security/planGuard.ts +2 -1
  347. package/src/security/runtimeGuard.ts +9 -6
  348. package/src/security/secretComparison.ts +13 -0
  349. package/src/security/sensitiveGuard.ts +27 -8
  350. package/src/security/toolInvocationGuard.ts +2 -2
  351. package/src/security/workspaceRootGuard.ts +53 -0
  352. package/src/smoke-test.ts +276 -273
  353. package/src/tools/catalog/index.ts +4 -0
  354. package/src/tools/{toolCatalog.ts → catalog/toolCatalog.ts} +3 -12
  355. package/src/tools/{toolRegistry.ts → catalog/toolRegistry.ts} +29 -16
  356. package/src/tools/definitions/toolDefs.ts +1264 -0
  357. package/src/tools/{auditSession.ts → diagnostics/auditSession.ts} +2 -2
  358. package/src/tools/{auditTask.ts → diagnostics/auditTask.ts} +196 -89
  359. package/src/tools/{healthCheck.ts → diagnostics/healthCheck.ts} +11 -11
  360. package/src/tools/diagnostics/index.ts +6 -0
  361. package/src/tools/{safeStatus.ts → diagnostics/safeStatus.ts} +7 -7
  362. package/src/tools/{safeViews.ts → diagnostics/safeViews.ts} +29 -19
  363. package/src/tools/{schemaDriftCheck.ts → diagnostics/schemaDriftCheck.ts} +3 -3
  364. package/src/tools/{createDirectSession.ts → direct/createDirectSession.ts} +9 -9
  365. package/src/tools/{finalizeDirectSession.ts → direct/finalizeDirectSession.ts} +11 -9
  366. package/src/tools/direct/index.ts +3 -0
  367. package/src/tools/{runDirectVerificationBundle.ts → direct/runDirectVerificationBundle.ts} +2 -2
  368. package/src/tools/{discoverTools.ts → discovery/discoverTools.ts} +6 -6
  369. package/src/tools/{explainTool.ts → discovery/explainTool.ts} +3 -3
  370. package/src/tools/discovery/index.ts +3 -0
  371. package/src/tools/{invokeDiscoveredTool.ts → discovery/invokeDiscoveredTool.ts} +7 -7
  372. package/src/tools/dispatch/coreDispatch.ts +379 -0
  373. package/src/tools/dispatch/diagnosticDispatch.ts +106 -0
  374. package/src/tools/dispatch/directDispatch.ts +168 -0
  375. package/src/tools/dispatch/goalDispatch.ts +128 -0
  376. package/src/tools/dispatch/releaseDispatch.ts +66 -0
  377. package/src/tools/dispatch/types.ts +24 -0
  378. package/src/tools/dispatch/validation.ts +78 -0
  379. package/src/tools/{getPlan.ts → goals/getPlan.ts} +4 -4
  380. package/src/tools/{goalSubgoalTask.ts → goals/goalSubgoalTask.ts} +43 -28
  381. package/src/tools/goals/index.ts +3 -0
  382. package/src/tools/{savePlan.ts → goals/savePlan.ts} +38 -8
  383. package/src/tools/registry.ts +54 -1858
  384. package/src/tools/{checkReleaseGate.ts → release/checkReleaseGate.ts} +3 -3
  385. package/src/tools/release/index.ts +2 -0
  386. package/src/tools/{releaseMode.ts → release/releaseMode.ts} +42 -24
  387. package/src/tools/tasks/cancelTask.ts +109 -0
  388. package/src/tools/{createTask.ts → tasks/createTask.ts} +56 -33
  389. package/src/tools/{diagnoseTask.ts → tasks/diagnoseTask.ts} +8 -8
  390. package/src/tools/tasks/evidencePack.ts +504 -0
  391. package/src/tools/{getTaskFile.ts → tasks/getTaskFile.ts} +4 -4
  392. package/src/tools/{getTaskStatus.ts → tasks/getTaskStatus.ts} +7 -5
  393. package/src/tools/{getTaskStdoutTail.ts → tasks/getTaskStdoutTail.ts} +13 -11
  394. package/src/tools/{getTaskSummary.ts → tasks/getTaskSummary.ts} +44 -33
  395. package/src/tools/tasks/index.ts +18 -0
  396. package/src/tools/{listTasks.ts → tasks/listTasks.ts} +4 -4
  397. package/src/tools/{reconcileTasks.ts → tasks/reconcileTasks.ts} +68 -66
  398. package/src/tools/tasks/retryTask.ts +69 -0
  399. package/src/tools/{runTaskLoop.ts → tasks/runTaskLoop.ts} +70 -35
  400. package/src/tools/{runVerification.ts → tasks/runVerification.ts} +6 -3
  401. package/src/tools/{taskLineage.ts → tasks/taskLineage.ts} +8 -7
  402. package/src/tools/{taskOutputs.ts → tasks/taskOutputs.ts} +27 -20
  403. package/src/tools/{androidDoctor.ts → workspace/androidDoctor.ts} +15 -10
  404. package/src/tools/{applyPatch.ts → workspace/applyPatch.ts} +38 -16
  405. package/src/tools/{discardWorktree.ts → workspace/discardWorktree.ts} +3 -3
  406. package/src/tools/workspace/index.ts +10 -0
  407. package/src/tools/{listAgents.ts → workspace/listAgents.ts} +11 -4
  408. package/src/tools/{listWorkspace.ts → workspace/listWorkspace.ts} +3 -3
  409. package/src/tools/{mergeWorktree.ts → workspace/mergeWorktree.ts} +3 -3
  410. package/src/tools/{readWorkspaceFile.ts → workspace/readWorkspaceFile.ts} +8 -8
  411. package/src/tools/{recommendAgentForTask.ts → workspace/recommendAgentForTask.ts} +3 -3
  412. package/src/tools/{searchWorkspace.ts → workspace/searchWorkspace.ts} +5 -5
  413. package/src/tools/workspace/syncFile.ts +292 -0
  414. package/src/utils/atomicFile.ts +58 -0
  415. package/src/utils/boundedFile.ts +116 -0
  416. package/src/utils/lockedJsonFile.ts +251 -0
  417. package/src/utils/platform.ts +31 -0
  418. package/src/utils/stableJson.ts +12 -0
  419. package/src/version.ts +3 -2
  420. package/src/watcherStatus.ts +19 -1
  421. package/ui/desktop-bootstrap.js +11 -0
  422. package/ui/desktop-bridge.js +36 -0
  423. package/ui/desktop.css +160 -0
  424. package/ui/getting-started.js +93 -0
  425. package/ui/i18n.js +484 -0
  426. package/ui/log-parser.js +30 -0
  427. package/ui/pages/audit.html +204 -3
  428. package/ui/pages/dashboard.html +937 -79
  429. package/ui/pages/direct-sessions.html +609 -60
  430. package/ui/pages/getting-started.html +43 -0
  431. package/ui/pages/logs.html +105 -22
  432. package/ui/pages/settings.html +101 -0
  433. package/ui/pages/task-detail.html +468 -438
  434. package/ui/pages/tasks.html +648 -65
  435. package/ui/pages/workspace.html +38 -1
  436. package/ui/settings.js +245 -0
  437. package/PatchWarden-Control.cmd +0 -6
  438. package/Restart-PatchWarden-Control.cmd +0 -6
  439. package/dist/test/unit/acceptance-engine.test.d.ts +0 -1
  440. package/dist/test/unit/acceptance-engine.test.js +0 -228
  441. package/dist/test/unit/agent-router.test.d.ts +0 -1
  442. package/dist/test/unit/agent-router.test.js +0 -287
  443. package/dist/test/unit/android-doctor.test.d.ts +0 -1
  444. package/dist/test/unit/android-doctor.test.js +0 -118
  445. package/dist/test/unit/audit-checks.test.d.ts +0 -1
  446. package/dist/test/unit/audit-checks.test.js +0 -350
  447. package/dist/test/unit/chinese-path.test.d.ts +0 -1
  448. package/dist/test/unit/chinese-path.test.js +0 -91
  449. package/dist/test/unit/command-guard.test.d.ts +0 -1
  450. package/dist/test/unit/command-guard.test.js +0 -160
  451. package/dist/test/unit/diagnose-task.test.d.ts +0 -1
  452. package/dist/test/unit/diagnose-task.test.js +0 -457
  453. package/dist/test/unit/direct-guards.test.d.ts +0 -1
  454. package/dist/test/unit/direct-guards.test.js +0 -213
  455. package/dist/test/unit/discovery-token-store.test.d.ts +0 -1
  456. package/dist/test/unit/discovery-token-store.test.js +0 -139
  457. package/dist/test/unit/evidence-pack.test.d.ts +0 -1
  458. package/dist/test/unit/evidence-pack.test.js +0 -130
  459. package/dist/test/unit/goal-graph.test.d.ts +0 -1
  460. package/dist/test/unit/goal-graph.test.js +0 -298
  461. package/dist/test/unit/goal-progress.test.d.ts +0 -1
  462. package/dist/test/unit/goal-progress.test.js +0 -381
  463. package/dist/test/unit/goal-status.test.d.ts +0 -1
  464. package/dist/test/unit/goal-status.test.js +0 -215
  465. package/dist/test/unit/goal-store.test.d.ts +0 -1
  466. package/dist/test/unit/goal-store.test.js +0 -253
  467. package/dist/test/unit/goal-subgoal-task.test.d.ts +0 -1
  468. package/dist/test/unit/goal-subgoal-task.test.js +0 -55
  469. package/dist/test/unit/goal-tools-registry.test.d.ts +0 -1
  470. package/dist/test/unit/goal-tools-registry.test.js +0 -190
  471. package/dist/test/unit/handoff-export.test.d.ts +0 -1
  472. package/dist/test/unit/handoff-export.test.js +0 -263
  473. package/dist/test/unit/invoke-discovered-tool.test.d.ts +0 -1
  474. package/dist/test/unit/invoke-discovered-tool.test.js +0 -167
  475. package/dist/test/unit/logging.test.d.ts +0 -1
  476. package/dist/test/unit/logging.test.js +0 -397
  477. package/dist/test/unit/path-guard.test.d.ts +0 -1
  478. package/dist/test/unit/path-guard.test.js +0 -109
  479. package/dist/test/unit/post-task-cleanup.test.d.ts +0 -1
  480. package/dist/test/unit/post-task-cleanup.test.js +0 -48
  481. package/dist/test/unit/project-policy-release-mode.test.d.ts +0 -1
  482. package/dist/test/unit/project-policy-release-mode.test.js +0 -125
  483. package/dist/test/unit/reconcile-tasks.test.d.ts +0 -1
  484. package/dist/test/unit/reconcile-tasks.test.js +0 -456
  485. package/dist/test/unit/release-gate.test.d.ts +0 -1
  486. package/dist/test/unit/release-gate.test.js +0 -242
  487. package/dist/test/unit/run-task-loop.test.d.ts +0 -1
  488. package/dist/test/unit/run-task-loop.test.js +0 -380
  489. package/dist/test/unit/safe-status.test.d.ts +0 -1
  490. package/dist/test/unit/safe-status.test.js +0 -165
  491. package/dist/test/unit/safe-views.test.d.ts +0 -1
  492. package/dist/test/unit/safe-views.test.js +0 -171
  493. package/dist/test/unit/schema-drift-check.test.d.ts +0 -1
  494. package/dist/test/unit/schema-drift-check.test.js +0 -176
  495. package/dist/test/unit/sensitive-guard.test.d.ts +0 -1
  496. package/dist/test/unit/sensitive-guard.test.js +0 -104
  497. package/dist/test/unit/subgoal-sync.test.d.ts +0 -1
  498. package/dist/test/unit/subgoal-sync.test.js +0 -183
  499. package/dist/test/unit/sync-file.test.d.ts +0 -1
  500. package/dist/test/unit/sync-file.test.js +0 -154
  501. package/dist/test/unit/tool-invocation-guard.test.d.ts +0 -1
  502. package/dist/test/unit/tool-invocation-guard.test.js +0 -432
  503. package/dist/test/unit/tool-usage-stats.test.d.ts +0 -1
  504. package/dist/test/unit/tool-usage-stats.test.js +0 -300
  505. package/dist/test/unit/toolSearch.test.d.ts +0 -1
  506. package/dist/test/unit/toolSearch.test.js +0 -571
  507. package/dist/test/unit/watcher-status.test.d.ts +0 -1
  508. package/dist/test/unit/watcher-status.test.js +0 -169
  509. package/dist/test/unit/worktree-manager.test.d.ts +0 -1
  510. package/dist/test/unit/worktree-manager.test.js +0 -176
  511. package/dist/tools/applyPatch.js +0 -41
  512. package/dist/tools/cancelTask.d.ts +0 -30
  513. package/dist/tools/cancelTask.js +0 -64
  514. package/dist/tools/evidencePack.js +0 -168
  515. package/dist/tools/finalizeDirectSession.js +0 -84
  516. package/dist/tools/goalSubgoalTask.js +0 -110
  517. package/dist/tools/killTask.d.ts +0 -15
  518. package/dist/tools/retryTask.js +0 -45
  519. package/dist/tools/runVerification.js +0 -36
  520. package/dist/tools/syncFile.js +0 -65
  521. package/docs/control-center/control-center-daily-driver.md +0 -211
  522. package/docs/control-center/control-center-mvp.md +0 -205
  523. package/docs/control-center/control-center-phase2.md +0 -159
  524. package/docs/release-v0.6.0.md +0 -71
  525. package/docs/release-v0.6.1.md +0 -75
  526. package/docs/release-v0.6.4.md +0 -45
  527. package/src/test/unit/acceptance-engine.test.ts +0 -261
  528. package/src/test/unit/agent-router.test.ts +0 -342
  529. package/src/test/unit/android-doctor.test.ts +0 -158
  530. package/src/test/unit/audit-checks.test.ts +0 -567
  531. package/src/test/unit/chinese-path.test.ts +0 -106
  532. package/src/test/unit/command-guard.test.ts +0 -221
  533. package/src/test/unit/diagnose-task.test.ts +0 -544
  534. package/src/test/unit/direct-guards.test.ts +0 -297
  535. package/src/test/unit/discovery-token-store.test.ts +0 -181
  536. package/src/test/unit/evidence-pack.test.ts +0 -142
  537. package/src/test/unit/goal-graph.test.ts +0 -347
  538. package/src/test/unit/goal-progress.test.ts +0 -538
  539. package/src/test/unit/goal-status.test.ts +0 -270
  540. package/src/test/unit/goal-store.test.ts +0 -318
  541. package/src/test/unit/goal-subgoal-task.test.ts +0 -72
  542. package/src/test/unit/goal-tools-registry.test.ts +0 -243
  543. package/src/test/unit/handoff-export.test.ts +0 -295
  544. package/src/test/unit/invoke-discovered-tool.test.ts +0 -216
  545. package/src/test/unit/logging.test.ts +0 -497
  546. package/src/test/unit/path-guard.test.ts +0 -150
  547. package/src/test/unit/post-task-cleanup.test.ts +0 -53
  548. package/src/test/unit/project-policy-release-mode.test.ts +0 -156
  549. package/src/test/unit/reconcile-tasks.test.ts +0 -551
  550. package/src/test/unit/release-gate.test.ts +0 -314
  551. package/src/test/unit/run-task-loop.test.ts +0 -425
  552. package/src/test/unit/safe-status.test.ts +0 -187
  553. package/src/test/unit/safe-views.test.ts +0 -184
  554. package/src/test/unit/schema-drift-check.test.ts +0 -260
  555. package/src/test/unit/sensitive-guard.test.ts +0 -124
  556. package/src/test/unit/subgoal-sync.test.ts +0 -236
  557. package/src/test/unit/sync-file.test.ts +0 -231
  558. package/src/test/unit/tool-invocation-guard.test.ts +0 -542
  559. package/src/test/unit/tool-usage-stats.test.ts +0 -384
  560. package/src/test/unit/toolSearch.test.ts +0 -756
  561. package/src/test/unit/watcher-status.test.ts +0 -190
  562. package/src/test/unit/worktree-manager.test.ts +0 -247
  563. package/src/tools/cancelTask.ts +0 -70
  564. package/src/tools/evidencePack.ts +0 -205
  565. package/src/tools/retryTask.ts +0 -53
  566. package/src/tools/syncFile.ts +0 -122
  567. /package/dist/tools/{toolCatalog.d.ts → catalog/toolCatalog.d.ts} +0 -0
  568. /package/dist/tools/{toolSearch.d.ts → catalog/toolSearch.d.ts} +0 -0
  569. /package/dist/tools/{toolSearch.js → catalog/toolSearch.js} +0 -0
  570. /package/dist/tools/{toolUsageStats.d.ts → catalog/toolUsageStats.d.ts} +0 -0
  571. /package/dist/tools/{toolUsageStats.js → catalog/toolUsageStats.js} +0 -0
  572. /package/dist/tools/{runDirectVerificationBundle.d.ts → direct/runDirectVerificationBundle.d.ts} +0 -0
  573. /package/dist/tools/{getPlan.d.ts → goals/getPlan.d.ts} +0 -0
  574. /package/dist/tools/{savePlan.d.ts → goals/savePlan.d.ts} +0 -0
  575. /package/dist/tools/{getTaskFile.d.ts → tasks/getTaskFile.d.ts} +0 -0
  576. /package/dist/tools/{getTaskProgress.d.ts → tasks/getTaskProgress.d.ts} +0 -0
  577. /package/dist/tools/{getTaskProgress.js → tasks/getTaskProgress.js} +0 -0
  578. /package/dist/tools/{getTaskStdoutTail.d.ts → tasks/getTaskStdoutTail.d.ts} +0 -0
  579. /package/dist/tools/{getTaskSummary.d.ts → tasks/getTaskSummary.d.ts} +0 -0
  580. /package/dist/tools/{killTask.js → tasks/killTask.js} +0 -0
  581. /package/dist/tools/{runVerification.d.ts → tasks/runVerification.d.ts} +0 -0
  582. /package/dist/tools/{taskLineage.d.ts → tasks/taskLineage.d.ts} +0 -0
  583. /package/dist/tools/{taskOutputs.d.ts → tasks/taskOutputs.d.ts} +0 -0
  584. /package/dist/tools/{waitForTask.d.ts → tasks/waitForTask.d.ts} +0 -0
  585. /package/dist/tools/{waitForTask.js → tasks/waitForTask.js} +0 -0
  586. /package/dist/tools/{androidDoctor.d.ts → workspace/androidDoctor.d.ts} +0 -0
  587. /package/dist/tools/{discardWorktree.d.ts → workspace/discardWorktree.d.ts} +0 -0
  588. /package/dist/tools/{listWorkspace.d.ts → workspace/listWorkspace.d.ts} +0 -0
  589. /package/dist/tools/{mergeWorktree.d.ts → workspace/mergeWorktree.d.ts} +0 -0
  590. /package/dist/tools/{readWorkspaceFile.d.ts → workspace/readWorkspaceFile.d.ts} +0 -0
  591. /package/dist/tools/{recommendAgentForTask.d.ts → workspace/recommendAgentForTask.d.ts} +0 -0
  592. /package/dist/tools/{searchWorkspace.d.ts → workspace/searchWorkspace.d.ts} +0 -0
  593. /package/src/tools/{toolSearch.ts → catalog/toolSearch.ts} +0 -0
  594. /package/src/tools/{toolUsageStats.ts → catalog/toolUsageStats.ts} +0 -0
  595. /package/src/tools/{getTaskProgress.ts → tasks/getTaskProgress.ts} +0 -0
  596. /package/src/tools/{killTask.ts → tasks/killTask.ts} +0 -0
  597. /package/src/tools/{waitForTask.ts → tasks/waitForTask.ts} +0 -0
@@ -1,245 +1,254 @@
1
- import { writeFileSync } from "node:fs";
2
1
  import { join, resolve, relative, isAbsolute } from "node:path";
3
- import { getConfig } from "../config.js";
4
2
  import { isSensitivePath } from "../security/sensitiveGuard.js";
5
- import { readDirectSession, getDirectSessionDir, } from "./directSessionStore.js";
3
+ import { readDirectSession, getDirectSessionDir, updateDirectSession, withDirectSessionMutationLock, } from "./directSessionStore.js";
4
+ import { atomicWriteFileSync, atomicWriteJsonFileSync } from "../utils/atomicFile.js";
6
5
  // ── Main audit function ────────────────────────────────────────────
7
6
  export function auditDirectSession(sessionId) {
8
- const config = getConfig();
9
- const session = readDirectSession(sessionId);
10
- const sessionDir = getDirectSessionDir(sessionId);
11
- const checks = [];
12
- const reasonCodes = [];
13
- const blockingFindings = [];
14
- const warnings = [];
15
- // Check 1: session finalized
16
- checks.push({
17
- name: "session_finalized",
18
- result: session.finalized ? "pass" : "fail",
19
- detail: session.finalized
20
- ? "Session has been finalized."
21
- : "Session has not been finalized. Call finalize_direct_session first.",
22
- reason_code: session.finalized ? undefined : "session_not_finalized",
23
- });
24
- // Get change artifacts if available
25
- const artifacts = session.change_artifacts;
26
- // Check 2: diff empty
27
- const changedFilesTotal = artifacts?.changed_files?.length ?? 0;
28
- checks.push({
29
- name: "diff_empty",
30
- result: changedFilesTotal === 0 ? "warn" : "pass",
31
- detail: changedFilesTotal === 0
32
- ? "No file changes detected in this session."
33
- : `${changedFilesTotal} file(s) changed.`,
34
- reason_code: changedFilesTotal === 0 ? "empty_diff" : undefined,
35
- });
36
- if (artifacts) {
37
- // Check 3: out-of-scope changes
38
- const outOfScope = findOutOfScopeChanges(artifacts, session.resolved_repo_path);
39
- checks.push({
40
- name: "out_of_scope_changes",
41
- result: outOfScope.length === 0 ? "pass" : "fail",
42
- detail: outOfScope.length === 0
43
- ? "All changes are within the session repo_path."
44
- : `${outOfScope.length} file(s) modified outside session repo_path: ${outOfScope.join(", ")}`,
45
- reason_code: outOfScope.length > 0 ? "out_of_scope_changes" : undefined,
46
- });
47
- // Check 4: sensitive files
48
- const sensitiveFiles = findSensitiveChanges(artifacts);
7
+ return withDirectSessionMutationLock(sessionId, () => {
8
+ const session = readDirectSession(sessionId);
9
+ const sessionDir = getDirectSessionDir(sessionId);
10
+ const checks = [];
11
+ const reasonCodes = [];
12
+ const blockingFindings = [];
13
+ const warnings = [];
14
+ // Check 1: session finalized
49
15
  checks.push({
50
- name: "sensitive_file_access",
51
- result: sensitiveFiles.length === 0 ? "pass" : "fail",
52
- detail: sensitiveFiles.length === 0
53
- ? "No sensitive files modified."
54
- : `Sensitive files modified: ${sensitiveFiles.join(", ")}`,
55
- reason_code: sensitiveFiles.length > 0 ? "sensitive_file_modified" : undefined,
16
+ name: "session_finalized",
17
+ result: session.finalized ? "pass" : "fail",
18
+ detail: session.finalized
19
+ ? "Session has been finalized."
20
+ : "Session has not been finalized. Call finalize_direct_session first.",
21
+ reason_code: session.finalized ? undefined : "session_not_finalized",
56
22
  });
57
- // Check 5: node_modules modification
58
- const nodeModulesChanges = findPathChanges(artifacts, "node_modules");
23
+ // Get change artifacts if available
24
+ const artifacts = session.change_artifacts;
25
+ // Check 2: diff empty
26
+ const changedFilesTotal = artifacts?.changed_files?.length ?? 0;
59
27
  checks.push({
60
- name: "node_modules_modified",
61
- result: nodeModulesChanges.length === 0 ? "pass" : "fail",
62
- detail: nodeModulesChanges.length === 0
63
- ? "No node_modules modifications."
64
- : `node_modules modified: ${nodeModulesChanges.join(", ")}`,
65
- reason_code: nodeModulesChanges.length > 0 ? "node_modules_modified" : undefined,
28
+ name: "diff_empty",
29
+ result: changedFilesTotal === 0 ? "warn" : "pass",
30
+ detail: changedFilesTotal === 0
31
+ ? "No file changes detected in this session."
32
+ : `${changedFilesTotal} file(s) changed.`,
33
+ reason_code: changedFilesTotal === 0 ? "empty_diff" : undefined,
66
34
  });
67
- // Check 6: release/dist modification
68
- const releaseChanges = findPathChanges(artifacts, "release");
69
- const distChanges = findPathChanges(artifacts, "dist");
70
- const artifactDirChanges = [...releaseChanges, ...distChanges];
71
- const hasBuildArtifacts = artifacts.artifact_hygiene.counts.tracked_build_artifacts > 0;
35
+ if (artifacts) {
36
+ // Check 3: out-of-scope changes
37
+ const outOfScope = findOutOfScopeChanges(artifacts, session.resolved_repo_path);
38
+ checks.push({
39
+ name: "out_of_scope_changes",
40
+ result: outOfScope.length === 0 ? "pass" : "fail",
41
+ detail: outOfScope.length === 0
42
+ ? "All changes are within the session repo_path."
43
+ : `${outOfScope.length} file(s) modified outside session repo_path: ${outOfScope.join(", ")}`,
44
+ reason_code: outOfScope.length > 0 ? "out_of_scope_changes" : undefined,
45
+ });
46
+ // Check 4: sensitive files
47
+ const sensitiveFiles = findSensitiveChanges(artifacts);
48
+ checks.push({
49
+ name: "sensitive_file_access",
50
+ result: sensitiveFiles.length === 0 ? "pass" : "fail",
51
+ detail: sensitiveFiles.length === 0
52
+ ? "No sensitive files modified."
53
+ : `Sensitive files modified: ${sensitiveFiles.join(", ")}`,
54
+ reason_code: sensitiveFiles.length > 0 ? "sensitive_file_modified" : undefined,
55
+ });
56
+ checks.push({
57
+ name: "sensitive_content",
58
+ result: artifacts.diff_redacted ? "fail" : "pass",
59
+ detail: artifacts.diff_redacted
60
+ ? `Credential-like content was redacted from diff evidence (${(artifacts.diff_redaction_categories ?? []).join(", ") || "sensitive_content"}).`
61
+ : "No credential-like content was detected in diff evidence.",
62
+ reason_code: artifacts.diff_redacted ? "sensitive_content_detected" : undefined,
63
+ });
64
+ // Check 5: node_modules modification
65
+ const nodeModulesChanges = findPathChanges(artifacts, "node_modules");
66
+ checks.push({
67
+ name: "node_modules_modified",
68
+ result: nodeModulesChanges.length === 0 ? "pass" : "fail",
69
+ detail: nodeModulesChanges.length === 0
70
+ ? "No node_modules modifications."
71
+ : `node_modules modified: ${nodeModulesChanges.join(", ")}`,
72
+ reason_code: nodeModulesChanges.length > 0 ? "node_modules_modified" : undefined,
73
+ });
74
+ // Check 6: release/dist modification
75
+ const releaseChanges = findPathChanges(artifacts, "release");
76
+ const distChanges = findPathChanges(artifacts, "dist");
77
+ const artifactDirChanges = [...releaseChanges, ...distChanges];
78
+ const hasBuildArtifacts = artifacts.artifact_hygiene.counts.tracked_build_artifacts > 0;
79
+ checks.push({
80
+ name: "release_dist_modified",
81
+ result: artifactDirChanges.length === 0
82
+ ? "pass"
83
+ : hasBuildArtifacts
84
+ ? "warn"
85
+ : "fail",
86
+ detail: artifactDirChanges.length === 0
87
+ ? "No release/dist modifications."
88
+ : `release/dist modified: ${artifactDirChanges.join(", ")}${hasBuildArtifacts ? " (build-generated)" : " (not build-generated)"}`,
89
+ reason_code: artifactDirChanges.length > 0
90
+ ? hasBuildArtifacts
91
+ ? "build_artifact_modified"
92
+ : "release_dist_manually_modified"
93
+ : undefined,
94
+ });
95
+ // Check 7: file deletion
96
+ const deletedFiles = artifacts.changed_files.filter((f) => f.change === "deleted");
97
+ checks.push({
98
+ name: "file_deletion",
99
+ result: deletedFiles.length === 0 ? "pass" : "fail",
100
+ detail: deletedFiles.length === 0
101
+ ? "No files deleted."
102
+ : `Files deleted: ${deletedFiles.map((f) => f.path).join(", ")}`,
103
+ reason_code: deletedFiles.length > 0 ? "file_deleted" : undefined,
104
+ });
105
+ // Check 8: file rename
106
+ const renamedFiles = artifacts.changed_files.filter((f) => f.change === "renamed");
107
+ checks.push({
108
+ name: "file_rename",
109
+ result: renamedFiles.length === 0 ? "pass" : "fail",
110
+ detail: renamedFiles.length === 0
111
+ ? "No files renamed."
112
+ : `Files renamed: ${renamedFiles.map((f) => `${f.old_path} → ${f.path}`).join(", ")}`,
113
+ reason_code: renamedFiles.length > 0 ? "file_renamed" : undefined,
114
+ });
115
+ // Check 9: package-lock / dependency changes
116
+ const packageLockChanges = artifacts.changed_files.filter((f) => f.path === "package-lock.json" ||
117
+ f.path === "package.json" ||
118
+ f.path === "yarn.lock" ||
119
+ f.path === "pnpm-lock.yaml");
120
+ checks.push({
121
+ name: "dependency_changes",
122
+ result: packageLockChanges.length === 0 ? "pass" : "warn",
123
+ detail: packageLockChanges.length === 0
124
+ ? "No dependency file changes."
125
+ : `Dependency files changed: ${packageLockChanges.map((f) => f.path).join(", ")}`,
126
+ reason_code: packageLockChanges.length > 0 ? "dependency_file_changed" : undefined,
127
+ });
128
+ // Check 13: title vs changed files consistency (warning only)
129
+ if (session.title && changedFilesTotal > 0) {
130
+ checks.push({
131
+ name: "title_change_consistency",
132
+ result: "pass",
133
+ detail: `Session title: "${session.title}", ${changedFilesTotal} file(s) changed. (Semantic check not performed - deterministic audit only.)`,
134
+ reason_code: undefined,
135
+ });
136
+ }
137
+ else {
138
+ checks.push({
139
+ name: "title_change_consistency",
140
+ result: "pass",
141
+ detail: "No title provided or no changes to compare.",
142
+ });
143
+ }
144
+ // Check 14: suspicious changes
145
+ const suspiciousCount = artifacts.artifact_hygiene.counts.suspicious_changes;
146
+ checks.push({
147
+ name: "suspicious_changes",
148
+ result: suspiciousCount === 0 ? "pass" : "warn",
149
+ detail: suspiciousCount === 0
150
+ ? "No suspicious changes detected."
151
+ : `${suspiciousCount} suspicious change(s) detected.`,
152
+ reason_code: suspiciousCount > 0 ? "suspicious_changes" : undefined,
153
+ });
154
+ // Check 15: runtime generated files
155
+ const runtimeCount = artifacts.artifact_hygiene.counts.runtime_generated_files;
156
+ checks.push({
157
+ name: "runtime_generated_files",
158
+ result: runtimeCount === 0 ? "pass" : "warn",
159
+ detail: runtimeCount === 0
160
+ ? "No runtime-generated files detected."
161
+ : `${runtimeCount} runtime-generated file(s) detected.`,
162
+ reason_code: runtimeCount > 0 ? "runtime_generated_files" : undefined,
163
+ });
164
+ // Check 16: tracked build artifacts
165
+ const buildArtifactCount = artifacts.artifact_hygiene.counts.tracked_build_artifacts;
166
+ checks.push({
167
+ name: "tracked_build_artifacts",
168
+ result: buildArtifactCount === 0 ? "pass" : "warn",
169
+ detail: buildArtifactCount === 0
170
+ ? "No tracked build artifacts detected."
171
+ : `${buildArtifactCount} tracked build artifact(s) detected.`,
172
+ reason_code: buildArtifactCount > 0 ? "tracked_build_artifacts" : undefined,
173
+ });
174
+ }
175
+ // Check 10: at least one verification command run
176
+ const verificationRuns = session.verification_runs || [];
177
+ const hasVerification = verificationRuns.length > 0;
178
+ const hasSourceChanges = artifacts
179
+ ? artifacts.changed_files.some((f) => f.kind === "source")
180
+ : false;
72
181
  checks.push({
73
- name: "release_dist_modified",
74
- result: artifactDirChanges.length === 0
182
+ name: "verification_run",
183
+ result: hasVerification
75
184
  ? "pass"
76
- : hasBuildArtifacts
77
- ? "warn"
78
- : "fail",
79
- detail: artifactDirChanges.length === 0
80
- ? "No release/dist modifications."
81
- : `release/dist modified: ${artifactDirChanges.join(", ")}${hasBuildArtifacts ? " (build-generated)" : " (not build-generated)"}`,
82
- reason_code: artifactDirChanges.length > 0
83
- ? hasBuildArtifacts
84
- ? "build_artifact_modified"
85
- : "release_dist_manually_modified"
185
+ : hasSourceChanges
186
+ ? "fail"
187
+ : "warn",
188
+ detail: hasVerification
189
+ ? `${verificationRuns.length} verification command(s) run.`
190
+ : hasSourceChanges
191
+ ? "Source files were modified but no verification commands were run."
192
+ : "No verification commands were run (no source changes detected).",
193
+ reason_code: !hasVerification
194
+ ? hasSourceChanges
195
+ ? "source_changes_without_verification"
196
+ : "no_verification_run"
86
197
  : undefined,
87
198
  });
88
- // Check 7: file deletion
89
- const deletedFiles = artifacts.changed_files.filter((f) => f.change === "deleted");
90
- checks.push({
91
- name: "file_deletion",
92
- result: deletedFiles.length === 0 ? "pass" : "fail",
93
- detail: deletedFiles.length === 0
94
- ? "No files deleted."
95
- : `Files deleted: ${deletedFiles.map((f) => f.path).join(", ")}`,
96
- reason_code: deletedFiles.length > 0 ? "file_deleted" : undefined,
97
- });
98
- // Check 8: file rename
99
- const renamedFiles = artifacts.changed_files.filter((f) => f.change === "renamed");
100
- checks.push({
101
- name: "file_rename",
102
- result: renamedFiles.length === 0 ? "pass" : "fail",
103
- detail: renamedFiles.length === 0
104
- ? "No files renamed."
105
- : `Files renamed: ${renamedFiles.map((f) => `${f.old_path} → ${f.path}`).join(", ")}`,
106
- reason_code: renamedFiles.length > 0 ? "file_renamed" : undefined,
107
- });
108
- // Check 9: package-lock / dependency changes
109
- const packageLockChanges = artifacts.changed_files.filter((f) => f.path === "package-lock.json" ||
110
- f.path === "package.json" ||
111
- f.path === "yarn.lock" ||
112
- f.path === "pnpm-lock.yaml");
113
- checks.push({
114
- name: "dependency_changes",
115
- result: packageLockChanges.length === 0 ? "pass" : "warn",
116
- detail: packageLockChanges.length === 0
117
- ? "No dependency file changes."
118
- : `Dependency files changed: ${packageLockChanges.map((f) => f.path).join(", ")}`,
119
- reason_code: packageLockChanges.length > 0 ? "dependency_file_changed" : undefined,
120
- });
121
- // Check 13: title vs changed files consistency (warning only)
122
- if (session.title && changedFilesTotal > 0) {
199
+ // Check 11: verification commands passed
200
+ if (hasVerification) {
201
+ const allPassed = verificationRuns.every((r) => r.passed);
123
202
  checks.push({
124
- name: "title_change_consistency",
125
- result: "pass",
126
- detail: `Session title: "${session.title}", ${changedFilesTotal} file(s) changed. (Semantic check not performed - deterministic audit only.)`,
127
- reason_code: undefined,
203
+ name: "verification_passed",
204
+ result: allPassed ? "pass" : "fail",
205
+ detail: allPassed
206
+ ? "All verification commands passed."
207
+ : `${verificationRuns.filter((r) => !r.passed).length} verification command(s) failed.`,
208
+ reason_code: !allPassed ? "verification_failed" : undefined,
128
209
  });
129
210
  }
130
- else {
131
- checks.push({
132
- name: "title_change_consistency",
133
- result: "pass",
134
- detail: "No title provided or no changes to compare.",
135
- });
211
+ // Collect results
212
+ for (const check of checks) {
213
+ if (check.reason_code)
214
+ reasonCodes.push(check.reason_code);
215
+ if (check.result === "fail")
216
+ blockingFindings.push(`${check.name}: ${check.detail}`);
217
+ if (check.result === "warn")
218
+ warnings.push(`${check.name}: ${check.detail}`);
136
219
  }
137
- // Check 14: suspicious changes
138
- const suspiciousCount = artifacts.artifact_hygiene.counts.suspicious_changes;
139
- checks.push({
140
- name: "suspicious_changes",
141
- result: suspiciousCount === 0 ? "pass" : "warn",
142
- detail: suspiciousCount === 0
143
- ? "No suspicious changes detected."
144
- : `${suspiciousCount} suspicious change(s) detected.`,
145
- reason_code: suspiciousCount > 0 ? "suspicious_changes" : undefined,
146
- });
147
- // Check 15: runtime generated files
148
- const runtimeCount = artifacts.artifact_hygiene.counts.runtime_generated_files;
149
- checks.push({
150
- name: "runtime_generated_files",
151
- result: runtimeCount === 0 ? "pass" : "warn",
152
- detail: runtimeCount === 0
153
- ? "No runtime-generated files detected."
154
- : `${runtimeCount} runtime-generated file(s) detected.`,
155
- reason_code: runtimeCount > 0 ? "runtime_generated_files" : undefined,
156
- });
157
- // Check 16: tracked build artifacts
158
- const buildArtifactCount = artifacts.artifact_hygiene.counts.tracked_build_artifacts;
159
- checks.push({
160
- name: "tracked_build_artifacts",
161
- result: buildArtifactCount === 0 ? "pass" : "warn",
162
- detail: buildArtifactCount === 0
163
- ? "No tracked build artifacts detected."
164
- : `${buildArtifactCount} tracked build artifact(s) detected.`,
165
- reason_code: buildArtifactCount > 0 ? "tracked_build_artifacts" : undefined,
166
- });
167
- }
168
- // Check 10: at least one verification command run
169
- const verificationRuns = session.verification_runs || [];
170
- const hasVerification = verificationRuns.length > 0;
171
- const hasSourceChanges = artifacts
172
- ? artifacts.changed_files.some((f) => f.kind === "source")
173
- : false;
174
- checks.push({
175
- name: "verification_run",
176
- result: hasVerification
177
- ? "pass"
178
- : hasSourceChanges
179
- ? "fail"
180
- : "warn",
181
- detail: hasVerification
182
- ? `${verificationRuns.length} verification command(s) run.`
183
- : hasSourceChanges
184
- ? "Source files were modified but no verification commands were run."
185
- : "No verification commands were run (no source changes detected).",
186
- reason_code: !hasVerification
187
- ? hasSourceChanges
188
- ? "source_changes_without_verification"
189
- : "no_verification_run"
190
- : undefined,
220
+ // Determine decision
221
+ const hasFail = checks.some((c) => c.result === "fail");
222
+ const hasWarn = checks.some((c) => c.result === "warn");
223
+ const decision = hasFail ? "fail" : hasWarn ? "warn" : "pass";
224
+ const diffPath = join(sessionDir, "diff.patch");
225
+ const summaryPath = join(sessionDir, "summary.md");
226
+ const auditPath = join(sessionDir, "audit.md");
227
+ const output = {
228
+ session_id: sessionId,
229
+ decision,
230
+ reason_codes: reasonCodes,
231
+ blocking_findings: blockingFindings,
232
+ warnings,
233
+ evidence: {
234
+ changed_files_total: changedFilesTotal,
235
+ verification_runs: verificationRuns,
236
+ diff_path: diffPath,
237
+ summary_path: summaryPath,
238
+ audit_path: auditPath,
239
+ },
240
+ next_action: decision === "pass"
241
+ ? "Audit passed. Changes are safe to accept."
242
+ : decision === "warn"
243
+ ? "Audit completed with warnings. Review the warnings before accepting changes."
244
+ : "Audit failed. Review the blocking findings and create a new session to fix issues.",
245
+ };
246
+ // Write audit.json and audit.md
247
+ atomicWriteJsonFileSync(join(sessionDir, "audit.json"), output);
248
+ atomicWriteFileSync(auditPath, formatAuditMd(output, checks, session));
249
+ updateDirectSession(sessionId, { audited: true });
250
+ return output;
191
251
  });
192
- // Check 11: verification commands passed
193
- if (hasVerification) {
194
- const allPassed = verificationRuns.every((r) => r.passed);
195
- checks.push({
196
- name: "verification_passed",
197
- result: allPassed ? "pass" : "fail",
198
- detail: allPassed
199
- ? "All verification commands passed."
200
- : `${verificationRuns.filter((r) => !r.passed).length} verification command(s) failed.`,
201
- reason_code: !allPassed ? "verification_failed" : undefined,
202
- });
203
- }
204
- // Collect results
205
- for (const check of checks) {
206
- if (check.reason_code)
207
- reasonCodes.push(check.reason_code);
208
- if (check.result === "fail")
209
- blockingFindings.push(`${check.name}: ${check.detail}`);
210
- if (check.result === "warn")
211
- warnings.push(`${check.name}: ${check.detail}`);
212
- }
213
- // Determine decision
214
- const hasFail = checks.some((c) => c.result === "fail");
215
- const hasWarn = checks.some((c) => c.result === "warn");
216
- const decision = hasFail ? "fail" : hasWarn ? "warn" : "pass";
217
- const diffPath = join(sessionDir, "diff.patch");
218
- const summaryPath = join(sessionDir, "summary.md");
219
- const auditPath = join(sessionDir, "audit.md");
220
- const output = {
221
- session_id: sessionId,
222
- decision,
223
- reason_codes: reasonCodes,
224
- blocking_findings: blockingFindings,
225
- warnings,
226
- evidence: {
227
- changed_files_total: changedFilesTotal,
228
- verification_runs: verificationRuns,
229
- diff_path: diffPath,
230
- summary_path: summaryPath,
231
- audit_path: auditPath,
232
- },
233
- next_action: decision === "pass"
234
- ? "Audit passed. Changes are safe to accept."
235
- : decision === "warn"
236
- ? "Audit completed with warnings. Review the warnings before accepting changes."
237
- : "Audit failed. Review the blocking findings and create a new session to fix issues.",
238
- };
239
- // Write audit.json and audit.md
240
- writeFileSync(join(sessionDir, "audit.json"), JSON.stringify(output, null, 2), "utf-8");
241
- writeFileSync(auditPath, formatAuditMd(output, checks, session), "utf-8");
242
- return output;
243
252
  }
244
253
  // ── Helper functions ───────────────────────────────────────────────
245
254
  function findOutOfScopeChanges(artifacts, resolvedRepoPath) {
@@ -1,3 +1,4 @@
1
+ import { type PatchWardenConfig } from "../config.js";
1
2
  import type { DirectSessionRecord } from "./directSessionStore.js";
2
3
  export declare function guardDirectSessionActive(session: DirectSessionRecord): void;
3
4
  export declare function guardDirectSessionFinalized(session: DirectSessionRecord): void;
@@ -16,5 +17,5 @@ export declare function guardDirectReadPath(filePath: string, resolvedRepoPath:
16
17
  */
17
18
  export declare function guardDirectWritePath(filePath: string, resolvedRepoPath: string, workspaceRoot: string): string;
18
19
  export declare function guardDirectPatchSize(patchBytes: number): void;
19
- export declare function guardDirectFileSize(fileBytes: number): void;
20
+ export declare function guardDirectFileSize(fileBytes: number, config?: PatchWardenConfig): void;
20
21
  export declare function isBinaryFile(filePath: string): boolean;