@karajan-family/code 4.21.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 (746) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +98 -0
  3. package/bin/karajan-mcp.js +2 -0
  4. package/bin/kj-rag-mcp.js +75 -0
  5. package/bin/kj-tail +361 -0
  6. package/bin/kj.js +2 -0
  7. package/docs/README.es.md +80 -0
  8. package/docs/karajan-code-logo-small.png +0 -0
  9. package/library/logical-clocks-lamport.md +40 -0
  10. package/package.json +140 -0
  11. package/packages/ai-trash/README.md +37 -0
  12. package/packages/ai-trash/bin/kj-trash.js +10 -0
  13. package/packages/ai-trash/package.json +43 -0
  14. package/packages/ai-trash/src/cli.js +200 -0
  15. package/packages/ai-trash/src/destructive-parser.js +74 -0
  16. package/packages/ai-trash/src/git-snapshot.js +128 -0
  17. package/packages/ai-trash/src/hook.js +137 -0
  18. package/packages/ai-trash/src/index.js +14 -0
  19. package/packages/ai-trash/src/install.js +73 -0
  20. package/packages/ai-trash/src/logger.js +60 -0
  21. package/packages/ai-trash/src/manifest.js +91 -0
  22. package/packages/ai-trash/src/permissions.js +26 -0
  23. package/packages/ai-trash/src/snapshot.js +66 -0
  24. package/packages/ai-trash/src/ulid.js +66 -0
  25. package/packages/hu-board/README.md +69 -0
  26. package/packages/hu-board/package.json +28 -0
  27. package/packages/hu-board/public/app.js +259 -0
  28. package/packages/hu-board/public/index.html +77 -0
  29. package/packages/hu-board/public/pipeline.css +132 -0
  30. package/packages/hu-board/public/pipeline.html +48 -0
  31. package/packages/hu-board/public/pipeline.js +200 -0
  32. package/packages/hu-board/public/rag.html +21 -0
  33. package/packages/hu-board/public/rag.js +39 -0
  34. package/packages/hu-board/public/styles.css +973 -0
  35. package/packages/hu-board/public/utils/api.js +139 -0
  36. package/packages/hu-board/public/utils/board-view.js +473 -0
  37. package/packages/hu-board/public/utils/command-launcher.js +213 -0
  38. package/packages/hu-board/public/utils/config-editor.js +181 -0
  39. package/packages/hu-board/public/utils/dashboard-view.js +103 -0
  40. package/packages/hu-board/public/utils/formatters.js +300 -0
  41. package/packages/hu-board/public/utils/graph-view.js +216 -0
  42. package/packages/hu-board/public/utils/hu-actions.js +224 -0
  43. package/packages/hu-board/public/utils/init-listeners.js +180 -0
  44. package/packages/hu-board/public/utils/log-panel.js +222 -0
  45. package/packages/hu-board/public/utils/modals.js +309 -0
  46. package/packages/hu-board/public/utils/plan-rollup-view.js +53 -0
  47. package/packages/hu-board/public/utils/preflight-view.js +89 -0
  48. package/packages/hu-board/public/utils/project-actions.js +143 -0
  49. package/packages/hu-board/public/utils/project-picker-view.js +139 -0
  50. package/packages/hu-board/public/utils/run-launcher.js +169 -0
  51. package/packages/hu-board/public/utils/server-push.js +252 -0
  52. package/packages/hu-board/public/utils/sessions-view.js +199 -0
  53. package/packages/hu-board/public/utils/story-detail-view.js +324 -0
  54. package/packages/hu-board/public/utils/story-edit-form.js +271 -0
  55. package/packages/hu-board/public/wiki.html +32 -0
  56. package/packages/hu-board/public/wiki.js +53 -0
  57. package/packages/hu-board/src/auth.js +92 -0
  58. package/packages/hu-board/src/boot-info.js +16 -0
  59. package/packages/hu-board/src/cleanup-zombies.js +145 -0
  60. package/packages/hu-board/src/command-runner.js +133 -0
  61. package/packages/hu-board/src/config-yaml.js +531 -0
  62. package/packages/hu-board/src/db.js +963 -0
  63. package/packages/hu-board/src/ephemeral-cleaner.js +196 -0
  64. package/packages/hu-board/src/event-bus.js +58 -0
  65. package/packages/hu-board/src/format.js +207 -0
  66. package/packages/hu-board/src/hu-zombie-reaper.js +103 -0
  67. package/packages/hu-board/src/journal-parser.js +180 -0
  68. package/packages/hu-board/src/plan-mutations.js +424 -0
  69. package/packages/hu-board/src/preflight.js +286 -0
  70. package/packages/hu-board/src/routes/api.js +1374 -0
  71. package/packages/hu-board/src/routes/pipeline.js +45 -0
  72. package/packages/hu-board/src/routes/rag.js +42 -0
  73. package/packages/hu-board/src/routes/wiki.js +43 -0
  74. package/packages/hu-board/src/run-tracker.js +121 -0
  75. package/packages/hu-board/src/server.js +438 -0
  76. package/packages/hu-board/src/sync.js +732 -0
  77. package/packages/hu-board/src/token-store.js +56 -0
  78. package/packages/hu-board/src/zombie-reaper.js +206 -0
  79. package/scripts/ai-attribution-guard.yml +84 -0
  80. package/scripts/audit-test-diet.mjs +151 -0
  81. package/scripts/build-sea.mjs +150 -0
  82. package/scripts/diet-baseline.mjs +170 -0
  83. package/scripts/dual-publish.mjs +67 -0
  84. package/scripts/esbuild-sea.config.mjs +273 -0
  85. package/scripts/git-hooks/post-merge +18 -0
  86. package/scripts/install-binary.ps1 +174 -0
  87. package/scripts/install-binary.sh +159 -0
  88. package/scripts/install-guard-all-repos.sh +85 -0
  89. package/scripts/install-kj.sh +193 -0
  90. package/scripts/install.js +901 -0
  91. package/scripts/install.sh +7 -0
  92. package/scripts/postinstall.js +117 -0
  93. package/scripts/protect-all-repos.sh +88 -0
  94. package/scripts/quickstart-gate.mjs +97 -0
  95. package/scripts/regen-arch-stats.sh +71 -0
  96. package/scripts/setup-multi-instance.sh +150 -0
  97. package/scripts/verify-pack.mjs +278 -0
  98. package/src/activity-log.js +59 -0
  99. package/src/agents/agy-agent.js +62 -0
  100. package/src/agents/aider-agent.js +78 -0
  101. package/src/agents/availability.js +52 -0
  102. package/src/agents/base-agent.js +134 -0
  103. package/src/agents/claude-agent.js +413 -0
  104. package/src/agents/codex-agent.js +112 -0
  105. package/src/agents/copilot-agent.js +65 -0
  106. package/src/agents/gemini-agent.js +85 -0
  107. package/src/agents/host-agent.js +38 -0
  108. package/src/agents/index.js +59 -0
  109. package/src/agents/kimi-agent.js +45 -0
  110. package/src/agents/model-registry.js +137 -0
  111. package/src/agents/opencode-agent.js +72 -0
  112. package/src/agents/qwen-agent.js +20 -0
  113. package/src/agents/resolve-bin.js +73 -0
  114. package/src/audit/agent-readiness.js +259 -0
  115. package/src/audit/ai-slop-findings.js +102 -0
  116. package/src/audit/audit-fallback.js +66 -0
  117. package/src/audit/audit-history-display.js +61 -0
  118. package/src/audit/audit-history.js +102 -0
  119. package/src/audit/basal-cost.js +281 -0
  120. package/src/audit/circular-deps.js +144 -0
  121. package/src/audit/dead-exports.js +186 -0
  122. package/src/audit/deterministic-summary.js +327 -0
  123. package/src/audit/harness-scorecard.js +100 -0
  124. package/src/audit/harness-section.js +81 -0
  125. package/src/audit/infra-findings.js +100 -0
  126. package/src/audit/injection-findings.js +114 -0
  127. package/src/audit/issue-filter.js +133 -0
  128. package/src/audit/osv-findings.js +167 -0
  129. package/src/audit/plan-adherence.js +224 -0
  130. package/src/audit/semgrep-findings.js +129 -0
  131. package/src/audit/sonar-findings.js +93 -0
  132. package/src/audit/webperf-input.js +133 -0
  133. package/src/autonomy/arbiter-role.js +71 -0
  134. package/src/autonomy/arbiter.js +22 -0
  135. package/src/autonomy/decider.js +18 -0
  136. package/src/autonomy/decision-resolver.js +58 -0
  137. package/src/autonomy/outcome-report.js +55 -0
  138. package/src/autonomy/policy.js +41 -0
  139. package/src/autonomy/stage-ask.js +30 -0
  140. package/src/bootstrap.js +276 -0
  141. package/src/brain/agent-error-classifier.js +116 -0
  142. package/src/brain/decision-tracker.js +125 -0
  143. package/src/brain/decisor.js +243 -0
  144. package/src/brain/solomon-consult.js +171 -0
  145. package/src/brain/standby-scheduler.js +8 -0
  146. package/src/brain/standby-store.js +12 -0
  147. package/src/brain/with-brain-recovery.js +235 -0
  148. package/src/budget/comparison.js +96 -0
  149. package/src/canvas/parse-md.js +238 -0
  150. package/src/canvas/schema.js +101 -0
  151. package/src/canvas/to-flat.js +85 -0
  152. package/src/canvas/validate.js +163 -0
  153. package/src/checks/ai-surface.js +79 -0
  154. package/src/checks/ai-trash.js +34 -0
  155. package/src/checks/binaries.js +207 -0
  156. package/src/checks/ci.js +105 -0
  157. package/src/checks/config-files.js +217 -0
  158. package/src/checks/dir-setup.js +103 -0
  159. package/src/checks/guarantee-level.js +38 -0
  160. package/src/checks/hardware.js +150 -0
  161. package/src/checks/harness-scorecard.js +41 -0
  162. package/src/checks/mcp-health.js +169 -0
  163. package/src/checks/method.js +73 -0
  164. package/src/checks/native-build.js +67 -0
  165. package/src/checks/node.js +70 -0
  166. package/src/checks/ollama.js +41 -0
  167. package/src/checks/orphans.js +77 -0
  168. package/src/checks/ports.js +188 -0
  169. package/src/checks/project-checks.js +245 -0
  170. package/src/checks/qmd.js +41 -0
  171. package/src/checks/rag-hooks.js +54 -0
  172. package/src/checks/release-check.js +102 -0
  173. package/src/checks/rtk.js +36 -0
  174. package/src/checks/runner.js +326 -0
  175. package/src/checks/skills.js +53 -0
  176. package/src/checks/sonar.js +67 -0
  177. package/src/checks/squeezr.js +36 -0
  178. package/src/checks/system.js +53 -0
  179. package/src/checks/tokens.js +172 -0
  180. package/src/checks/types.js +103 -0
  181. package/src/ci/dispatch.js +99 -0
  182. package/src/ci/index.js +3 -0
  183. package/src/ci/pr-diff.js +26 -0
  184. package/src/ci/repo.js +45 -0
  185. package/src/cli/_shared.js +30 -0
  186. package/src/cli/advanced-commands.js +61 -0
  187. package/src/cli/register-meta.js +772 -0
  188. package/src/cli/register-pipeline.js +335 -0
  189. package/src/cli/register-plan.js +224 -0
  190. package/src/cli/register-roles-skills.js +54 -0
  191. package/src/cli/register-sonar.js +28 -0
  192. package/src/cli/register-standby.js +26 -0
  193. package/src/cli.js +155 -0
  194. package/src/commands/advanced.js +31 -0
  195. package/src/commands/agent-run.js +63 -0
  196. package/src/commands/agents.js +105 -0
  197. package/src/commands/architect.js +123 -0
  198. package/src/commands/audit.js +430 -0
  199. package/src/commands/autorun.js +49 -0
  200. package/src/commands/board.js +458 -0
  201. package/src/commands/check.js +40 -0
  202. package/src/commands/clean.js +145 -0
  203. package/src/commands/code.js +45 -0
  204. package/src/commands/config.js +74 -0
  205. package/src/commands/discover.js +105 -0
  206. package/src/commands/doctor.js +251 -0
  207. package/src/commands/env.js +207 -0
  208. package/src/commands/harden.js +203 -0
  209. package/src/commands/hu.js +210 -0
  210. package/src/commands/identity.js +60 -0
  211. package/src/commands/init.js +950 -0
  212. package/src/commands/install-tools.js +432 -0
  213. package/src/commands/mutate.js +94 -0
  214. package/src/commands/ollama.js +44 -0
  215. package/src/commands/onboard.js +45 -0
  216. package/src/commands/plan/_shared.js +55 -0
  217. package/src/commands/plan/add-hu.js +23 -0
  218. package/src/commands/plan/delete.js +9 -0
  219. package/src/commands/plan/fix.js +99 -0
  220. package/src/commands/plan/generate.js +532 -0
  221. package/src/commands/plan/index.js +13 -0
  222. package/src/commands/plan/list.js +21 -0
  223. package/src/commands/plan/migrate-result.js +41 -0
  224. package/src/commands/plan/ready.js +46 -0
  225. package/src/commands/plan/remove-hu.js +17 -0
  226. package/src/commands/plan/share.js +85 -0
  227. package/src/commands/plan/show.js +81 -0
  228. package/src/commands/plan/unshare.js +41 -0
  229. package/src/commands/plan/validate.js +20 -0
  230. package/src/commands/plan.js +17 -0
  231. package/src/commands/policy.js +164 -0
  232. package/src/commands/privacy.js +45 -0
  233. package/src/commands/qmd.js +86 -0
  234. package/src/commands/rag-mcp.js +18 -0
  235. package/src/commands/rag.js +173 -0
  236. package/src/commands/report-issue.js +77 -0
  237. package/src/commands/report.js +469 -0
  238. package/src/commands/researcher.js +54 -0
  239. package/src/commands/resume.js +68 -0
  240. package/src/commands/review-gate.js +355 -0
  241. package/src/commands/review.js +89 -0
  242. package/src/commands/roles.js +116 -0
  243. package/src/commands/run.js +185 -0
  244. package/src/commands/scan.js +18 -0
  245. package/src/commands/skills.js +86 -0
  246. package/src/commands/sonar.js +53 -0
  247. package/src/commands/standby.js +117 -0
  248. package/src/commands/start.js +121 -0
  249. package/src/commands/status.js +36 -0
  250. package/src/commands/sync.js +103 -0
  251. package/src/commands/telemetry.js +70 -0
  252. package/src/commands/tournament.js +85 -0
  253. package/src/commands/triage.js +78 -0
  254. package/src/commands/undo.js +62 -0
  255. package/src/commands/watch.js +46 -0
  256. package/src/commands/webperf.js +162 -0
  257. package/src/commands/worktree.js +76 -0
  258. package/src/config/defaults.js +270 -0
  259. package/src/config/loader.js +204 -0
  260. package/src/config/overrides.js +220 -0
  261. package/src/config/role-resolver.js +171 -0
  262. package/src/config/schema.js +299 -0
  263. package/src/config/test-harness.js +78 -0
  264. package/src/config.js +34 -0
  265. package/src/domains/domain-loader.js +245 -0
  266. package/src/domains/domain-registry.js +140 -0
  267. package/src/domains/domain-synthesizer.js +129 -0
  268. package/src/environment/adr.js +45 -0
  269. package/src/environment/board-access.js +97 -0
  270. package/src/environment/board-select.js +59 -0
  271. package/src/environment/briefs.js +129 -0
  272. package/src/environment/issue-report.js +72 -0
  273. package/src/environment/mcp-wiring.js +44 -0
  274. package/src/environment/playbook.js +127 -0
  275. package/src/git/automation.js +334 -0
  276. package/src/git/hu-automation.js +171 -0
  277. package/src/git/hu-snapshot.js +10 -0
  278. package/src/golden/asserter.js +92 -0
  279. package/src/golden/loader.js +52 -0
  280. package/src/golden/runner.js +92 -0
  281. package/src/golden/schema.js +41 -0
  282. package/src/guards/intent-guard.js +161 -0
  283. package/src/guards/output-guard.js +149 -0
  284. package/src/guards/perf-guard.js +126 -0
  285. package/src/guards/policy-guard.js +90 -0
  286. package/src/guards/policy-resolver.js +85 -0
  287. package/src/guards/secret-redactor.js +71 -0
  288. package/src/harden/advisory.js +203 -0
  289. package/src/harden/alternatives.js +50 -0
  290. package/src/harden/check.js +81 -0
  291. package/src/harden/config-engine.js +128 -0
  292. package/src/harden/config-templates.js +122 -0
  293. package/src/harden/guidelines-engine.js +48 -0
  294. package/src/harden/guidelines-templates.js +36 -0
  295. package/src/harden/harden-engine.js +80 -0
  296. package/src/harden/harness-hooks.js +107 -0
  297. package/src/harden/hook-commands.js +25 -0
  298. package/src/harden/hook-templates.js +183 -0
  299. package/src/harden/interactive.js +76 -0
  300. package/src/harden/sentinel-hooks.js +721 -0
  301. package/src/harden/stack-roots.js +105 -0
  302. package/src/harden/test-on-push.js +38 -0
  303. package/src/harden/workflow-engine.js +116 -0
  304. package/src/harden/workflow-templates.js +285 -0
  305. package/src/hu/acceptance-runner.js +138 -0
  306. package/src/hu/auto-generator.js +358 -0
  307. package/src/hu/graph.js +71 -0
  308. package/src/hu/lazy-planner.js +109 -0
  309. package/src/hu/model-router.js +108 -0
  310. package/src/hu/parallel-executor.js +94 -0
  311. package/src/hu/split-validator.js +143 -0
  312. package/src/hu/splitting-detector.js +158 -0
  313. package/src/hu/splitting-generator.js +175 -0
  314. package/src/hu/store.js +392 -0
  315. package/src/hu/worktree-bootstrap.js +59 -0
  316. package/src/identity/bootstrap.js +48 -0
  317. package/src/identity/compare.js +38 -0
  318. package/src/identity/detect.js +51 -0
  319. package/src/identity/store.js +66 -0
  320. package/src/infrastructure/command-runner.js +44 -0
  321. package/src/infrastructure/environment.js +38 -0
  322. package/src/infrastructure/file-system-service.js +63 -0
  323. package/src/infrastructure/mocks.js +182 -0
  324. package/src/lang/chunk-go.js +94 -0
  325. package/src/lang/chunk-java.js +90 -0
  326. package/src/lang/chunk-python.js +88 -0
  327. package/src/lang/chunk-rust.js +102 -0
  328. package/src/lang/go.js +14 -0
  329. package/src/lang/java.js +16 -0
  330. package/src/lang/js.js +8 -0
  331. package/src/lang/python.js +14 -0
  332. package/src/lang/registry.js +79 -0
  333. package/src/lang/rust.js +14 -0
  334. package/src/lang/tree-sitter-loader.js +45 -0
  335. package/src/mcp/direct-role-runner.js +112 -0
  336. package/src/mcp/error-classifiers.js +66 -0
  337. package/src/mcp/handlers/direct-handlers.js +486 -0
  338. package/src/mcp/handlers/hu-handlers.js +93 -0
  339. package/src/mcp/handlers/management-handlers.js +265 -0
  340. package/src/mcp/handlers/rag-handler.js +52 -0
  341. package/src/mcp/handlers/run-handler.js +313 -0
  342. package/src/mcp/orphan-guard.js +131 -0
  343. package/src/mcp/preflight.js +47 -0
  344. package/src/mcp/progress.js +149 -0
  345. package/src/mcp/response-compressor.js +81 -0
  346. package/src/mcp/run-kj.js +135 -0
  347. package/src/mcp/server-handlers.js +79 -0
  348. package/src/mcp/server.js +66 -0
  349. package/src/mcp/shared-helpers.js +297 -0
  350. package/src/mcp/sovereignty-guard.js +112 -0
  351. package/src/mcp/suggest-handler.js +92 -0
  352. package/src/mcp/tool-arg-normalizers.js +16 -0
  353. package/src/mcp/tools.js +432 -0
  354. package/src/mutate/diff-scope.js +105 -0
  355. package/src/mutate/reviewer-signal.js +76 -0
  356. package/src/mutate/runner.js +72 -0
  357. package/src/mutate/tool-registry.js +90 -0
  358. package/src/onboarder/cache.js +24 -0
  359. package/src/onboarder/collectors/framework-multilang.js +64 -0
  360. package/src/onboarder/collectors/index.js +136 -0
  361. package/src/orchestrator/agent-fallback.js +81 -0
  362. package/src/orchestrator/brain-coordinator.js +186 -0
  363. package/src/orchestrator/ci-integration.js +139 -0
  364. package/src/orchestrator/config-init.js +510 -0
  365. package/src/orchestrator/direct-actions.js +217 -0
  366. package/src/orchestrator/drivers/error-recovery.js +287 -0
  367. package/src/orchestrator/drivers/init-context.js +227 -0
  368. package/src/orchestrator/drivers/iteration-loop.js +380 -0
  369. package/src/orchestrator/drivers/iteration-phases/coder-and-refactorer.js +69 -0
  370. package/src/orchestrator/drivers/iteration-phases/guards.js +84 -0
  371. package/src/orchestrator/drivers/iteration-phases/handle-approved.js +29 -0
  372. package/src/orchestrator/drivers/iteration-phases/quality-gates.js +114 -0
  373. package/src/orchestrator/drivers/iteration-phases/reviewer-gate.js +60 -0
  374. package/src/orchestrator/drivers/post-loop.js +383 -0
  375. package/src/orchestrator/drivers/pre-loop-phases/auto-hu-batch.js +136 -0
  376. package/src/orchestrator/drivers/pre-loop-phases/config-deprecations.js +47 -0
  377. package/src/orchestrator/drivers/pre-loop-phases/ensure-addyosmani-skills.js +84 -0
  378. package/src/orchestrator/drivers/pre-loop-phases/inject-loaded-plan.js +391 -0
  379. package/src/orchestrator/drivers/pre-loop.js +507 -0
  380. package/src/orchestrator/drivers/run-hu-batch.js +427 -0
  381. package/src/orchestrator/feedback-enrichment.js +140 -0
  382. package/src/orchestrator/feedback-queue.js +151 -0
  383. package/src/orchestrator/flow-control.js +170 -0
  384. package/src/orchestrator/flow-runner.js +364 -0
  385. package/src/orchestrator/fs-leak-detector.js +210 -0
  386. package/src/orchestrator/hu-scheduler.js +114 -0
  387. package/src/orchestrator/hu-sub-pipeline.js +616 -0
  388. package/src/orchestrator/integrations.js +81 -0
  389. package/src/orchestrator/iteration-gate.js +73 -0
  390. package/src/orchestrator/iteration-stages.js +9 -0
  391. package/src/orchestrator/parallel-limiter.js +74 -0
  392. package/src/orchestrator/pipeline-context.js +72 -0
  393. package/src/orchestrator/post-loop-stages.js +468 -0
  394. package/src/orchestrator/pre-loop-stages.js +11 -0
  395. package/src/orchestrator/preflight-checks.js +462 -0
  396. package/src/orchestrator/repair/repair-detector.js +117 -0
  397. package/src/orchestrator/repair/repair-runner.js +142 -0
  398. package/src/orchestrator/reviewer-fallback.js +45 -0
  399. package/src/orchestrator/role-output-compressor.js +189 -0
  400. package/src/orchestrator/session-journal.js +308 -0
  401. package/src/orchestrator/solomon-escalation.js +305 -0
  402. package/src/orchestrator/solomon-rules.js +212 -0
  403. package/src/orchestrator/stages/architect-stage.js +172 -0
  404. package/src/orchestrator/stages/coder-stage.js +480 -0
  405. package/src/orchestrator/stages/domain-curator-stage.js +82 -0
  406. package/src/orchestrator/stages/hu-reviewer-phases/detect-and-apply-splits.js +127 -0
  407. package/src/orchestrator/stages/hu-reviewer-stage.js +394 -0
  408. package/src/orchestrator/stages/perf-stage.js +140 -0
  409. package/src/orchestrator/stages/planner-stage.js +85 -0
  410. package/src/orchestrator/stages/rag-context-stage.js +77 -0
  411. package/src/orchestrator/stages/rag-preload-decisor.js +58 -0
  412. package/src/orchestrator/stages/research-stage.js +69 -0
  413. package/src/orchestrator/stages/reviewer-stage.js +422 -0
  414. package/src/orchestrator/stages/sonar-stage.js +421 -0
  415. package/src/orchestrator/stages/stage-classes.js +84 -0
  416. package/src/orchestrator/stages/stage-executor.js +155 -0
  417. package/src/orchestrator/stages/tdd-discipline-stage.js +56 -0
  418. package/src/orchestrator/stages/tool-judge-stage.js +53 -0
  419. package/src/orchestrator/stages/triage-stage.js +172 -0
  420. package/src/orchestrator/standby.js +71 -0
  421. package/src/orchestrator/verification-gate.js +183 -0
  422. package/src/orchestrator.js +22 -0
  423. package/src/plan/adr-generator.js +170 -0
  424. package/src/plan/adr-loader.js +60 -0
  425. package/src/plan/plan-executor.js +100 -0
  426. package/src/plan/plan-fixer.js +192 -0
  427. package/src/plan/plan-hu-ops.js +16 -0
  428. package/src/plan/plan-id.js +4 -0
  429. package/src/plan/plan-migrate-result.js +24 -0
  430. package/src/plan/plan-reviewer.js +236 -0
  431. package/src/plan/plan-schema.js +334 -0
  432. package/src/plan/plan-store.js +260 -0
  433. package/src/plan/plan-structural-pass.js +122 -0
  434. package/src/plan/plan-validation.js +4 -0
  435. package/src/plan/preflight-hu.js +105 -0
  436. package/src/plan/spec-detector.js +61 -0
  437. package/src/plan/tests-synthesizer.js +131 -0
  438. package/src/planning-game/adapter.js +108 -0
  439. package/src/planning-game/architect-adrs.js +45 -0
  440. package/src/planning-game/client.js +108 -0
  441. package/src/planning-game/decomposition.js +87 -0
  442. package/src/planning-game/pipeline-adapter.js +251 -0
  443. package/src/plugins/loader.js +67 -0
  444. package/src/policy/add.js +111 -0
  445. package/src/policy/decisions.js +42 -0
  446. package/src/policy/engine.js +82 -0
  447. package/src/policy/exceptions.js +60 -0
  448. package/src/privacy/onboarding.js +35 -0
  449. package/src/privacy/scan.js +120 -0
  450. package/src/prompts/arbiter.js +38 -0
  451. package/src/prompts/architect.js +103 -0
  452. package/src/prompts/audit.js +474 -0
  453. package/src/prompts/coder.js +287 -0
  454. package/src/prompts/diff-clip.js +27 -0
  455. package/src/prompts/discover.js +222 -0
  456. package/src/prompts/hu-reviewer.js +219 -0
  457. package/src/prompts/planner.js +312 -0
  458. package/src/prompts/prompt-layout.js +80 -0
  459. package/src/prompts/prompt-resolver.js +120 -0
  460. package/src/prompts/reviewer.js +75 -0
  461. package/src/prompts/rtk-snippet.js +25 -0
  462. package/src/prompts/spec-reviewer.js +66 -0
  463. package/src/prompts/split-signal.js +82 -0
  464. package/src/prompts/start-decision.js +52 -0
  465. package/src/prompts/tool-correctness-judge.js +31 -0
  466. package/src/prompts/triage.js +57 -0
  467. package/src/rag/auto-update.js +72 -0
  468. package/src/rag/chunker-ast.js +56 -0
  469. package/src/rag/chunker.js +132 -0
  470. package/src/rag/embedder.js +2 -0
  471. package/src/rag/embedders/_cloud-base.js +2 -0
  472. package/src/rag/embedders/cohere.js +2 -0
  473. package/src/rag/embedders/factory.js +2 -0
  474. package/src/rag/embedders/mistral.js +2 -0
  475. package/src/rag/embedders/onnx.js +2 -0
  476. package/src/rag/embedders/openai.js +2 -0
  477. package/src/rag/embedders/voyage.js +2 -0
  478. package/src/rag/eval.js +61 -0
  479. package/src/rag/governed-embedder.js +39 -0
  480. package/src/rag/indexer.js +199 -0
  481. package/src/rag/library.js +62 -0
  482. package/src/rag/ollama-capability.js +59 -0
  483. package/src/rag/ollama-manager.js +98 -0
  484. package/src/rag/onnx-fallback.js +69 -0
  485. package/src/rag/rerank.js +4 -0
  486. package/src/rag/retriever.js +2 -0
  487. package/src/rag/vec-store.js +17 -0
  488. package/src/rag/watcher.js +62 -0
  489. package/src/rag/where-parser.js +4 -0
  490. package/src/repeat-detector.js +88 -0
  491. package/src/review/card-first.js +99 -0
  492. package/src/review/card-verify.js +83 -0
  493. package/src/review/diff-generator.js +112 -0
  494. package/src/review/gate-gitignore.js +77 -0
  495. package/src/review/git-stash-helper.js +104 -0
  496. package/src/review/mutation-pregate.js +48 -0
  497. package/src/review/one-shot-review.js +122 -0
  498. package/src/review/parser.js +80 -0
  499. package/src/review/policy-gate.js +26 -0
  500. package/src/review/profiles.js +66 -0
  501. package/src/review/reviewer-fallback.js +125 -0
  502. package/src/review/schema.js +31 -0
  503. package/src/review/scope-filter.js +152 -0
  504. package/src/review/snapshot-diff.js +122 -0
  505. package/src/review/solomon-arbitration.js +113 -0
  506. package/src/review/sonar-pregate.js +63 -0
  507. package/src/review/tdd-discipline.js +90 -0
  508. package/src/review/tdd-policy.js +69 -0
  509. package/src/review/tests-with-code.js +33 -0
  510. package/src/review/verdict-store.js +87 -0
  511. package/src/review/workspace.js +21 -0
  512. package/src/roles/agent-role.js +194 -0
  513. package/src/roles/architect-role.js +77 -0
  514. package/src/roles/audit-role.js +258 -0
  515. package/src/roles/base-role.js +165 -0
  516. package/src/roles/coder-role.js +107 -0
  517. package/src/roles/commiter-role.js +110 -0
  518. package/src/roles/discover-role.js +81 -0
  519. package/src/roles/domain-curator-role.js +141 -0
  520. package/src/roles/hu-reviewer-role.js +64 -0
  521. package/src/roles/impeccable-role.js +85 -0
  522. package/src/roles/index.js +18 -0
  523. package/src/roles/karajan-brain-role.js +134 -0
  524. package/src/roles/onboarder-role.js +61 -0
  525. package/src/roles/perf-role.js +122 -0
  526. package/src/roles/planner-role.js +151 -0
  527. package/src/roles/refactorer-role.js +30 -0
  528. package/src/roles/repairer-role.js +181 -0
  529. package/src/roles/researcher-role.js +70 -0
  530. package/src/roles/reviewer-role.js +104 -0
  531. package/src/roles/security-role.js +73 -0
  532. package/src/roles/solomon-role.js +265 -0
  533. package/src/roles/sonar-role.js +70 -0
  534. package/src/roles/spec-reviewer-role.js +106 -0
  535. package/src/roles/tester-role.js +235 -0
  536. package/src/roles/tool-correctness-judge-role.js +78 -0
  537. package/src/roles/triage-role.js +99 -0
  538. package/src/session/journal/decisions-writer.js +200 -0
  539. package/src/session/journal/iteration-logger.js +194 -0
  540. package/src/session/journal/summary-writer.js +320 -0
  541. package/src/session/journal/tree-writer.js +164 -0
  542. package/src/session/journal/write-all.js +89 -0
  543. package/src/session/mutators.js +339 -0
  544. package/src/session/runtime-overrides.js +59 -0
  545. package/src/session/store.js +106 -0
  546. package/src/session-cleanup.js +116 -0
  547. package/src/skills/addyosmani-catalog.js +315 -0
  548. package/src/skills/addyosmani-role-map.js +139 -0
  549. package/src/skills/openskills-client.js +157 -0
  550. package/src/skills/semantic-detector.js +167 -0
  551. package/src/skills/skill-detector.js +385 -0
  552. package/src/skills/skill-loader.js +219 -0
  553. package/src/skills/skills-cache.js +128 -0
  554. package/src/sonar/api.js +128 -0
  555. package/src/sonar/cloud-scanner.js +78 -0
  556. package/src/sonar/config-resolver.js +88 -0
  557. package/src/sonar/credentials.js +60 -0
  558. package/src/sonar/discovery.js +124 -0
  559. package/src/sonar/enforcer.js +19 -0
  560. package/src/sonar/issue-filter.js +12 -0
  561. package/src/sonar/manager.js +181 -0
  562. package/src/sonar/project-key.js +120 -0
  563. package/src/sonar/scanner.js +307 -0
  564. package/src/sonar/token-bootstrap.js +205 -0
  565. package/src/sonar/token-recovery.js +67 -0
  566. package/src/spec-review/refine-loop.js +58 -0
  567. package/src/spec-review/run-spec-review.js +119 -0
  568. package/src/start/assessment.js +74 -0
  569. package/src/start/maturity.js +73 -0
  570. package/src/start/start-decider-role.js +79 -0
  571. package/src/start/sweep.js +157 -0
  572. package/src/sync/apply-canvas-patch.js +55 -0
  573. package/src/sync/detect-drift.js +113 -0
  574. package/src/tournament/crown.js +88 -0
  575. package/src/tournament/judge.js +150 -0
  576. package/src/tournament/run.js +142 -0
  577. package/src/tournament/scoreboard.js +124 -0
  578. package/src/tracker-bootstrap.js +44 -0
  579. package/src/types/agent.js +55 -0
  580. package/src/types/config.js +114 -0
  581. package/src/types/hu.js +47 -0
  582. package/src/types/index.js +38 -0
  583. package/src/types/policy.js +43 -0
  584. package/src/types/session.js +75 -0
  585. package/src/types/solomon.js +87 -0
  586. package/src/types/stage.js +68 -0
  587. package/src/utils/agent-detect.js +93 -0
  588. package/src/utils/ai-trash.js +48 -0
  589. package/src/utils/async-lock.js +31 -0
  590. package/src/utils/atomic-write.js +6 -0
  591. package/src/utils/banner.js +66 -0
  592. package/src/utils/binary-sources.js +70 -0
  593. package/src/utils/board-prompt-bridge.js +108 -0
  594. package/src/utils/budget.js +229 -0
  595. package/src/utils/cli-ask-question.js +93 -0
  596. package/src/utils/cli-progress.js +220 -0
  597. package/src/utils/cli-run-log.js +83 -0
  598. package/src/utils/cwd-confirm.js +39 -0
  599. package/src/utils/derive-project-name-from-cwd.js +119 -0
  600. package/src/utils/display/event-handlers.js +403 -0
  601. package/src/utils/display/formatters.js +132 -0
  602. package/src/utils/display/header.js +47 -0
  603. package/src/utils/display/resume-hint.js +41 -0
  604. package/src/utils/display/session-summary.js +118 -0
  605. package/src/utils/display/solomon.js +42 -0
  606. package/src/utils/display/spec-findings.js +44 -0
  607. package/src/utils/doc-links.js +29 -0
  608. package/src/utils/docker-install.js +34 -0
  609. package/src/utils/escape-regexp.js +15 -0
  610. package/src/utils/events.js +35 -0
  611. package/src/utils/fs.js +19 -0
  612. package/src/utils/garbage-collector.js +481 -0
  613. package/src/utils/git.js +279 -0
  614. package/src/utils/home-migration.js +87 -0
  615. package/src/utils/injection-guard.js +186 -0
  616. package/src/utils/install-hints.js +180 -0
  617. package/src/utils/json-extract.js +64 -0
  618. package/src/utils/locale.js +59 -0
  619. package/src/utils/logger.js +96 -0
  620. package/src/utils/managed-markers.js +93 -0
  621. package/src/utils/manifest-sniff.js +82 -0
  622. package/src/utils/messages.js +61 -0
  623. package/src/utils/model-selector.js +107 -0
  624. package/src/utils/os-detect.js +79 -0
  625. package/src/utils/paths.js +13 -0
  626. package/src/utils/pending-user-action.js +95 -0
  627. package/src/utils/port-check.js +6 -0
  628. package/src/utils/port-occupant.js +96 -0
  629. package/src/utils/pricing.js +29 -0
  630. package/src/utils/process.js +4 -0
  631. package/src/utils/project-detect.js +160 -0
  632. package/src/utils/prompt-project-name.js +35 -0
  633. package/src/utils/provider-env.js +116 -0
  634. package/src/utils/qmd-collection.js +72 -0
  635. package/src/utils/qmd-detect.js +18 -0
  636. package/src/utils/qmd-install.js +37 -0
  637. package/src/utils/quota-simulator.js +56 -0
  638. package/src/utils/rate-limit-detector.js +181 -0
  639. package/src/utils/repo-cleaner.js +79 -0
  640. package/src/utils/retry.js +88 -0
  641. package/src/utils/role-assigner.js +137 -0
  642. package/src/utils/role-env.js +58 -0
  643. package/src/utils/rtk-detect.js +18 -0
  644. package/src/utils/rtk-install.js +38 -0
  645. package/src/utils/rtk-wrapper.js +87 -0
  646. package/src/utils/run-context.js +75 -0
  647. package/src/utils/run-log.js +217 -0
  648. package/src/utils/run-registry.js +9 -0
  649. package/src/utils/shared-paths.js +12 -0
  650. package/src/utils/squeezr-detect.js +21 -0
  651. package/src/utils/squeezr-install.js +37 -0
  652. package/src/utils/stack-detect.js +135 -0
  653. package/src/utils/stall-detector.js +159 -0
  654. package/src/utils/status-dashboard.js +254 -0
  655. package/src/utils/task-file.js +109 -0
  656. package/src/utils/telemetry.js +124 -0
  657. package/src/utils/templates-root.js +61 -0
  658. package/src/utils/tool-call-extractor.js +56 -0
  659. package/src/utils/tool-governor.js +116 -0
  660. package/src/utils/tool-installer.js +93 -0
  661. package/src/utils/update-check.js +280 -0
  662. package/src/utils/vector-store-orphans.js +89 -0
  663. package/src/utils/welcome.js +47 -0
  664. package/src/utils/with-timeout.js +42 -0
  665. package/src/utils/wizard.js +47 -0
  666. package/src/webperf/cwv-gate.js +94 -0
  667. package/src/webperf/devtools-detect.js +112 -0
  668. package/src/webperf/scanner.js +209 -0
  669. package/src/webperf/webperf-role-integration.js +66 -0
  670. package/templates/coder-rules.md +45 -0
  671. package/templates/docker-compose.sonar.yml +60 -0
  672. package/templates/domains/example-dental.md +57 -0
  673. package/templates/kj.config.yml +128 -0
  674. package/templates/review-rules.md +17 -0
  675. package/templates/roles/architect/anthropic.md +74 -0
  676. package/templates/roles/architect/default.md +72 -0
  677. package/templates/roles/architect/google.md +61 -0
  678. package/templates/roles/architect/openai.md +60 -0
  679. package/templates/roles/architect/opencode.md +59 -0
  680. package/templates/roles/architect.md +76 -0
  681. package/templates/roles/audit.md +68 -0
  682. package/templates/roles/coder/anthropic.md +81 -0
  683. package/templates/roles/coder/default.md +78 -0
  684. package/templates/roles/coder/google.md +87 -0
  685. package/templates/roles/coder/openai.md +68 -0
  686. package/templates/roles/coder/opencode.md +58 -0
  687. package/templates/roles/coder.md +152 -0
  688. package/templates/roles/commiter.md +44 -0
  689. package/templates/roles/discover.md +167 -0
  690. package/templates/roles/domain-curator.md +52 -0
  691. package/templates/roles/hu-reviewer.md +236 -0
  692. package/templates/roles/impeccable-design.md +87 -0
  693. package/templates/roles/impeccable.md +125 -0
  694. package/templates/roles/karajan-brain.md +95 -0
  695. package/templates/roles/onboarder.md +45 -0
  696. package/templates/roles/planner/anthropic.md +59 -0
  697. package/templates/roles/planner/default.md +57 -0
  698. package/templates/roles/planner/google.md +75 -0
  699. package/templates/roles/planner/openai.md +55 -0
  700. package/templates/roles/planner/opencode.md +62 -0
  701. package/templates/roles/planner.md +61 -0
  702. package/templates/roles/refactorer.md +48 -0
  703. package/templates/roles/repairer.md +103 -0
  704. package/templates/roles/researcher.md +41 -0
  705. package/templates/roles/reviewer/anthropic.md +61 -0
  706. package/templates/roles/reviewer/default.md +62 -0
  707. package/templates/roles/reviewer/google.md +63 -0
  708. package/templates/roles/reviewer/openai.md +57 -0
  709. package/templates/roles/reviewer/opencode.md +42 -0
  710. package/templates/roles/reviewer-paranoid.md +38 -0
  711. package/templates/roles/reviewer-relaxed.md +34 -0
  712. package/templates/roles/reviewer-strict.md +37 -0
  713. package/templates/roles/reviewer.md +62 -0
  714. package/templates/roles/security.md +54 -0
  715. package/templates/roles/solomon/anthropic.md +71 -0
  716. package/templates/roles/solomon/default.md +83 -0
  717. package/templates/roles/solomon/google.md +61 -0
  718. package/templates/roles/solomon/openai.md +53 -0
  719. package/templates/roles/solomon/opencode.md +55 -0
  720. package/templates/roles/solomon.md +83 -0
  721. package/templates/roles/sonar.md +49 -0
  722. package/templates/roles/spec-reviewer.md +47 -0
  723. package/templates/roles/tester.md +50 -0
  724. package/templates/roles/triage.md +69 -0
  725. package/templates/skills/kj-architect.md +45 -0
  726. package/templates/skills/kj-audit.md +63 -0
  727. package/templates/skills/kj-board.md +16 -0
  728. package/templates/skills/kj-code.md +51 -0
  729. package/templates/skills/kj-csv-transform.md +40 -0
  730. package/templates/skills/kj-data-report.md +44 -0
  731. package/templates/skills/kj-discover.md +24 -0
  732. package/templates/skills/kj-rag-query.md +50 -0
  733. package/templates/skills/kj-review.md +47 -0
  734. package/templates/skills/kj-run.md +73 -0
  735. package/templates/skills/kj-security.md +49 -0
  736. package/templates/skills/kj-sonar.md +41 -0
  737. package/templates/skills/kj-sql-analysis.md +40 -0
  738. package/templates/skills/kj-test.md +40 -0
  739. package/templates/workflows/automerge.yml +30 -0
  740. package/templates/workflows/houston-override.yml +46 -0
  741. package/templates/workflows/kj-ci-gateway.yml +58 -0
  742. package/vendor/tree-sitter-grammars/README.md +21 -0
  743. package/vendor/tree-sitter-grammars/go.wasm +0 -0
  744. package/vendor/tree-sitter-grammars/java.wasm +0 -0
  745. package/vendor/tree-sitter-grammars/python.wasm +0 -0
  746. package/vendor/tree-sitter-grammars/rust.wasm +0 -0
