karajan-code 4.70.3 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (388) hide show
  1. package/README.md +2 -2
  2. package/package.json +6 -14
  3. package/packages/hu-board/package.json +1 -1
  4. package/packages/hu-board/public/app.js +4 -18
  5. package/packages/hu-board/public/index.html +5 -2
  6. package/packages/hu-board/public/styles.css +26 -0
  7. package/packages/hu-board/public/utils/api.js +0 -74
  8. package/packages/hu-board/public/utils/board-tour.js +62 -0
  9. package/packages/hu-board/public/utils/board-view.js +49 -144
  10. package/packages/hu-board/public/utils/command-launcher.js +8 -70
  11. package/packages/hu-board/public/utils/formatters.js +10 -0
  12. package/packages/hu-board/public/utils/governance-view.js +13 -1
  13. package/packages/hu-board/public/utils/hu-actions.js +17 -68
  14. package/packages/hu-board/public/utils/init-listeners.js +7 -8
  15. package/packages/hu-board/public/utils/log-panel.js +3 -16
  16. package/packages/hu-board/public/utils/maggle-mode.js +2 -12
  17. package/packages/hu-board/public/utils/modals.js +7 -0
  18. package/packages/hu-board/public/utils/project-picker-view.js +1 -1
  19. package/packages/hu-board/public/utils/server-push.js +3 -22
  20. package/packages/hu-board/public/utils/shared-board-notice.js +33 -0
  21. package/packages/hu-board/public/utils/story-detail-view.js +5 -19
  22. package/packages/hu-board/src/cleanup-zombies.js +0 -1
  23. package/packages/hu-board/src/command-runner.js +36 -25
  24. package/packages/hu-board/src/db-connection.js +282 -0
  25. package/packages/hu-board/src/db-paths.js +113 -0
  26. package/packages/hu-board/src/db-queries.js +188 -0
  27. package/packages/hu-board/src/db-tombstones.js +51 -0
  28. package/packages/hu-board/src/db.js +28 -619
  29. package/packages/hu-board/src/ephemeral-cleaner.js +2 -3
  30. package/packages/hu-board/src/hu-zombie-reaper.js +5 -1
  31. package/packages/hu-board/src/plan-mutations.js +3 -153
  32. package/packages/hu-board/src/plans-service.js +55 -0
  33. package/packages/hu-board/src/routes/api/commands.js +122 -0
  34. package/packages/hu-board/src/routes/api/plans.js +55 -0
  35. package/packages/hu-board/src/routes/api/projects.js +267 -0
  36. package/packages/hu-board/src/routes/api/prompts.js +135 -0
  37. package/packages/hu-board/src/routes/api/sessions.js +95 -0
  38. package/packages/hu-board/src/routes/api/stories.js +183 -0
  39. package/packages/hu-board/src/routes/api/system.js +241 -0
  40. package/packages/hu-board/src/routes/api/tombstones.js +38 -0
  41. package/packages/hu-board/src/routes/api.js +24 -1371
  42. package/packages/hu-board/src/routes/governance.js +23 -1
  43. package/packages/hu-board/src/routes/lanes.js +40 -0
  44. package/packages/hu-board/src/routes/rag.js +4 -3
  45. package/packages/hu-board/src/server.js +20 -34
  46. package/packages/hu-board/src/sync-files.js +318 -0
  47. package/packages/hu-board/src/sync-project.js +99 -0
  48. package/packages/hu-board/src/sync.js +22 -566
  49. package/packages/hu-board/src/zombie-reaper.js +1 -1
  50. package/scripts/dual-publish.mjs +19 -3
  51. package/scripts/postinstall.js +15 -2
  52. package/scripts/verify-pack-mcp.mjs +11 -7
  53. package/scripts/verify-pack.mjs +4 -4
  54. package/src/audit/audit-history.js +3 -2
  55. package/src/audit/dead-exports.js +68 -59
  56. package/src/audit/deterministic-summary.js +33 -13
  57. package/src/audit/npm-signatures.js +41 -0
  58. package/src/audit/sbom.js +35 -0
  59. package/src/checks/agent-token.js +112 -0
  60. package/src/checks/ai-surface.js +9 -7
  61. package/src/checks/config-files.js +8 -7
  62. package/src/checks/dir-setup.js +34 -1
  63. package/src/checks/native-build.js +21 -39
  64. package/src/checks/runner.js +128 -142
  65. package/src/cli/advanced-commands.js +6 -6
  66. package/src/cli/register-meta.js +42 -82
  67. package/src/cli/register-pipeline.js +8 -140
  68. package/src/cli/register-plan.js +9 -100
  69. package/src/cli/retired-commands.js +49 -0
  70. package/src/cli.js +18 -5
  71. package/src/commands/agent-run.js +40 -26
  72. package/src/commands/audit.js +127 -124
  73. package/src/commands/board.js +5 -9
  74. package/src/commands/check.js +29 -16
  75. package/src/commands/doctor.js +2 -0
  76. package/src/commands/env.js +176 -148
  77. package/src/commands/go.js +76 -55
  78. package/src/commands/harden.js +105 -86
  79. package/src/commands/hu-start.js +52 -0
  80. package/src/commands/hu.js +288 -221
  81. package/src/commands/identity.js +111 -78
  82. package/src/commands/init-atril.js +47 -0
  83. package/src/commands/init.js +11 -40
  84. package/src/commands/install-tools.js +70 -85
  85. package/src/commands/main-guard.js +78 -0
  86. package/src/commands/policy.js +226 -184
  87. package/src/commands/qmd.js +27 -21
  88. package/src/commands/rag.js +75 -48
  89. package/src/commands/review-gate.js +422 -339
  90. package/src/commands/start.js +4 -5
  91. package/src/commands/steward.js +96 -47
  92. package/src/commands/tournament.js +46 -37
  93. package/src/commands/worktree.js +94 -25
  94. package/src/config/loader.js +34 -17
  95. package/src/config/overrides.js +2 -1
  96. package/src/config/secrets.js +36 -0
  97. package/src/config.js +1 -0
  98. package/src/environment/adr.js +16 -2
  99. package/src/environment/board-access.js +11 -9
  100. package/src/git/karajan-label.js +20 -8
  101. package/src/guards/main-guard.js +54 -0
  102. package/src/harden/branch-protection.js +36 -3
  103. package/src/harden/hook-templates.js +16 -1
  104. package/src/harden/sentinel/posttooluse.mjs +18 -6
  105. package/src/harden/sentinel/pretooluse-sentinel.mjs +81 -35
  106. package/src/harden/sentinel/sentinel-lib.mjs +149 -23
  107. package/src/harden/sentinel/sentinel-shell.mjs +64 -0
  108. package/src/harden/sentinel/sessionstart.mjs +3 -2
  109. package/src/harden/sentinel/stop.mjs +5 -4
  110. package/src/harden/workflow-engine.js +12 -1
  111. package/src/harden/workflow-templates.js +1 -1
  112. package/src/hu/board-lookup.js +29 -0
  113. package/src/hu/gh-identity.js +23 -0
  114. package/src/hu/github-board.js +4 -2
  115. package/src/hu/lane-prune.js +15 -7
  116. package/src/hu/lane-setup.js +65 -0
  117. package/src/hu/lanes.js +66 -0
  118. package/src/hu/team-board-mirror.js +3 -2
  119. package/src/infrastructure/command-runner.js +1 -1
  120. package/src/infrastructure/file-system-service.js +1 -1
  121. package/src/mcp/handlers/direct-handlers.js +2 -292
  122. package/src/mcp/handlers/hu-handlers.js +44 -55
  123. package/src/mcp/handlers/management-handlers.js +2 -42
  124. package/src/mcp/server-handlers.js +16 -22
  125. package/src/mcp/tools.js +5 -200
  126. package/src/plan/lane-plans.js +54 -0
  127. package/src/plan/plan-store.js +7 -4
  128. package/src/policy/add.js +26 -12
  129. package/src/policy/adr-number-check.js +31 -0
  130. package/src/prompts/audit.js +299 -339
  131. package/src/prompts/card-context.js +10 -5
  132. package/src/prompts/reviewer.js +5 -2
  133. package/src/rag/auto-update.js +56 -43
  134. package/src/rag/bootstrap-index.js +28 -54
  135. package/src/rag/migrate.js +1 -1
  136. package/src/rag/onnx-fallback.js +2 -2
  137. package/src/rag/pid-lease.js +70 -0
  138. package/src/rag/project-store.js +2 -12
  139. package/src/review/card-first.js +57 -46
  140. package/src/review/dual-review.js +5 -4
  141. package/src/review/gate-gitignore.js +23 -4
  142. package/src/review/gate-hook.js +47 -0
  143. package/src/review/one-shot-review.js +51 -37
  144. package/src/review/publish-pr.js +18 -3
  145. package/src/review/repo-docs.js +73 -0
  146. package/src/review/repo-stack.js +59 -0
  147. package/src/review/reviewer-fallback.js +34 -3
  148. package/src/review/seal-commit.js +29 -0
  149. package/src/review/sonar-pregate.js +59 -44
  150. package/src/review/third-party-review.js +90 -16
  151. package/src/review/third-party-size.js +43 -0
  152. package/src/review/third-party-skills.js +54 -0
  153. package/src/review/verify-pr.js +2 -26
  154. package/src/roles/audit-role.js +106 -125
  155. package/src/skills/atril-skills.js +5 -4
  156. package/src/sonar/scanner.js +116 -101
  157. package/src/steward/invariants.js +5 -4
  158. package/src/steward/phantom-sweep.js +66 -0
  159. package/src/tournament/judge.js +60 -53
  160. package/src/utils/agent-home.js +33 -0
  161. package/src/utils/gh-account.js +37 -0
  162. package/src/utils/git.js +0 -13
  163. package/src/utils/home-migration.js +7 -1
  164. package/src/utils/main-checkout.js +53 -0
  165. package/src/utils/qmd-collection.js +3 -1
  166. package/src/utils/welcome.js +3 -3
  167. package/templates/{skills → atril/commands}/kj-architect.md +5 -0
  168. package/templates/{skills → atril/commands}/kj-audit.md +5 -0
  169. package/templates/{skills → atril/commands}/kj-board.md +5 -0
  170. package/templates/{skills → atril/commands}/kj-code.md +5 -0
  171. package/templates/{skills → atril/commands}/kj-csv-transform.md +5 -0
  172. package/templates/{skills → atril/commands}/kj-data-report.md +5 -0
  173. package/templates/{skills → atril/commands}/kj-discover.md +5 -0
  174. package/templates/{skills → atril/commands}/kj-rag-query.md +5 -0
  175. package/templates/{skills → atril/commands}/kj-review.md +5 -0
  176. package/templates/{skills → atril/commands}/kj-security.md +5 -0
  177. package/templates/{skills → atril/commands}/kj-sonar.md +5 -0
  178. package/templates/{skills → atril/commands}/kj-sql-analysis.md +5 -0
  179. package/templates/{skills → atril/commands}/kj-test.md +5 -0
  180. package/packages/hu-board/public/utils/run-launcher.js +0 -169
  181. package/packages/hu-board/src/run-tracker.js +0 -121
  182. package/src/activity-log.js +0 -59
  183. package/src/agents/host-agent.js +0 -38
  184. package/src/agents/model-registry.js +0 -142
  185. package/src/audit/plan-adherence.js +0 -224
  186. package/src/autonomy/arbiter-role.js +0 -71
  187. package/src/autonomy/arbiter.js +0 -22
  188. package/src/autonomy/decider.js +0 -18
  189. package/src/autonomy/decision-resolver.js +0 -58
  190. package/src/autonomy/outcome-report.js +0 -55
  191. package/src/autonomy/stage-ask.js +0 -30
  192. package/src/brain/decision-tracker.js +0 -125
  193. package/src/brain/decisor.js +0 -243
  194. package/src/brain/solomon-consult.js +0 -171
  195. package/src/brain/standby-scheduler.js +0 -8
  196. package/src/budget/comparison.js +0 -96
  197. package/src/canvas/parse-md.js +0 -238
  198. package/src/canvas/schema.js +0 -101
  199. package/src/canvas/to-flat.js +0 -85
  200. package/src/canvas/validate.js +0 -163
  201. package/src/ci/dispatch.js +0 -99
  202. package/src/ci/index.js +0 -3
  203. package/src/ci/pr-diff.js +0 -26
  204. package/src/cli/register-standby.js +0 -26
  205. package/src/commands/architect.js +0 -111
  206. package/src/commands/autorun.js +0 -49
  207. package/src/commands/researcher.js +0 -54
  208. package/src/commands/resume.js +0 -72
  209. package/src/commands/review.js +0 -89
  210. package/src/commands/run.js +0 -185
  211. package/src/commands/standby.js +0 -117
  212. package/src/commands/status.js +0 -36
  213. package/src/commands/triage.js +0 -78
  214. package/src/commands/undo.js +0 -62
  215. package/src/domains/domain-loader.js +0 -245
  216. package/src/domains/domain-registry.js +0 -140
  217. package/src/domains/domain-synthesizer.js +0 -129
  218. package/src/git/automation.js +0 -433
  219. package/src/git/coder-commit-guard.js +0 -40
  220. package/src/git/hu-automation.js +0 -243
  221. package/src/git/hu-snapshot.js +0 -10
  222. package/src/git/symlink-targets.js +0 -57
  223. package/src/golden/asserter.js +0 -92
  224. package/src/golden/loader.js +0 -52
  225. package/src/golden/runner.js +0 -92
  226. package/src/golden/schema.js +0 -41
  227. package/src/guards/duplicate-members.js +0 -86
  228. package/src/guards/intent-guard.js +0 -161
  229. package/src/guards/perf-guard.js +0 -126
  230. package/src/guards/policy-guard.js +0 -90
  231. package/src/guards/policy-resolver.js +0 -85
  232. package/src/guards/secret-redactor.js +0 -71
  233. package/src/hu/acceptance-runner.js +0 -138
  234. package/src/hu/lazy-planner.js +0 -109
  235. package/src/hu/parallel-executor.js +0 -94
  236. package/src/hu/routing-metrics.js +0 -17
  237. package/src/hu/split-validator.js +0 -143
  238. package/src/hu/splitting-detector.js +0 -158
  239. package/src/hu/splitting-generator.js +0 -175
  240. package/src/hu/store.js +0 -394
  241. package/src/infrastructure/mocks.js +0 -182
  242. package/src/mcp/handlers/run-handler.js +0 -318
  243. package/src/mcp/sovereignty-guard.js +0 -113
  244. package/src/mcp/tool-arg-normalizers.js +0 -16
  245. package/src/mutate/reviewer-signal.js +0 -76
  246. package/src/orchestrator/agent-fallback.js +0 -81
  247. package/src/orchestrator/brain-coordinator.js +0 -186
  248. package/src/orchestrator/ci-integration.js +0 -139
  249. package/src/orchestrator/config-init.js +0 -426
  250. package/src/orchestrator/direct-actions.js +0 -217
  251. package/src/orchestrator/drivers/error-recovery.js +0 -287
  252. package/src/orchestrator/drivers/init-context.js +0 -238
  253. package/src/orchestrator/drivers/iteration-loop.js +0 -382
  254. package/src/orchestrator/drivers/iteration-phases/coder-and-refactorer.js +0 -69
  255. package/src/orchestrator/drivers/iteration-phases/guards.js +0 -91
  256. package/src/orchestrator/drivers/iteration-phases/handle-approved.js +0 -29
  257. package/src/orchestrator/drivers/iteration-phases/quality-gates.js +0 -125
  258. package/src/orchestrator/drivers/iteration-phases/reviewer-gate.js +0 -62
  259. package/src/orchestrator/drivers/post-loop.js +0 -404
  260. package/src/orchestrator/drivers/pre-loop-phases/auto-hu-batch.js +0 -137
  261. package/src/orchestrator/drivers/pre-loop-phases/config-deprecations.js +0 -47
  262. package/src/orchestrator/drivers/pre-loop-phases/ensure-addyosmani-skills.js +0 -84
  263. package/src/orchestrator/drivers/pre-loop-phases/inject-loaded-plan.js +0 -393
  264. package/src/orchestrator/drivers/pre-loop.js +0 -524
  265. package/src/orchestrator/drivers/run-hu-batch.js +0 -468
  266. package/src/orchestrator/feedback-enrichment.js +0 -140
  267. package/src/orchestrator/feedback-queue.js +0 -151
  268. package/src/orchestrator/flow-control.js +0 -170
  269. package/src/orchestrator/flow-runner.js +0 -365
  270. package/src/orchestrator/fs-leak-detector.js +0 -228
  271. package/src/orchestrator/hu-scheduler.js +0 -114
  272. package/src/orchestrator/hu-sub-pipeline.js +0 -642
  273. package/src/orchestrator/iteration-gate.js +0 -73
  274. package/src/orchestrator/iteration-stages.js +0 -9
  275. package/src/orchestrator/parallel-limiter.js +0 -74
  276. package/src/orchestrator/pipeline-context.js +0 -72
  277. package/src/orchestrator/post-loop-stages.js +0 -468
  278. package/src/orchestrator/pre-loop-stages.js +0 -11
  279. package/src/orchestrator/preflight-checks.js +0 -487
  280. package/src/orchestrator/repair/repair-detector.js +0 -117
  281. package/src/orchestrator/repair/repair-runner.js +0 -142
  282. package/src/orchestrator/reviewer-fallback.js +0 -45
  283. package/src/orchestrator/role-output-compressor.js +0 -189
  284. package/src/orchestrator/session-journal.js +0 -308
  285. package/src/orchestrator/solomon-escalation.js +0 -331
  286. package/src/orchestrator/solomon-rules.js +0 -212
  287. package/src/orchestrator/stages/acceptance-coverage-stage.js +0 -47
  288. package/src/orchestrator/stages/architect-stage.js +0 -172
  289. package/src/orchestrator/stages/coder-stage.js +0 -506
  290. package/src/orchestrator/stages/domain-curator-stage.js +0 -82
  291. package/src/orchestrator/stages/format-stage.js +0 -61
  292. package/src/orchestrator/stages/hu-reviewer-phases/detect-and-apply-splits.js +0 -127
  293. package/src/orchestrator/stages/hu-reviewer-stage.js +0 -419
  294. package/src/orchestrator/stages/perf-stage.js +0 -140
  295. package/src/orchestrator/stages/planner-stage.js +0 -85
  296. package/src/orchestrator/stages/rag-context-stage.js +0 -80
  297. package/src/orchestrator/stages/rag-preload-decisor.js +0 -58
  298. package/src/orchestrator/stages/research-stage.js +0 -69
  299. package/src/orchestrator/stages/reviewer-stage.js +0 -431
  300. package/src/orchestrator/stages/sonar-stage.js +0 -439
  301. package/src/orchestrator/stages/stage-classes.js +0 -84
  302. package/src/orchestrator/stages/stage-executor.js +0 -155
  303. package/src/orchestrator/stages/suite-green-stage.js +0 -62
  304. package/src/orchestrator/stages/tdd-discipline-stage.js +0 -56
  305. package/src/orchestrator/stages/tool-judge-stage.js +0 -53
  306. package/src/orchestrator/stages/triage-stage.js +0 -172
  307. package/src/orchestrator/standby.js +0 -71
  308. package/src/orchestrator/verification-gate.js +0 -183
  309. package/src/orchestrator.js +0 -22
  310. package/src/plan/adr-generator.js +0 -170
  311. package/src/plan/adr-loader.js +0 -60
  312. package/src/plan/plan-executor.js +0 -100
  313. package/src/plan/plan-validation.js +0 -4
  314. package/src/prompts/acceptance-coverage.js +0 -32
  315. package/src/prompts/arbiter.js +0 -38
  316. package/src/prompts/architect.js +0 -103
  317. package/src/prompts/hu-reviewer.js +0 -244
  318. package/src/prompts/tool-correctness-judge.js +0 -31
  319. package/src/prompts/triage.js +0 -57
  320. package/src/rag/embedder.js +0 -2
  321. package/src/rag/embedders/_cloud-base.js +0 -2
  322. package/src/rag/embedders/cohere.js +0 -2
  323. package/src/rag/embedders/mistral.js +0 -2
  324. package/src/rag/embedders/onnx.js +0 -2
  325. package/src/rag/embedders/openai.js +0 -2
  326. package/src/rag/embedders/voyage.js +0 -2
  327. package/src/rag/rerank.js +0 -4
  328. package/src/rag/where-parser.js +0 -4
  329. package/src/repeat-detector.js +0 -88
  330. package/src/review/diff-generator.js +0 -112
  331. package/src/review/git-stash-helper.js +0 -104
  332. package/src/review/schema.js +0 -31
  333. package/src/review/scope-filter.js +0 -152
  334. package/src/review/snapshot-diff.js +0 -122
  335. package/src/review/tdd-discipline.js +0 -90
  336. package/src/review/tdd-policy.js +0 -69
  337. package/src/roles/acceptance-coverage-role.js +0 -78
  338. package/src/roles/architect-role.js +0 -77
  339. package/src/roles/coder-role.js +0 -113
  340. package/src/roles/commiter-role.js +0 -113
  341. package/src/roles/domain-curator-role.js +0 -134
  342. package/src/roles/hu-reviewer-role.js +0 -64
  343. package/src/roles/impeccable-role.js +0 -85
  344. package/src/roles/index.js +0 -18
  345. package/src/roles/karajan-brain-role.js +0 -134
  346. package/src/roles/perf-role.js +0 -122
  347. package/src/roles/planner-role.js +0 -151
  348. package/src/roles/refactorer-role.js +0 -30
  349. package/src/roles/repairer-role.js +0 -181
  350. package/src/roles/researcher-role.js +0 -70
  351. package/src/roles/reviewer-role.js +0 -115
  352. package/src/roles/security-role.js +0 -73
  353. package/src/roles/solomon-role.js +0 -271
  354. package/src/roles/sonar-role.js +0 -72
  355. package/src/roles/tester-role.js +0 -235
  356. package/src/roles/tool-correctness-judge-role.js +0 -78
  357. package/src/roles/triage-role.js +0 -99
  358. package/src/session/journal/decisions-writer.js +0 -200
  359. package/src/session/journal/iteration-logger.js +0 -194
  360. package/src/session/journal/summary-writer.js +0 -320
  361. package/src/session/journal/tree-writer.js +0 -164
  362. package/src/session/journal/write-all.js +0 -89
  363. package/src/session-cleanup.js +0 -116
  364. package/src/skills/semantic-detector.js +0 -167
  365. package/src/skills/skill-detector.js +0 -385
  366. package/src/sonar/cloud-scanner.js +0 -78
  367. package/src/tracker-bootstrap.js +0 -44
  368. package/src/types/index.js +0 -38
  369. package/src/types/policy.js +0 -43
  370. package/src/types/solomon.js +0 -87
  371. package/src/utils/async-lock.js +0 -31
  372. package/src/utils/budget.js +0 -229
  373. package/src/utils/cwd-confirm.js +0 -39
  374. package/src/utils/display/event-handlers.js +0 -403
  375. package/src/utils/display/formatters.js +0 -132
  376. package/src/utils/display/header.js +0 -47
  377. package/src/utils/display/session-summary.js +0 -118
  378. package/src/utils/display/solomon.js +0 -42
  379. package/src/utils/pricing.js +0 -29
  380. package/src/utils/quota-simulator.js +0 -56
  381. package/src/utils/role-assigner.js +0 -137
  382. package/src/utils/rtk-wrapper.js +0 -87
  383. package/src/utils/run-registry.js +0 -9
  384. package/src/utils/status-dashboard.js +0 -254
  385. package/src/utils/tool-call-extractor.js +0 -56
  386. package/src/webperf/devtools-detect.js +0 -112
  387. package/src/webperf/webperf-role-integration.js +0 -66
  388. package/templates/skills/kj-run.md +0 -73
@@ -1,142 +0,0 @@
1
- const modelRegistry = new Map();
2
-
3
- export function registerModel(name, { provider, pricing, deprecated } = {}) {
4
- if (!name || typeof name !== "string") {
5
- throw new Error("Model name must be a non-empty string");
6
- }
7
- if (!pricing || typeof pricing.input_per_million !== "number" || typeof pricing.output_per_million !== "number") {
8
- throw new Error(`Model "${name}" requires pricing with input_per_million and output_per_million`);
9
- }
10
- modelRegistry.set(name, {
11
- name,
12
- provider: provider || name.split("/")[0],
13
- pricing: { input_per_million: pricing.input_per_million, output_per_million: pricing.output_per_million },
14
- deprecated: deprecated || null,
15
- });
16
- }
17
-
18
- export function registerModelAlias(alias, target, { provider } = {}) {
19
- const entry = modelRegistry.get(target);
20
- if (!entry) {
21
- throw new Error(`Target model "${target}" for alias "${alias}" not found`);
22
- }
23
- modelRegistry.set(alias, {
24
- ...entry,
25
- name: alias,
26
- provider: provider || entry.provider
27
- });
28
- }
29
-
30
- export function getModelPricing(name) {
31
- const entry = modelRegistry.get(name);
32
- return entry ? { ...entry.pricing } : null;
33
- }
34
-
35
- export function isModelDeprecated(name) {
36
- const entry = modelRegistry.get(name);
37
- if (!entry?.deprecated) return false;
38
- return new Date(entry.deprecated) <= new Date();
39
- }
40
-
41
- export function getModelInfo(name) {
42
- const entry = modelRegistry.get(name);
43
- if (!entry) return null;
44
- return { name: entry.name, provider: entry.provider, pricing: { ...entry.pricing }, deprecated: entry.deprecated };
45
- }
46
-
47
- export function getRegisteredModels() {
48
- return [...modelRegistry.entries()].map(([_name, entry]) => ({
49
- name: entry.name,
50
- provider: entry.provider,
51
- pricing: { ...entry.pricing },
52
- deprecated: entry.deprecated,
53
- }));
54
- }
55
-
56
- export function buildDefaultPricingTable() {
57
- const table = {};
58
- for (const [name, entry] of modelRegistry) {
59
- table[name] = { ...entry.pricing };
60
- }
61
- return table;
62
- }
63
-
64
- /**
65
- * Anthropic Claude Family
66
- * Pricing & Info: https://platform.claude.com/docs/en/about-claude/pricing
67
- */
68
- registerModel("claude-opus-4.6", { provider: "anthropic", pricing: { input_per_million: 5.0, output_per_million: 25.0 } });
69
- registerModel("claude-sonnet-4.6", { provider: "anthropic", pricing: { input_per_million: 3.0, output_per_million: 15.0 } });
70
- registerModel("claude-haiku-4.5", { provider: "anthropic", pricing: { input_per_million: 1.0, output_per_million: 5.0 } });
71
-
72
- // Default models & General aliases
73
- registerModel("claude", { provider: "anthropic", pricing: { input_per_million: 3, output_per_million: 15 } });
74
- registerModel("sonnet", { provider: "anthropic", pricing: { input_per_million: 3, output_per_million: 15 } });
75
- registerModel("opus", { provider: "anthropic", pricing: { input_per_million: 15, output_per_million: 75 } });
76
- registerModel("haiku", { provider: "anthropic", pricing: { input_per_million: 0.25, output_per_million: 1.25 } });
77
-
78
- /**
79
- * OpenAI GPT Family
80
- * Pricing: https://developers.openai.com/api/docs/pricing
81
- */
82
- registerModel("gpt-5.4-standard", { provider: "openai", pricing: { input_per_million: 2.5, output_per_million: 15.0 } });
83
- registerModel("gpt-5.4-thinking", { provider: "openai", pricing: { input_per_million: 2.5, output_per_million: 15.0 } });
84
- registerModel("gpt-5.4-pro", { provider: "openai", pricing: { input_per_million: 30.0, output_per_million: 180.0 } });
85
- registerModel("gpt-5.4-mini", { provider: "openai", pricing: { input_per_million: 0.75, output_per_million: 4.5 } });
86
-
87
- // Default models & General aliases
88
- registerModel("codex", { provider: "openai", pricing: { input_per_million: 1.5, output_per_million: 4 } });
89
- // KJC-TSK-0699: the models the codex CLI lists (0.146.1). List prices after the
90
- // 2026-07-30 cut; Sol at its base rate, not the temporary promotion.
91
- registerModel("gpt-5.6-sol", { provider: "openai", pricing: { input_per_million: 5.0, output_per_million: 30.0 } });
92
- registerModel("gpt-5.6-terra", { provider: "openai", pricing: { input_per_million: 2.0, output_per_million: 12.0 } });
93
- registerModel("gpt-5.6-luna", { provider: "openai", pricing: { input_per_million: 0.2, output_per_million: 1.2 } });
94
- registerModel("o4-mini", { provider: "openai", pricing: { input_per_million: 1.5, output_per_million: 4 } });
95
- registerModel("o3", { provider: "openai", pricing: { input_per_million: 10, output_per_million: 40 } });
96
-
97
- /**
98
- * Google Gemini Family
99
- * Pricing: https://ai.google.dev/gemini-api/docs/pricing
100
- */
101
- registerModel("gemini-3.1-pro-preview", { provider: "google", pricing: { input_per_million: 2.0, output_per_million: 12.0 } });
102
- registerModel("gemini-3.1-flash-lite", { provider: "google", pricing: { input_per_million: 0.25, output_per_million: 1.5 } });
103
- registerModel("gemini-3-flash-preview", { provider: "google", pricing: { input_per_million: 0.5, output_per_million: 3.0 } });
104
- registerModel("gemini-2.5-pro", { provider: "google", pricing: { input_per_million: 1.25, output_per_million: 5 } });
105
- registerModel("gemini-2.0-flash", { provider: "google", pricing: { input_per_million: 0.075, output_per_million: 0.3 } });
106
-
107
- // Default models & General aliases
108
- registerModelAlias("gemini", "gemini-2.5-pro");
109
-
110
- /**
111
- * Other Providers & CLI Aliases
112
- */
113
- registerModel("aider", { provider: "aider", pricing: { input_per_million: 3, output_per_million: 15 } });
114
- registerModel("opencode", { provider: "opencode", pricing: { input_per_million: 0, output_per_million: 0 } });
115
-
116
- /**
117
- * Moonshot Kimi Family (KJC-TSK-0633) — consumed through OpenCode as an
118
- * OpenAI-compatible provider (docs/providers-via-opencode.md).
119
- * Pricing: https://platform.moonshot.ai/docs/pricing — verify before
120
- * trusting for billing decisions; ids/prices move fast.
121
- */
122
- registerModel("kimi-k2", { provider: "moonshot", pricing: { input_per_million: 0.6, output_per_million: 2.5 } });
123
- registerModel("kimi-k2-thinking", { provider: "moonshot", pricing: { input_per_million: 0.6, output_per_million: 2.5 } });
124
- registerModelAlias("kimi", "kimi-k2");
125
- // Prefixed ids as the documented opencode.json snippet produces them.
126
- registerModelAlias("kimi/kimi-k2", "kimi-k2");
127
- registerModelAlias("kimi/kimi-k2-thinking", "kimi-k2-thinking");
128
-
129
- /**
130
- * DeepSeek Family (KJC-TSK-0633) — same OpenCode route.
131
- * Pricing: https://api-docs.deepseek.com/quick_start/pricing
132
- */
133
- registerModel("deepseek-chat", { provider: "deepseek", pricing: { input_per_million: 0.28, output_per_million: 0.42 } });
134
- registerModel("deepseek-reasoner", { provider: "deepseek", pricing: { input_per_million: 0.28, output_per_million: 0.42 } });
135
- registerModelAlias("deepseek", "deepseek-chat");
136
- registerModelAlias("deepseek/deepseek-chat", "deepseek-chat");
137
- registerModelAlias("deepseek/deepseek-reasoner", "deepseek-reasoner");
138
-
139
- // Common CLI Aliases (with provider overrides)
140
- registerModelAlias("aider/claude-3-7-sonnet", "claude-sonnet-4.6", { provider: "aider" });
141
- registerModelAlias("aider/gpt-4o", "gpt-5.4-standard", { provider: "aider" });
142
- registerModelAlias("opencode/minimax-m2.5", "opencode", { provider: "opencode" });
@@ -1,224 +0,0 @@
1
- /**
2
- * Plan adherence metric — KJC-TSK-0376 (deepeval-inspired).
3
- * Pure offline 0-100 score: how faithfully did the coder follow the plan?
4
- * Components (weighted): commit_attribution 40%, acceptance_tests 30%,
5
- * scope_discipline 20%, dependency_order 10%. Components return null
6
- * when no data; aggregator redistributes the weight.
7
- * See docs/plan-adherence.md (PR-C) for the full spec.
8
- */
9
-
10
- import { escapeRegExp } from "../utils/escape-regexp.js";
11
-
12
- const WEIGHTS = {
13
- commit_attribution: 40,
14
- acceptance_tests: 30,
15
- scope_discipline: 20,
16
- dependency_order: 10,
17
- };
18
-
19
- /**
20
- * Build a regex that matches the HU id anywhere in a commit message
21
- * (case-insensitive, word-boundary friendly). The `_` and `-` characters
22
- * appear inside HU ids so we anchor on whole-token rather than \b.
23
- */
24
- function huIdMatcher(huId) {
25
- const escaped = escapeRegExp(huId);
26
- return new RegExp(`(^|[^a-z0-9])${escaped}([^a-z0-9]|$)`, "i");
27
- }
28
-
29
- /**
30
- * Slugify an HU title for branch-name / scope matching. Mirrors the
31
- * `buildHuBranchName` slug rule (lowercase, non-alnum → "-").
32
- */
33
- function slugify(text) {
34
- return String(text || "")
35
- .toLowerCase()
36
- .replaceAll(/[^a-z0-9]+/g, "-")
37
- .replaceAll(/(^-+)|(-+$)/g, "");
38
- }
39
-
40
- /**
41
- * Try to attribute a single commit to one of the plan's HUs.
42
- *
43
- * Order of evidence, strongest first:
44
- * 1. The HU id appears in the commit message.
45
- * 2. The HU id appears in the branch name where the commit lives
46
- * (commit.branch is supplied by listCommitsBetween's caller when
47
- * it knows the per-HU branches).
48
- * 3. The HU title slug matches the commit message.
49
- *
50
- * Returns the matched huId, or null when none of the above fires.
51
- */
52
- export function attributeCommitToHu(commit, hus) {
53
- if (!commit || !Array.isArray(hus) || hus.length === 0) return null;
54
- const msg = String(commit.message || "");
55
- const branch = String(commit.branch || "");
56
- for (const hu of hus) {
57
- if (!hu?.id) continue;
58
- const matcher = huIdMatcher(hu.id);
59
- if (matcher.test(msg)) return hu.id;
60
- if (branch && matcher.test(branch)) return hu.id;
61
- }
62
- // Fallback: title slug
63
- for (const hu of hus) {
64
- const slug = slugify(hu.title);
65
- if (!slug || slug.length < 6) continue;
66
- if (slugify(msg).includes(slug)) return hu.id;
67
- }
68
- return null;
69
- }
70
-
71
- /**
72
- * Component 1: commit attribution. Returns null when the run produced
73
- * no commits at all (avoids penalising analysis-only or doc-only runs).
74
- */
75
- export function computeCommitAttribution(commits, plan) {
76
- if (!Array.isArray(commits) || commits.length === 0) return null;
77
- if (!plan?.hus || plan.hus.length === 0) return null;
78
- let attributed = 0;
79
- for (const commit of commits) {
80
- if (attributeCommitToHu(commit, plan.hus)) attributed += 1;
81
- }
82
- return Math.round((attributed / commits.length) * 100);
83
- }
84
-
85
- /**
86
- * Component 2: acceptance test coverage. Heuristic: each HU declares
87
- * `acceptance_tests`. We check whether at least one commit from that
88
- * HU's pool has a `test:`-prefixed message. Per-HU score (1 or 0),
89
- * averaged across HUs that DO declare tests. Returns null when no HU
90
- * declares acceptance tests.
91
- */
92
- export function computeAcceptanceTestCoverage(commits, plan) {
93
- if (!plan?.hus || plan.hus.length === 0) return null;
94
- if (!Array.isArray(commits) || commits.length === 0) return null;
95
- const husWithTests = plan.hus.filter(
96
- (hu) => Array.isArray(hu?.acceptance_tests) && hu.acceptance_tests.length > 0,
97
- );
98
- if (husWithTests.length === 0) return null;
99
-
100
- let covered = 0;
101
- for (const hu of husWithTests) {
102
- const huCommits = (commits || []).filter(
103
- (c) => attributeCommitToHu(c, [hu]) === hu.id,
104
- );
105
- const hasTestCommit = huCommits.some((c) =>
106
- /^test[:(]/i.test(String(c.message || "").trim()),
107
- );
108
- if (hasTestCommit) covered += 1;
109
- }
110
- return Math.round((covered / husWithTests.length) * 100);
111
- }
112
-
113
- /**
114
- * Component 3: scope discipline. For each file changed by the run, we
115
- * try to match it against at least one HU's id slug, title slug, or
116
- * `scope` text. A file that matches no HU is flagged as out-of-scope.
117
- * Returns null when the run changed no files.
118
- */
119
- export function computeScopeDiscipline(filesChanged, plan) {
120
- if (!Array.isArray(filesChanged) || filesChanged.length === 0) return null;
121
- if (!plan?.hus || plan.hus.length === 0) return null;
122
- const huKeywords = plan.hus.map((hu) => ({
123
- id: hu.id,
124
- matchers: [
125
- slugify(hu.id),
126
- slugify(hu.title),
127
- // Pull alpha-rich words from `scope` text (length >= 4).
128
- ...String(hu.scope || "")
129
- .toLowerCase()
130
- .split(/[^a-z]+/)
131
- .filter((w) => w.length >= 4),
132
- ].filter(Boolean),
133
- }));
134
- let inScope = 0;
135
- for (const file of filesChanged) {
136
- const slug = slugify(file);
137
- const matched = huKeywords.some((hk) =>
138
- hk.matchers.some((m) => slug.includes(m) || file.includes(m)),
139
- );
140
- if (matched) inScope += 1;
141
- }
142
- return Math.round((inScope / filesChanged.length) * 100);
143
- }
144
-
145
- /**
146
- * Component 4: dependency order. For every `(parent, child)` edge
147
- * declared via `child.blocked_by`, check that the EARLIEST commit
148
- * attributed to `parent` is older than the EARLIEST commit attributed
149
- * to `child`. Returns null when no dependency edges exist.
150
- *
151
- * `commits` are expected oldest-first (the shape `listCommitsBetween`
152
- * returns). When that's not the case the score still makes sense — we
153
- * just compare relative positions in the array.
154
- */
155
- export function computeDependencyOrder(commits, plan) {
156
- if (!plan?.hus || plan.hus.length === 0) return null;
157
- const edges = [];
158
- for (const hu of plan.hus) {
159
- for (const parentId of hu.blocked_by || []) {
160
- edges.push([parentId, hu.id]);
161
- }
162
- }
163
- if (edges.length === 0) return null;
164
- if (!Array.isArray(commits) || commits.length === 0) return null;
165
-
166
- // Build huId → first commit index (oldest first attribution).
167
- const firstIndex = new Map();
168
- commits.forEach((commit, idx) => {
169
- const huId = attributeCommitToHu(commit, plan.hus);
170
- if (huId && !firstIndex.has(huId)) firstIndex.set(huId, idx);
171
- });
172
-
173
- let respected = 0;
174
- let evaluable = 0;
175
- for (const [parentId, childId] of edges) {
176
- const p = firstIndex.get(parentId);
177
- const c = firstIndex.get(childId);
178
- if (p === undefined || c === undefined) continue; // can't evaluate
179
- evaluable += 1;
180
- if (p < c) respected += 1;
181
- }
182
- if (evaluable === 0) return null;
183
- return Math.round((respected / evaluable) * 100);
184
- }
185
-
186
- /**
187
- * Aggregator: compute every component and weight them. Components
188
- * that return `null` are excluded and their weight redistributed
189
- * proportionally across the rest, so a run that legitimately has no
190
- * acceptance tests or no dependencies isn't penalised.
191
- *
192
- * Returns the full structured result (see file header for shape).
193
- */
194
- export function computePlanAdherenceScore({ commits, plan, filesChanged }) {
195
- const breakdown = {
196
- commit_attribution: computeCommitAttribution(commits, plan),
197
- acceptance_tests: computeAcceptanceTestCoverage(commits, plan),
198
- scope_discipline: computeScopeDiscipline(filesChanged, plan),
199
- dependency_order: computeDependencyOrder(commits, plan),
200
- };
201
-
202
- // Weighted average over non-null components only.
203
- let totalWeight = 0;
204
- let weightedSum = 0;
205
- for (const [key, weight] of Object.entries(WEIGHTS)) {
206
- const value = breakdown[key];
207
- if (value === null || value === undefined) continue;
208
- totalWeight += weight;
209
- weightedSum += value * weight;
210
- }
211
- const score = totalWeight === 0 ? null : Math.round(weightedSum / totalWeight);
212
-
213
- // Per-HU detail: was the HU "touched" (attributed at least one commit)?
214
- const hu_scores = (plan?.hus || []).map((hu) => {
215
- const huCommits = (commits || []).filter(
216
- (c) => attributeCommitToHu(c, [hu]) === hu.id,
217
- );
218
- const issues = [];
219
- if (huCommits.length === 0) issues.push("no commit attributed");
220
- return { huId: hu.id, attributed: huCommits.length > 0, issues };
221
- });
222
-
223
- return { score, breakdown, hu_scores };
224
- }
@@ -1,71 +0,0 @@
1
- /**
2
- * ArbiterRole — the autonomous decision authority that resolves agent conflicts
3
- * by picking the least-bad verdict (KJC-TSK-0573, épica KJC-PCS-0062).
4
- *
5
- * Extends AgentRole (so it inherits Brain recovery / standby) following the
6
- * TriageRole pattern: a cheap decisor model emits a closed-set verdict, and any
7
- * parse failure degrades to BLOCK_AND_CONTINUE — the pipeline never crashes and
8
- * never blocks on the Arbiter.
9
- */
10
-
11
- import { AgentRole } from "../roles/agent-role.js";
12
- import { extractFirstJson } from "../utils/json-extract.js";
13
- import { buildArbiterPrompt, VERDICTS } from "../prompts/arbiter.js";
14
-
15
- const CONSERVATIVE = "BLOCK_AND_CONTINUE";
16
- const VERDICT_SET = new Set(VERDICTS);
17
-
18
- function clampConfidence(value) {
19
- const n = Number(value);
20
- return Number.isFinite(n) ? Math.min(1, Math.max(0, n)) : 0;
21
- }
22
-
23
- export class ArbiterRole extends AgentRole {
24
- constructor(opts) {
25
- super({ ...opts, name: "arbiter" });
26
- }
27
-
28
- async buildPrompt(input) {
29
- return { prompt: buildArbiterPrompt(input) };
30
- }
31
-
32
- parseOutput(raw) {
33
- return extractFirstJson(raw);
34
- }
35
-
36
- buildSuccessResult(parsed, provider) {
37
- const verdict = VERDICT_SET.has(parsed?.verdict) ? parsed.verdict : CONSERVATIVE;
38
- return {
39
- verdict,
40
- confidence: clampConfidence(parsed?.confidence),
41
- rationale: String(parsed?.rationale || "").trim() || "no rationale",
42
- defect: parsed?.defect ? String(parsed.defect).trim() : null,
43
- directive: parsed?.directive ? String(parsed.directive).trim() : null,
44
- provider,
45
- };
46
- }
47
-
48
- buildSummary(parsed) {
49
- return `Arbiter: ${VERDICT_SET.has(parsed?.verdict) ? parsed.verdict : CONSERVATIVE}`;
50
- }
51
-
52
- // Never crash on garbage: degrade to the conservative verdict so the pipeline
53
- // moves on instead of aborting (ok:true keeps the run alive).
54
- handleParseNull(agentResult, provider) {
55
- return this.degraded(agentResult, provider, "unstructured output");
56
- }
57
-
58
- handleParseError(err, agentResult, provider) {
59
- return this.degraded(agentResult, provider, err?.message || "parse error");
60
- }
61
-
62
- degraded(agentResult, provider, why) {
63
- this.logger?.warn?.(`[arbiter] ${why} → ${CONSERVATIVE} (conservative)`);
64
- return {
65
- ok: true,
66
- result: { verdict: CONSERVATIVE, confidence: 0, rationale: `degraded: ${why}`, defect: null, directive: null, provider },
67
- summary: `Arbiter: ${CONSERVATIVE} (degraded)`,
68
- usage: agentResult.usage,
69
- };
70
- }
71
- }
@@ -1,22 +0,0 @@
1
- /**
2
- * createArbiter — adapt ArbiterRole to the function the decision-resolver
3
- * injects (KJC-TSK-0573). The resolver calls `arbiter(req)` and expects
4
- * `{ choice, rationale, ... }`; here `choice` is the Arbiter's verdict, which
5
- * the resolver then validates against the caller's options (AUTO-A).
6
- */
7
-
8
- import { ArbiterRole } from "./arbiter-role.js";
9
-
10
- export function createArbiter({ config = {}, logger = console, createAgentFn = null } = {}) {
11
- return async function arbiter(req) {
12
- const role = new ArbiterRole({ config, logger, createAgentFn });
13
- const { result } = await role.execute(req);
14
- return {
15
- choice: result.verdict,
16
- rationale: result.rationale,
17
- confidence: result.confidence,
18
- defect: result.defect,
19
- directive: result.directive,
20
- };
21
- };
22
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * buildDecider — wire the active autonomy level to a ready decision resolver
3
- * (KJC-TSK-0572, design in docs/specs/autonomous-delivery.md §5).
4
- *
5
- * interactive → the human `ask`; assisted/autonomous → the Arbiter (AUTO-B).
6
- * Consumers (spec-review, reviewer, checkpoint…) call `resolve(...)` instead of
7
- * prompting directly, so the autonomy level decides who answers in one place.
8
- */
9
-
10
- import { createDecisionResolver } from "./decision-resolver.js";
11
- import { resolveAutonomy } from "./policy.js";
12
- import { createArbiter } from "./arbiter.js";
13
-
14
- export function buildDecider({ config = {}, flags = {}, ask = null, env = process.env, logger = console, createAgentFn = null } = {}) {
15
- const autonomy = resolveAutonomy({ config, flags, env });
16
- const arbiter = autonomy === "interactive" ? null : createArbiter({ config, logger, createAgentFn });
17
- return { autonomy, resolve: createDecisionResolver({ autonomy, ask, arbiter, logger }) };
18
- }
@@ -1,58 +0,0 @@
1
- /**
2
- * autonomy/decision-resolver — the single choke point for every pipeline
3
- * question (KJC-TSK-0572, design in docs/specs/autonomous-delivery.md §5).
4
- *
5
- * Today the "ask a human" logic is scattered (spec-review, checkpoint,
6
- * reviewer, board-bridge). This unifies it: callers ask `resolveDecision`
7
- * instead of prompting directly, and the autonomy level decides who answers —
8
- * the human (`ask`) or the Arbiter (`arbiter`, injected by AUTO-B).
9
- *
10
- * INVARIANT: in `autonomous` mode the resolver NEVER returns a null choice and
11
- * NEVER blocks — if the Arbiter can't decide it degrades to the option flagged
12
- * `conservative` (or the first option). Decisions are always traced.
13
- */
14
-
15
- import { RISK, usesArbiter } from "./policy.js";
16
-
17
- /** Pick the safe fallback: the option flagged conservative, else the first. */
18
- function conservativeOf(options) {
19
- return options.find((o) => o.conservative) ?? options[0] ?? null;
20
- }
21
-
22
- function decision(choice, rationale, source) {
23
- return { choice: choice ?? null, rationale, source };
24
- }
25
-
26
- /**
27
- * Build a resolver bound to an autonomy level and its two answer sources.
28
- *
29
- * @param {object} opts
30
- * @param {string} opts.autonomy - interactive | assisted | autonomous
31
- * @param {(question: string, context?: object) => Promise<string|null>} [opts.ask] - human prompt
32
- * @param {(input: object) => Promise<{choice: string, rationale?: string}>} [opts.arbiter] - AUTO-B
33
- * @returns {(req: object) => Promise<{choice, rationale, source}>}
34
- */
35
- export function createDecisionResolver({ autonomy = "interactive", ask = null, arbiter = null, logger = console } = {}) {
36
- return async function resolveDecision({ question, options = [], context = null, risk = RISK.LOW } = {}) {
37
- const fallback = conservativeOf(options);
38
-
39
- // Human path: interactive, or assisted with a high-risk decision.
40
- if (!usesArbiter(autonomy, risk)) {
41
- const answer = ask ? await ask(question, context) : null;
42
- return decision(answer, "human", "human");
43
- }
44
-
45
- // Arbiter path: must always yield a valid choice, never block.
46
- if (!arbiter) return decision(fallback?.value, "no arbiter available → conservative", "fallback");
47
- let verdict;
48
- try {
49
- verdict = await arbiter({ question, options, context, risk });
50
- } catch (err) {
51
- logger.warn?.(`decision-resolver: arbiter failed (${err.message}) → conservative`);
52
- return decision(fallback?.value, "arbiter error → conservative", "fallback");
53
- }
54
- const valid = verdict && options.some((o) => o.value === verdict.choice);
55
- if (!valid) return decision(fallback?.value, "arbiter gave no valid choice → conservative", "fallback");
56
- return decision(verdict.choice, verdict.rationale ?? "arbiter", "arbiter");
57
- };
58
- }
@@ -1,55 +0,0 @@
1
- /**
2
- * outcome-report — the auditable "meets the ask, with known defects" report
3
- * for an autonomous run (KJC-TSK-0577, design in docs/specs/autonomous-delivery.md §10).
4
- *
5
- * Pure: builds a serializable outcome from the run results + Arbiter decisions,
6
- * and renders it as lines (or the structure is emitted as --json). The point is
7
- * that an imperfect-but-delivered result is explicit and auditable: which HUs
8
- * met the ask, what the Arbiter decided, and what debt remains.
9
- */
10
-
11
- /**
12
- * @param {object} opts
13
- * @param {string} [opts.planRef]
14
- * @param {boolean} opts.delivered - the run met the minimum ask
15
- * @param {Array<{id, title?, met: boolean, note?}>} [opts.hus]
16
- * @param {Array<{verdict, rationale, hu?, defect?}>} [opts.decisions] - Arbiter log
17
- */
18
- export function buildOutcome({ planRef = null, delivered = false, hus = [], decisions = [] } = {}) {
19
- const met = hus.filter((h) => h.met).length;
20
- const residualDefects = [
21
- ...hus.filter((h) => !h.met).map((h) => ({ hu: h.id, detail: h.note || "acceptance criteria not fully met" })),
22
- ...decisions.filter((d) => d.defect).map((d) => ({ hu: d.hu ?? null, detail: d.defect })),
23
- ];
24
- return {
25
- verdict: delivered ? "DELIVERED" : "INCOMPLETE",
26
- planRef,
27
- hus: { total: hus.length, met, unmet: hus.length - met },
28
- decisions,
29
- residualDefects,
30
- };
31
- }
32
-
33
- /** Render an outcome (from buildOutcome) as human-readable lines. */
34
- export function formatOutcomeReport(outcome) {
35
- const lines = [
36
- `kj autorun — outcome: ${outcome.verdict}`,
37
- ` plan: ${outcome.planRef ?? "?"}`,
38
- ` HUs: ${outcome.hus.met}/${outcome.hus.total} met the ask`,
39
- ];
40
- if (outcome.decisions?.length) {
41
- lines.push(" Decisions (Arbiter — least-bad calls):");
42
- for (const d of outcome.decisions) {
43
- lines.push(` • ${d.verdict}${d.hu ? ` [${d.hu}]` : ""} — ${d.rationale}`);
44
- }
45
- }
46
- if (outcome.residualDefects?.length) {
47
- lines.push(" Known defects (delivered with debt):");
48
- for (const def of outcome.residualDefects) {
49
- lines.push(` • ${def.hu ? `[${def.hu}] ` : ""}${def.detail}`);
50
- }
51
- } else {
52
- lines.push(" No residual defects recorded.");
53
- }
54
- return lines;
55
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * createAutonomyAskQuestion — make the stages' question function non-blocking in
3
- * autonomous mode (KJC-TSK-0576, AUTO-E, design in docs/specs/autonomous-delivery.md §9).
4
- *
5
- * In `autonomous` no stage asks a human or routes to the HU Board: the wrapper
6
- * answers in-process with the least-bad "keep going" choice, so the run never
7
- * pauses or aborts mid-loop. interactive and assisted keep the human prompts
8
- * (baseAsk) unchanged.
9
- *
10
- * The answer is chosen per stage so the EXISTING branches proceed (verified
11
- * against the stage code — no stage logic is touched):
12
- * - architect clarification: null → the stage continues best-effort (a truthy
13
- * answer would force a wasteful architect re-run).
14
- * - everything else (Solomon escalation, checkpoint, …): "continue" → parsed
15
- * as free-text guidance → the stage continues instead of pausing/aborting.
16
- */
17
- export function createAutonomyAskQuestion({ baseAsk = null, autonomy = "interactive", logger = console } = {}) {
18
- if (autonomy !== "autonomous") return baseAsk;
19
- const auto = async (_question, context = {}) => {
20
- const stage = context?.stage ?? null;
21
- logger?.info?.(`[autonomy] ${stage ? `${stage}: ` : ""}auto-continue (no human in the loop)`);
22
- return stage === "architect" ? null : "continue";
23
- };
24
- auto.interactive = false;
25
- // Marker so the orchestrator can tell an autonomous (unattended) run from an
26
- // interactive one even though both carry a truthy askQuestion — the wall-clock
27
- // backstop relies on it (KJC-TSK-0575, AUTO-D).
28
- auto.unattended = true;
29
- return auto;
30
- }