@@ -0,0 +1,78 @@
1
+ // KJC-TSK-0375 — ToolCorrectnessJudgeRole.
2
+ // Post-iteration LLM judge scoring how well a coder picked its tool calls.
3
+ // PR1 ships role + tests; wiring lives in PR3.
4
+
5
+ import { AgentRole } from "./agent-role.js";
6
+ import { buildToolCorrectnessJudgePrompt } from "../prompts/tool-correctness-judge.js";
7
+ import { extractFirstJson } from "../utils/json-extract.js";
8
+
9
+ const DEFAULT_THRESHOLD = 70;
10
+
11
+ const clampScore = (n) => Number.isFinite(n) ? Math.max(0, Math.min(100, Math.round(n))) : null;
12
+
13
+ const normalizeBreakdown = (b) => Array.isArray(b) ? b.map((x) => ({
14
+ tool: typeof x?.tool === "string" ? x.tool : "unknown",
15
+ args: x?.args && typeof x.args === "object" ? x.args : {},
16
+ correct: Boolean(x?.correct),
17
+ reason: typeof x?.reason === "string" ? x.reason.trim() : "",
18
+ })) : [];
19
+
20
+ export class ToolCorrectnessJudgeRole extends AgentRole {
21
+ constructor(opts) {
22
+ super({ ...opts, name: "tool-correctness-judge" });
23
+ this.threshold = opts?.threshold ?? this.config?.pipeline?.tool_judge?.threshold ?? DEFAULT_THRESHOLD;
24
+ }
25
+
26
+ resolveProvider() {
27
+ return this.config?.roles?.["tool-correctness-judge"]?.provider
28
+ || this.config?.roles?.reviewer?.provider
29
+ || this.config?.roles?.coder?.provider
30
+ || "claude";
31
+ }
32
+
33
+ extractInput(input) {
34
+ return { ...super.extractInput(input), toolCalls: Array.isArray(input?.toolCalls) ? input.toolCalls : [] };
35
+ }
36
+
37
+ async buildPrompt({ task, toolCalls }) {
38
+ return { prompt: buildToolCorrectnessJudgePrompt({ task, toolCalls, instructions: this.instructions }) };
39
+ }
40
+
41
+ parseOutput(raw) { return extractFirstJson(raw); }
42
+
43
+ buildSuccessResult(parsed, provider) {
44
+ const score = clampScore(parsed?.score);
45
+ return {
46
+ score,
47
+ summary: typeof parsed?.summary === "string" ? parsed.summary.trim() : "",
48
+ breakdown: normalizeBreakdown(parsed?.breakdown),
49
+ threshold: this.threshold,
50
+ lowQuality: score !== null && score < this.threshold,
51
+ provider,
52
+ };
53
+ }
54
+
55
+ buildSummary(parsed) {
56
+ const score = clampScore(parsed?.score);
57
+ if (score === null) return "Tool-judge: unparseable score";
58
+ return `Tool-judge: ${score}/100 (${score < this.threshold ? "LOW" : "OK"})`;
59
+ }
60
+
61
+ // Empty tool-call list = nothing to judge. Skip the LLM and report a
62
+ // neutral score so an absent transcript is never read as a failure.
63
+ async execute(input) {
64
+ const extracted = this.extractInput(input);
65
+ if (extracted.toolCalls.length === 0) {
66
+ return {
67
+ ok: true,
68
+ result: {
69
+ score: null, summary: "no tool calls captured (skipped)", breakdown: [],
70
+ threshold: this.threshold, lowQuality: false, provider: this.resolveProvider(), skipped: true,
71
+ },
72
+ summary: "Tool-judge: skipped (no calls)",
73
+ usage: null,
74
+ };
75
+ }
76
+ return super.execute(extracted);
77
+ }
78
+ }
@@ -0,0 +1,99 @@
1
+ import { AgentRole } from "./agent-role.js";
2
+ import { buildTriagePrompt } from "../prompts/triage.js";
3
+ import { VALID_TASK_TYPES } from "../guards/policy-resolver.js";
4
+ import { extractFirstJson } from "../utils/json-extract.js";
5
+
6
+ const VALID_LEVELS = new Set(["trivial", "simple", "medium", "complex"]);
7
+ const VALID_ROLES = new Set(["planner", "researcher", "refactorer", "reviewer", "tester", "security", "impeccable"]);
8
+ const FALLBACK_TASK_TYPE = "sw";
9
+ const FALLBACK_RESULT = { level: "medium", roles: ["reviewer"], taskType: FALLBACK_TASK_TYPE, shouldDecompose: false };
10
+
11
+ function normalizeRoles(roles) {
12
+ if (!Array.isArray(roles)) return [];
13
+ return Array.from(new Set(roles.filter((role) => VALID_ROLES.has(role))));
14
+ }
15
+
16
+ function normalizeSubtasks(subtasks) {
17
+ if (!Array.isArray(subtasks)) return [];
18
+ return subtasks.map((s) => (typeof s === "string" ? s.trim() : "")).filter(Boolean).slice(0, 5);
19
+ }
20
+
21
+ function normalizeDomainHints(hints) {
22
+ if (!Array.isArray(hints)) return [];
23
+ return hints.map((h) => (typeof h === "string" ? h.trim().toLowerCase() : "")).filter(Boolean);
24
+ }
25
+
26
+ export class TriageRole extends AgentRole {
27
+ constructor(opts) {
28
+ super({ ...opts, name: "triage" });
29
+ }
30
+
31
+ async buildPrompt({ task }) {
32
+ return { prompt: buildTriagePrompt({ task, instructions: this.instructions }) };
33
+ }
34
+
35
+ parseOutput(raw) { return extractFirstJson(raw); }
36
+
37
+ buildSuccessResult(parsed, provider) {
38
+ const level = VALID_LEVELS.has(parsed.level) ? parsed.level : "medium";
39
+ const roles = normalizeRoles(parsed.roles);
40
+ const reasoning = String(parsed.reasoning || "").trim() || "No reasoning provided.";
41
+ const shouldDecompose = Boolean(parsed.shouldDecompose);
42
+ const subtasks = normalizeSubtasks(parsed.subtasks);
43
+ const taskType = VALID_TASK_TYPES.has(parsed.taskType) ? parsed.taskType : FALLBACK_TASK_TYPE;
44
+ const domainHints = normalizeDomainHints(parsed.domainHints);
45
+
46
+ const result = { level, roles, reasoning, taskType, domainHints, provider };
47
+ if (shouldDecompose && subtasks.length > 0) {
48
+ result.shouldDecompose = true;
49
+ result.subtasks = subtasks;
50
+ } else {
51
+ result.shouldDecompose = false;
52
+ }
53
+ return result;
54
+ }
55
+
56
+ buildSummary(parsed) {
57
+ const level = VALID_LEVELS.has(parsed.level) ? parsed.level : "medium";
58
+ const roles = normalizeRoles(parsed.roles);
59
+ const decomposeNote = parsed.shouldDecompose ? " — decomposition recommended" : "";
60
+ return `Triage: ${level} (${roles.length} role${roles.length === 1 ? "" : "s"})${decomposeNote}`;
61
+ }
62
+
63
+ handleParseNull(agentResult, provider) {
64
+ return this.degradedTriageResult({
65
+ agentResult, provider,
66
+ reason: "parse-null",
67
+ reasoning: "Unstructured output, using safe defaults.",
68
+ message: "[triage] LLM output was unstructured — falling back to defaults; the pipeline may skip optional roles.",
69
+ });
70
+ }
71
+
72
+ handleParseError(err, agentResult, provider) {
73
+ return this.degradedTriageResult({
74
+ agentResult, provider,
75
+ reason: "parse-error",
76
+ reasoning: `Failed to parse triage output (${err?.message || "unknown error"}), using safe defaults.`,
77
+ message: `[triage] Could not parse LLM output — falling back to defaults: ${err?.message || "unknown"}.`,
78
+ });
79
+ }
80
+
81
+ // Triage degradation is what made a complex task quietly run as
82
+ // `level: "medium", roles: ["reviewer"]` — researcher / architect /
83
+ // security / tester silently skipped. The fallback is preserved so
84
+ // the pipeline still moves, but the user (and any board / kj-tail
85
+ // listener) now learns it happened. result.degraded = true lets
86
+ // downstream code react if it wants.
87
+ // Same shape as before so downstream cost / event accounting is
88
+ // byte-identical; the only change is the loud logger.warn, which is
89
+ // what makes the silent degradation visible to the user / kj-tail.
90
+ degradedTriageResult({ agentResult, provider, reason: _reason, reasoning, message }) {
91
+ this.logger?.warn?.(message);
92
+ return {
93
+ ok: true,
94
+ result: { ...FALLBACK_RESULT, reasoning, provider, raw: agentResult.output },
95
+ summary: "Triage complete (fallback defaults)",
96
+ usage: agentResult.usage,
97
+ };
98
+ }
99
+ }
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Build a human-readable `decisions.md` journal file summarizing every
3
+ * Solomon ruling and Brain decision made during a session.
4
+ *
5
+ * Acceptance criterion (KJC-TSK-0287):
6
+ * - Given Solomon was invoked at least once → decisions.md is written with
7
+ * timestamp, trigger, conflict context, ruling (action + reasoning),
8
+ * and resulting actions for every invocation.
9
+ * - Given Solomon was NOT invoked → decisions.md is NOT created.
10
+ *
11
+ * Brain routing decisions (from KJC-TSK-0322) are appended as a secondary
12
+ * section when present, since they share the same "decisions" semantics.
13
+ */
14
+
15
+ import fs from "node:fs/promises";
16
+ import path from "node:path";
17
+ import { getSessionRoot } from "../../utils/paths.js";
18
+
19
+ /**
20
+ * @typedef {Object} SolomonRuling
21
+ * @property {string} at - ISO timestamp
22
+ * @property {string} stage - conflict stage (reviewer, brain-routing, ...)
23
+ * @property {string} trigger - short reason the invocation was triggered
24
+ * @property {Object} conflict - conflict context (task, reason, summary)
25
+ * @property {string} ruling - approve / continue / escalate_human / create_subtask / ...
26
+ * @property {string} [reasoning]
27
+ * @property {string[]} [conditions]
28
+ * @property {string} [alternativeAgent]
29
+ * @property {string} [result] - what the orchestrator did with the ruling
30
+ */
31
+
32
+ /**
33
+ * @typedef {Object} BrainDecisionRecord
34
+ * @property {number} seq
35
+ * @property {string} at
36
+ * @property {string} intent
37
+ * @property {string[]} rolesOn
38
+ * @property {string} confidence
39
+ * @property {string} rationale
40
+ * @property {string[]} appliedOverrides
41
+ */
42
+
43
+ function esc(text) {
44
+ return String(text ?? "").replaceAll(/\|/g, "\\|");
45
+ }
46
+
47
+ function formatConditions(conditions) {
48
+ if (!Array.isArray(conditions) || conditions.length === 0) return "—";
49
+ return conditions.map((c) => `- ${esc(c)}`).join("\n");
50
+ }
51
+
52
+ function formatConflict(conflict) {
53
+ if (!conflict) return "—";
54
+ const parts = [];
55
+ if (conflict.task) parts.push(`**Task**: ${esc(conflict.task.slice(0, 200))}${conflict.task.length > 200 ? "…" : ""}`);
56
+ if (conflict.reason) parts.push(`**Reason**: ${esc(conflict.reason)}`);
57
+ if (conflict.summary) parts.push(`**Summary**: ${esc(conflict.summary)}`);
58
+ return parts.length > 0 ? parts.join("\n") : "—";
59
+ }
60
+
61
+ /**
62
+ * Render a Solomon ruling as a Markdown subsection.
63
+ * @param {SolomonRuling} ruling
64
+ * @param {number} index
65
+ * @returns {string}
66
+ */
67
+ function renderRuling(ruling, index) {
68
+ const at = ruling.at || "(unknown timestamp)";
69
+ const header = `### ${index + 1}. Solomon @ ${at} — ${esc(ruling.ruling || "unknown")}`;
70
+ const lines = [
71
+ header,
72
+ "",
73
+ `- **Stage**: ${esc(ruling.stage || "?")}`,
74
+ `- **Trigger**: ${esc(ruling.trigger || "?")}`,
75
+ `- **Ruling**: \`${esc(ruling.ruling || "?")}\``,
76
+ ];
77
+ if (ruling.alternativeAgent) lines.push(`- **Alternative agent**: ${esc(ruling.alternativeAgent)}`);
78
+ if (ruling.result) lines.push(`- **Applied result**: ${esc(ruling.result)}`);
79
+ lines.push("");
80
+ if (ruling.reasoning) {
81
+ lines.push("**Reasoning:**", "");
82
+ lines.push(ruling.reasoning.trim(), "");
83
+ }
84
+ if (ruling.conditions?.length) {
85
+ lines.push("**Conditions:**", "");
86
+ lines.push(formatConditions(ruling.conditions), "");
87
+ }
88
+ lines.push("**Conflict context:**", "");
89
+ lines.push(formatConflict(ruling.conflict), "");
90
+ return lines.join("\n");
91
+ }
92
+
93
+ function renderBrainDecision(decision, index) {
94
+ return [
95
+ `### ${index + 1}. Brain @ ${decision.at} — ${esc(decision.intent)}`,
96
+ "",
97
+ `- **Confidence**: ${esc(decision.confidence)}`,
98
+ `- **Roles on**: ${(decision.rolesOn || []).map(esc).join(", ") || "—"}`,
99
+ `- **Overrides applied**: ${(decision.appliedOverrides || []).map(esc).join(", ") || "—"}`,
100
+ "",
101
+ `> ${esc(decision.rationale || "")}`,
102
+ "",
103
+ ].join("\n");
104
+ }
105
+
106
+ /**
107
+ * Build the Markdown content for a session. Returns `null` if no Solomon
108
+ * rulings are present (per acceptance criteria — no Solomon, no file).
109
+ *
110
+ * @param {Object} session
111
+ * @returns {string|null}
112
+ */
113
+ export function buildDecisionsMarkdown(session) {
114
+ const rulings = Array.isArray(session?.solomonRulings) ? session.solomonRulings : [];
115
+ const brainDecisions = Array.isArray(session?.brainDecisions) ? session.brainDecisions : [];
116
+
117
+ // AC: no Solomon invocation → do not generate the file.
118
+ if (rulings.length === 0) return null;
119
+
120
+ const sessionId = session?.id || "(unknown)";
121
+ const header = [
122
+ `# Session decisions — ${sessionId}`,
123
+ "",
124
+ `_Generated at ${new Date().toISOString()}._`,
125
+ "",
126
+ `This journal records every decision the pipeline delegated to Solomon, plus Brain routing decisions for cross-reference.`,
127
+ "",
128
+ "## Summary",
129
+ "",
130
+ `- Solomon invocations: **${rulings.length}**`,
131
+ `- Brain routing decisions: **${brainDecisions.length}**`,
132
+ "",
133
+ "---",
134
+ "",
135
+ "## Solomon rulings",
136
+ "",
137
+ ].join("\n");
138
+
139
+ const solomonSection = rulings.map((r, i) => renderRuling(r, i)).join("\n---\n\n");
140
+
141
+ const brainSection = brainDecisions.length > 0
142
+ ? "\n---\n\n## Brain routing decisions\n\n" + brainDecisions.map((d, i) => renderBrainDecision(d, i)).join("\n")
143
+ : "";
144
+
145
+ return header + solomonSection + brainSection + "\n";
146
+ }
147
+
148
+ /**
149
+ * Persist decisions.md to the session's journal directory. No-op when there
150
+ * are no Solomon rulings (per acceptance criteria).
151
+ *
152
+ * Path resolution (first match wins):
153
+ * 1. options.journalDir — direct path to the session journal directory
154
+ * 2. options.sessionRoot + id — combines with session.id
155
+ * 3. getSessionRoot() + id — default Karajan session root
156
+ *
157
+ * @param {Object} session
158
+ * @param {{ journalDir?: string, sessionRoot?: string, logger?: Object }} [options]
159
+ * @returns {Promise<{ written: boolean, path: string|null }>}
160
+ */
161
+ export async function writeDecisionsJournal(session, options = {}) {
162
+ const content = buildDecisionsMarkdown(session);
163
+ if (content === null) return { written: false, path: null };
164
+
165
+ const sessionDir = options.journalDir
166
+ || path.join(options.sessionRoot || getSessionRoot(), session.id);
167
+ const filePath = path.join(sessionDir, "decisions.md");
168
+ try {
169
+ await fs.mkdir(sessionDir, { recursive: true });
170
+ await fs.writeFile(filePath, content, "utf8");
171
+ options.logger?.info?.(`Wrote decisions journal: ${filePath}`);
172
+ return { written: true, path: filePath };
173
+ } catch (err) {
174
+ options.logger?.warn?.(`Failed to write decisions journal (non-blocking): ${err.message}`);
175
+ return { written: false, path: null };
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Append a Solomon ruling to session.solomonRulings. Creates the array if
181
+ * absent. Callers (invokeSolomon) pass the structured record.
182
+ *
183
+ * @param {Object} session
184
+ * @param {SolomonRuling} record
185
+ */
186
+ export function recordSolomonRuling(session, record) {
187
+ if (!session) return;
188
+ if (!Array.isArray(session.solomonRulings)) session.solomonRulings = [];
189
+ session.solomonRulings.push({
190
+ at: record.at || new Date().toISOString(),
191
+ stage: record.stage || "unknown",
192
+ trigger: record.trigger || "",
193
+ conflict: record.conflict || {},
194
+ ruling: record.ruling || "unknown",
195
+ reasoning: record.reasoning || "",
196
+ conditions: Array.isArray(record.conditions) ? [...record.conditions] : [],
197
+ alternativeAgent: record.alternativeAgent || null,
198
+ result: record.result || "",
199
+ });
200
+ }
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Per-iteration journal entries for `.reviews/{sessionId}/iterations.md`.
3
+ *
4
+ * The orchestrator calls `recordIteration(session, data)` after every
5
+ * iteration of the coder/reviewer loop completes. Entries are appended to
6
+ * `session._journalIterations` and rendered as Markdown at session end.
7
+ *
8
+ * Acceptance criterion (KJC-TSK-0287):
9
+ * - Given a kj run with multiple iterations → iterations.md exists with
10
+ * one section per iteration containing: number, coder summary, reviewer
11
+ * blocking issues, sonar issues (if any), Solomon ruling (if any),
12
+ * duration.
13
+ */
14
+
15
+ /**
16
+ * @typedef {Object} IterationData
17
+ * @property {number} iteration - 1-based index
18
+ * @property {number} durationMs
19
+ * @property {string} [coderSummary]
20
+ * @property {string} [reviewerSummary]
21
+ * @property {Array<{id?:string, severity?:string, file?:string, line?:number, description?:string}>} [blockingIssues]
22
+ * @property {string} [sonarSummary]
23
+ * @property {number} [sonarIssuesFound]
24
+ * @property {number} [sonarIssuesResolved]
25
+ * @property {string} [testerSummary]
26
+ * @property {string} [securitySummary]
27
+ * @property {{ ruling?:string, reasoning?:string }} [solomon] - only present when Solomon ran in this iteration
28
+ */
29
+
30
+ function esc(text) {
31
+ return String(text ?? "").replaceAll(/\|/g, "\\|");
32
+ }
33
+
34
+ function formatDuration(ms) {
35
+ if (!Number.isFinite(ms) || ms < 0) return "—";
36
+ if (ms < 1000) return `${ms}ms`;
37
+ const s = Math.round(ms / 1000);
38
+ if (s < 60) return `${s}s`;
39
+ const m = Math.floor(s / 60);
40
+ const rs = s % 60;
41
+ return `${m}m ${rs}s`;
42
+ }
43
+
44
+ function formatBlockingIssues(issues) {
45
+ if (!Array.isArray(issues) || issues.length === 0) return null;
46
+ const lines = ["**Blocking issues**:"];
47
+ for (const issue of issues) {
48
+ const sev = issue.severity ? `[${issue.severity}] ` : "";
49
+ const loc = issue.file ? ` — \`${esc(issue.file)}${issue.line ? `:${issue.line}` : ""}\`` : "";
50
+ const id = issue.id ? `${issue.id}: ` : "";
51
+ const desc = esc(issue.description || issue.message || "(no description)");
52
+ lines.push(`- ${sev}${id}${desc}${loc}`);
53
+ }
54
+ return lines.join("\n");
55
+ }
56
+
57
+ function formatSonarBlock(data) {
58
+ const parts = [];
59
+ if (data.sonarSummary) parts.push(esc(data.sonarSummary));
60
+ if (Number.isFinite(data.sonarIssuesFound)) {
61
+ const resolved = Number.isFinite(data.sonarIssuesResolved) ? ` (${data.sonarIssuesResolved} resolved)` : "";
62
+ parts.push(`Issues: ${data.sonarIssuesFound}${resolved}`);
63
+ }
64
+ return parts.length > 0 ? parts.join(" · ") : null;
65
+ }
66
+
67
+ function formatSolomonBlock(solomon) {
68
+ if (!solomon || !solomon.ruling) return null;
69
+ const lines = [`**Ruling**: \`${esc(solomon.ruling)}\``];
70
+ if (solomon.reasoning) lines.push(`**Reasoning**: ${esc(solomon.reasoning)}`);
71
+ return lines.join(" \n");
72
+ }
73
+
74
+ /**
75
+ * Render a single iteration as a Markdown section.
76
+ *
77
+ * @param {IterationData} data
78
+ * @returns {string}
79
+ */
80
+ export function renderIterationEntry(data) {
81
+ const lines = [`## Iteration ${data.iteration}`, ""];
82
+ lines.push(`**Duration**: ${formatDuration(data.durationMs)}`);
83
+
84
+ if (data.coderSummary) {
85
+ lines.push("", "### Coder", data.coderSummary);
86
+ }
87
+
88
+ if (data.reviewerSummary || (data.blockingIssues && data.blockingIssues.length > 0)) {
89
+ lines.push("", "### Reviewer");
90
+ if (data.reviewerSummary) lines.push(data.reviewerSummary);
91
+ const blocks = formatBlockingIssues(data.blockingIssues);
92
+ if (blocks) {
93
+ lines.push("", blocks);
94
+ }
95
+ }
96
+
97
+ const sonarLine = formatSonarBlock(data);
98
+ if (sonarLine) {
99
+ lines.push("", "### Sonar", sonarLine);
100
+ }
101
+
102
+ if (data.testerSummary) lines.push("", "### Tester", data.testerSummary);
103
+ if (data.securitySummary) lines.push("", "### Security", data.securitySummary);
104
+
105
+ const solomonBlock = formatSolomonBlock(data.solomon);
106
+ if (solomonBlock) {
107
+ lines.push("", "### Solomon", solomonBlock);
108
+ }
109
+
110
+ lines.push("");
111
+ return lines.join("\n");
112
+ }
113
+
114
+ /**
115
+ * Append an iteration record to session._journalIterations.
116
+ * Creates the array if absent. Callers pass structured IterationData.
117
+ *
118
+ * @param {Object} session
119
+ * @param {IterationData} data
120
+ */
121
+ export function recordIteration(session, data) {
122
+ if (!session || !data) return;
123
+ if (!Array.isArray(session._journalIterations)) session._journalIterations = [];
124
+ session._journalIterations.push(renderIterationEntry(data));
125
+ }
126
+
127
+ /**
128
+ * Build the full iterations.md content from recorded entries.
129
+ * Returns null when there are no iterations to render.
130
+ *
131
+ * @param {Object} session
132
+ * @returns {string|null}
133
+ */
134
+ export function buildIterationsMarkdown(session) {
135
+ const entries = Array.isArray(session?._journalIterations) ? session._journalIterations : [];
136
+ if (entries.length === 0) return null;
137
+ const header = [
138
+ `# Session iterations — ${session.id || "(unknown)"}`,
139
+ "",
140
+ `_Generated at ${new Date().toISOString()}._`,
141
+ "",
142
+ `Total iterations: **${entries.length}**`,
143
+ "",
144
+ "---",
145
+ "",
146
+ ].join("\n");
147
+ return header + entries.join("---\n\n") + "\n";
148
+ }
149
+
150
+ /**
151
+ * Extract structured iteration data from a stageResults bundle + session state.
152
+ * The orchestrator produces stage results per role; this helper pulls the
153
+ * relevant fields into a single object suitable for recordIteration().
154
+ *
155
+ * @param {Object} args
156
+ * @param {number} args.iteration
157
+ * @param {number} args.durationMs
158
+ * @param {Object} args.stageResults
159
+ * @param {Object} [args.session]
160
+ * @returns {IterationData}
161
+ */
162
+ export function extractIterationData({ iteration, durationMs, stageResults = {}, session = {} }) {
163
+ const coderSummary = stageResults.coder?.summary || stageResults.coder?.result?.summary;
164
+ const reviewerSummary = stageResults.reviewer?.summary;
165
+ const blockingIssues = stageResults.reviewer?.result?.blocking_issues
166
+ || stageResults.reviewer?.blocking_issues
167
+ || [];
168
+ const testerSummary = stageResults.tester?.summary;
169
+ const securitySummary = stageResults.security?.summary;
170
+ const sonarSummary = stageResults.sonar?.summary
171
+ || (stageResults.sonar?.openIssues != null ? `${stageResults.sonar.openIssues} open issue(s)` : undefined);
172
+ const sonarIssuesFound = stageResults.sonar?.issuesInitial ?? stageResults.sonar?.issuesFound;
173
+ const sonarIssuesResolved = stageResults.sonar?.issuesResolved;
174
+
175
+ // Solomon ruling for THIS iteration: match by iteration if the session
176
+ // tracks it; otherwise just take the latest ruling.
177
+ const rulings = Array.isArray(session.solomonRulings) ? session.solomonRulings : [];
178
+ const solomonRecord = rulings.find((r) => r.iteration === iteration) || rulings.at(-1);
179
+ const solomon = solomonRecord ? { ruling: solomonRecord.ruling, reasoning: solomonRecord.reasoning } : undefined;
180
+
181
+ return {
182
+ iteration,
183
+ durationMs,
184
+ coderSummary,
185
+ reviewerSummary,
186
+ blockingIssues,
187
+ sonarSummary,
188
+ sonarIssuesFound,
189
+ sonarIssuesResolved,
190
+ testerSummary,
191
+ securitySummary,
192
+ solomon,
193
+ };
194
+ }