sneakoscope 4.8.7 → 5.3.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 (261) hide show
  1. package/README.md +51 -726
  2. package/config/bench-baseline.json +7 -0
  3. package/crates/sks-core/Cargo.lock +1 -1
  4. package/crates/sks-core/Cargo.toml +1 -1
  5. package/crates/sks-core/src/main.rs +1 -1
  6. package/dist/bin/install.js +35 -0
  7. package/dist/bin/sks.js +1 -1
  8. package/dist/cli/cli-theme.js +51 -0
  9. package/dist/cli/command-registry.js +15 -4
  10. package/dist/cli/help-fast.js +18 -8
  11. package/dist/cli/insane-search-command.js +36 -8
  12. package/dist/cli/install-helpers.js +32 -0
  13. package/dist/commands/codex-lb.js +2 -0
  14. package/dist/commands/doctor.js +94 -9
  15. package/dist/commands/proof.js +6 -3
  16. package/dist/config/skills-manifest.json +82 -54
  17. package/dist/core/agents/agent-conflict-graph.js +5 -0
  18. package/dist/core/agents/agent-lease.js +5 -0
  19. package/dist/core/agents/agent-ledger-schemas.js +1 -0
  20. package/dist/core/agents/agent-lifecycle.js +5 -3
  21. package/dist/core/agents/agent-orchestrator.js +268 -62
  22. package/dist/core/agents/agent-output-validator.js +14 -3
  23. package/dist/core/agents/agent-patch-queue-store.js +95 -2
  24. package/dist/core/agents/agent-patch-queue.js +6 -3
  25. package/dist/core/agents/agent-patch-schema.js +13 -0
  26. package/dist/core/agents/agent-proof-evidence.js +6 -1
  27. package/dist/core/agents/agent-runner-fake.js +40 -0
  28. package/dist/core/agents/agent-worker-pipeline.js +36 -2
  29. package/dist/core/agents/codex-exec-worker-adapter.js +2 -0
  30. package/dist/core/agents/native-cli-worker.js +0 -1
  31. package/dist/core/agents/native-worker-backend-router.js +58 -1
  32. package/dist/core/codex-app/sks-menubar.js +477 -132
  33. package/dist/core/codex-app.js +1 -0
  34. package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
  35. package/dist/core/codex-control/codex-sdk-env-policy.js +1 -1
  36. package/dist/core/codex-control/schemas/agent-worker-result.schema.js +12 -3
  37. package/dist/core/codex-hooks/codex-hook-managed-install.js +5 -0
  38. package/dist/core/codex-hooks/codex-hook-state-writer.js +70 -11
  39. package/dist/core/codex-hooks/codex-hook-trust-doctor.js +2 -2
  40. package/dist/core/codex-lb/codex-lb-env.js +20 -1
  41. package/dist/core/commands/basic-cli.js +18 -1
  42. package/dist/core/commands/check-command.js +37 -5
  43. package/dist/core/commands/computer-use-command.js +62 -7
  44. package/dist/core/commands/db-command.js +31 -5
  45. package/dist/core/commands/fast-mode-command.js +3 -0
  46. package/dist/core/commands/gate-result-contract.js +43 -0
  47. package/dist/core/commands/gates-command.js +6 -1
  48. package/dist/core/commands/gc-command.js +29 -2
  49. package/dist/core/commands/goal-command.js +9 -2
  50. package/dist/core/commands/gx-command.js +79 -7
  51. package/dist/core/commands/image-ux-review-command.js +188 -13
  52. package/dist/core/commands/mad-db-command.js +85 -176
  53. package/dist/core/commands/mad-sks-command.js +230 -29
  54. package/dist/core/commands/menubar-command.js +24 -2
  55. package/dist/core/commands/naruto-command.js +64 -10
  56. package/dist/core/commands/plan-command.js +76 -0
  57. package/dist/core/commands/ppt-command.js +159 -24
  58. package/dist/core/commands/qa-loop-command.js +6 -2
  59. package/dist/core/commands/release-command.js +55 -2
  60. package/dist/core/commands/research-command.js +1 -1
  61. package/dist/core/commands/review-command.js +217 -0
  62. package/dist/core/commands/route-success-helpers.js +59 -0
  63. package/dist/core/commands/run-command.js +19 -7
  64. package/dist/core/commands/seo-command.js +49 -1
  65. package/dist/core/commands/ui-command.js +161 -0
  66. package/dist/core/commands/uninstall-command.js +15 -1
  67. package/dist/core/db-safety.js +2 -2
  68. package/dist/core/doctor/doctor-dirty-planner.js +51 -7
  69. package/dist/core/doctor/doctor-transaction.js +8 -0
  70. package/dist/core/doctor/doctor-zellij-repair.js +1 -0
  71. package/dist/core/doctor/imagegen-repair.js +161 -0
  72. package/dist/core/feature-fixture-runner.js +2 -2
  73. package/dist/core/feature-fixtures.js +58 -37
  74. package/dist/core/feature-registry.js +102 -2
  75. package/dist/core/fsx.js +39 -6
  76. package/dist/core/image-ux-review/imagegen-adapter.js +48 -11
  77. package/dist/core/image-ux-review.js +16 -0
  78. package/dist/core/imagegen/imagegen-capability.js +11 -5
  79. package/dist/core/imagegen/require-imagegen.js +57 -0
  80. package/dist/core/init/skills.js +10 -5
  81. package/dist/core/mad-db/mad-db-coordinator.js +94 -18
  82. package/dist/core/mad-db/mad-db-policy.js +12 -10
  83. package/dist/core/mad-sks/executors/executor-base.js +8 -2
  84. package/dist/core/mad-sks/executors/index.js +4 -0
  85. package/dist/core/mad-sks/executors/sql-plane-executor.js +194 -0
  86. package/dist/core/naruto/naruto-active-pool.js +15 -4
  87. package/dist/core/naruto/naruto-real-worker-child.js +11 -1
  88. package/dist/core/naruto/naruto-role-policy.js +3 -0
  89. package/dist/core/naruto/naruto-task-hints.js +10 -0
  90. package/dist/core/naruto/naruto-work-graph.js +8 -2
  91. package/dist/core/naruto/naruto-work-item.js +6 -0
  92. package/dist/core/naruto/solution-tournament.js +101 -0
  93. package/dist/core/permission-gates.js +30 -0
  94. package/dist/core/pipeline-internals/runtime-core.js +11 -3
  95. package/dist/core/pipeline-internals/runtime-gates.js +27 -0
  96. package/dist/core/ppt-review/index.js +6 -1
  97. package/dist/core/ppt-review/slide-imagegen-review.js +75 -10
  98. package/dist/core/ppt.js +70 -2
  99. package/dist/core/proof/auto-finalize.js +70 -11
  100. package/dist/core/proof/proof-schema.js +2 -0
  101. package/dist/core/proof/route-adapter.js +5 -1
  102. package/dist/core/proof/route-finalizer.js +8 -5
  103. package/dist/core/proof/selftest-proof-fixtures.js +18 -5
  104. package/dist/core/proof/validation.js +2 -0
  105. package/dist/core/provider/model-router.js +53 -0
  106. package/dist/core/release/release-gate-node.js +3 -0
  107. package/dist/core/release/release-gate-resource-governor.js +1 -0
  108. package/dist/core/routes/constants.js +1 -1
  109. package/dist/core/routes.js +65 -18
  110. package/dist/core/safety/mutation-guard.js +5 -1
  111. package/dist/core/stop-gate/gate-evaluator.js +102 -0
  112. package/dist/core/stop-gate/stop-gate-check.js +16 -1
  113. package/dist/core/stop-gate/stop-gate-writer.js +4 -0
  114. package/dist/core/triwiki/agents-md-projector.js +184 -0
  115. package/dist/core/triwiki-wrongness/wrongness-schema.js +3 -1
  116. package/dist/core/trust-kernel/trust-kernel-schema.js +1 -0
  117. package/dist/core/trust-kernel/trust-report.js +1 -1
  118. package/dist/core/trust-kernel/trust-status.js +2 -0
  119. package/dist/core/ui/dashboard-html.js +111 -0
  120. package/dist/core/update/update-migration-state.js +386 -15
  121. package/dist/core/update-check.js +178 -81
  122. package/dist/core/verification/diff-quality.js +100 -0
  123. package/dist/core/verification/impact-scan.js +164 -0
  124. package/dist/core/verification/machine-feedback.js +146 -0
  125. package/dist/core/verification/mistake-rule-compiler.js +195 -0
  126. package/dist/core/version.js +1 -1
  127. package/dist/core/zellij/zellij-self-heal.js +9 -6
  128. package/dist/core/zellij/zellij-slot-telemetry.js +1 -1
  129. package/dist/scripts/check-feature-quality.js +2 -2
  130. package/dist/scripts/cli-output-consistency-check.js +57 -0
  131. package/dist/scripts/coding-bench-check.js +136 -0
  132. package/dist/scripts/doctor-imagegen-repair-check.js +62 -0
  133. package/dist/scripts/ensure-bin-executable.js +11 -3
  134. package/dist/scripts/harness-benchmark-check.js +104 -0
  135. package/dist/scripts/legacy-update-e2e-check.js +228 -0
  136. package/dist/scripts/mad-db-command-check.js +11 -8
  137. package/dist/scripts/mad-db-route-identity-check.js +8 -6
  138. package/dist/scripts/mad-db-safety-conflict-matrix-check.js +31 -8
  139. package/dist/scripts/mad-db-skill-policy-snapshot-check.js +4 -5
  140. package/dist/scripts/naruto-real-active-pool-runtime-check.js +26 -1
  141. package/dist/scripts/ppt-real-imagegen-wiring-check.js +5 -1
  142. package/dist/scripts/proof-root-cause-policy-check.js +2 -0
  143. package/dist/scripts/release-dag-full-coverage-check.js +13 -4
  144. package/dist/scripts/release-gate-dag-runner.js +14 -0
  145. package/dist/scripts/release-gate-existence-audit.js +2 -1
  146. package/dist/scripts/release-gate-planner.js +2 -1
  147. package/dist/scripts/release-gate-script-parity-check.js +45 -17
  148. package/dist/scripts/release-metadata-1-19-check.js +2 -1
  149. package/dist/scripts/seo-geo-feature-fixture-quality-check.js +1 -1
  150. package/dist/scripts/sks-1-11-gate-lib.js +8 -6
  151. package/dist/scripts/sks-menubar-install-check.js +57 -20
  152. package/dist/scripts/ux-review-real-loop-fixture-check.js +9 -4
  153. package/dist/scripts/ux-review-run-wires-imagegen-check.js +4 -0
  154. package/dist/scripts/zellij-slot-telemetry-runtime-check.js +1 -0
  155. package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
  156. package/docs/demo.tape +28 -0
  157. package/package.json +31 -24
  158. package/schemas/codex/completion-proof.schema.json +3 -2
  159. package/schemas/release/release-gate-node.schema.json +2 -1
  160. package/dist/scripts/agent-backfill-route-blackbox.js +0 -5
  161. package/dist/scripts/agent-dynamic-pool-route-blackbox.js +0 -5
  162. package/dist/scripts/agent-parallel-write-blackbox.js +0 -56
  163. package/dist/scripts/agent-patch-swarm-route-blackbox.js +0 -10
  164. package/dist/scripts/agent-route-blackbox-lib.js +0 -132
  165. package/dist/scripts/blackbox-command-import-smoke.js +0 -143
  166. package/dist/scripts/blackbox-global-shim.js +0 -77
  167. package/dist/scripts/blackbox-matrix.js +0 -70
  168. package/dist/scripts/blackbox-npx-one-shot.js +0 -69
  169. package/dist/scripts/blackbox-pack-install.js +0 -174
  170. package/dist/scripts/brand-neutrality-zero-leakage-blackbox.js +0 -4
  171. package/dist/scripts/build-once-runner-blackbox.js +0 -34
  172. package/dist/scripts/codex-0140-integration-blackbox.js +0 -13
  173. package/dist/scripts/codex-agent-type-blackbox.js +0 -4
  174. package/dist/scripts/codex-app-harness-blackbox.js +0 -4
  175. package/dist/scripts/codex-app-skill-agent-blackbox.js +0 -4
  176. package/dist/scripts/codex-hook-approval-blackbox.js +0 -4
  177. package/dist/scripts/codex-init-deep-directory-local-blackbox.js +0 -4
  178. package/dist/scripts/codex-native-feature-broker-blackbox.js +0 -4
  179. package/dist/scripts/codex-native-pattern-analysis-blackbox.js +0 -4
  180. package/dist/scripts/codex-native-read-repair-split-blackbox.js +0 -55
  181. package/dist/scripts/codex-native-reference-cache-blackbox.js +0 -41
  182. package/dist/scripts/core-skill-integrity-blackbox.js +0 -32
  183. package/dist/scripts/dfix-fast-blackbox-check.js +0 -37
  184. package/dist/scripts/dfix-parallel-write-blackbox.js +0 -48
  185. package/dist/scripts/dfix-patch-swarm-route-blackbox.js +0 -10
  186. package/dist/scripts/doctor-dirty-repair-blackbox.js +0 -22
  187. package/dist/scripts/doctor-dirty-semantic-blackbox.js +0 -8
  188. package/dist/scripts/doctor-native-capability-repair-blackbox.js +0 -39
  189. package/dist/scripts/doctor-transaction-engine-blackbox.js +0 -28
  190. package/dist/scripts/doctor-zellij-fix-blackbox.js +0 -4
  191. package/dist/scripts/doctor-zellij-no-homebrew-blackbox.js +0 -4
  192. package/dist/scripts/doctor-zellij-upgrade-blackbox.js +0 -4
  193. package/dist/scripts/gate-pack-runner-blackbox.js +0 -27
  194. package/dist/scripts/gate-pack-v2-blackbox.js +0 -18
  195. package/dist/scripts/geo-cli-blackbox-check.js +0 -18
  196. package/dist/scripts/loop-collision-blackbox.js +0 -3
  197. package/dist/scripts/loop-concurrency-oversubscription-blackbox.js +0 -3
  198. package/dist/scripts/loop-fixture-production-misuse-blackbox.js +0 -3
  199. package/dist/scripts/loop-kill-interrupt-real-blackbox.js +0 -3
  200. package/dist/scripts/loop-merge-strategy-blackbox.js +0 -3
  201. package/dist/scripts/loop-mesh-production-e2e-blackbox.js +0 -3
  202. package/dist/scripts/loop-side-effect-blackbox.js +0 -3
  203. package/dist/scripts/mad-db-operation-lifecycle-blackbox.js +0 -29
  204. package/dist/scripts/mad-sks-actual-executor-blackbox.js +0 -5
  205. package/dist/scripts/mad-zellij-headless-fallback-blackbox.js +0 -4
  206. package/dist/scripts/mad-zellij-self-heal-blackbox.js +0 -4
  207. package/dist/scripts/naruto-loop-mesh-blackbox.js +0 -3
  208. package/dist/scripts/naruto-real-parallelism-blackbox.js +0 -307
  209. package/dist/scripts/naruto-worktree-coding-blackbox.js +0 -29
  210. package/dist/scripts/parallel-runtime-real-blackbox.js +0 -44
  211. package/dist/scripts/pipeline-codex-native-doctor-mad-routing-real-blackbox.js +0 -77
  212. package/dist/scripts/pipeline-codex-native-e2e-blackbox.js +0 -13
  213. package/dist/scripts/pipeline-codex-native-image-routing-real-blackbox.js +0 -50
  214. package/dist/scripts/pipeline-codex-native-loop-routing-real-blackbox.js +0 -74
  215. package/dist/scripts/pipeline-codex-native-qa-routing-real-blackbox.js +0 -51
  216. package/dist/scripts/pipeline-codex-native-research-routing-real-blackbox.js +0 -45
  217. package/dist/scripts/pipeline-execution-profile-routing-blackbox.js +0 -4
  218. package/dist/scripts/postinstall-global-doctor-blackbox.js +0 -12
  219. package/dist/scripts/ppt-full-e2e-blackbox-check.js +0 -109
  220. package/dist/scripts/ppt-imagegen-blackbox-check.js +0 -46
  221. package/dist/scripts/qa-backfill-route-blackbox.js +0 -5
  222. package/dist/scripts/qa-patch-swarm-route-blackbox.js +0 -10
  223. package/dist/scripts/release-full-parallelism-blackbox.js +0 -41
  224. package/dist/scripts/release-triwiki-first-runner-blackbox.js +0 -48
  225. package/dist/scripts/release-wiring-3110-blackbox.js +0 -27
  226. package/dist/scripts/release-wiring-3112-blackbox.js +0 -17
  227. package/dist/scripts/release-wiring-3113-blackbox.js +0 -17
  228. package/dist/scripts/research-backfill-route-blackbox.js +0 -5
  229. package/dist/scripts/research-final-reviewer-blackbox.js +0 -70
  230. package/dist/scripts/research-stage-cycle-runtime-blackbox.js +0 -40
  231. package/dist/scripts/research-synthesis-writer-blackbox.js +0 -24
  232. package/dist/scripts/route-blackbox-realism-check.js +0 -21
  233. package/dist/scripts/scheduler-resource-claim-blackbox.js +0 -24
  234. package/dist/scripts/seo-cli-blackbox-check.js +0 -18
  235. package/dist/scripts/sks-3110-all-feature-regression-blackbox.js +0 -116
  236. package/dist/scripts/sks-3112-all-feature-regression-blackbox.js +0 -29
  237. package/dist/scripts/sks-3113-all-feature-regression-blackbox.js +0 -17
  238. package/dist/scripts/sks-400-all-feature-regression-blackbox.js +0 -21
  239. package/dist/scripts/sks-400-extreme-parallel-blackbox.js +0 -8
  240. package/dist/scripts/sks-400-five-minute-blackbox.js +0 -9
  241. package/dist/scripts/sks-400-legacy-purge-blackbox.js +0 -8
  242. package/dist/scripts/sks-401-all-feature-regression-blackbox.js +0 -46
  243. package/dist/scripts/sks-401-five-minute-actual-blackbox.js +0 -23
  244. package/dist/scripts/sks-402-all-feature-regression-blackbox.js +0 -9
  245. package/dist/scripts/sks-402-five-minute-real-blackbox.js +0 -22
  246. package/dist/scripts/sksd-warm-cache-blackbox.js +0 -12
  247. package/dist/scripts/team-backfill-route-blackbox.js +0 -5
  248. package/dist/scripts/team-parallel-write-blackbox.js +0 -55
  249. package/dist/scripts/team-patch-swarm-route-blackbox.js +0 -10
  250. package/dist/scripts/triwiki-affected-graph-blackbox.js +0 -28
  251. package/dist/scripts/triwiki-proof-bank-blackbox.js +0 -30
  252. package/dist/scripts/triwiki-proof-bank-lock-blackbox.js +0 -7
  253. package/dist/scripts/ux-patch-swarm-route-blackbox.js +0 -10
  254. package/dist/scripts/ux-review-imagegen-blackbox-check.js +0 -67
  255. package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -28
  256. package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -80
  257. package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -137
  258. package/dist/scripts/zellij-self-heal-typed-blackbox.js +0 -4
  259. package/dist/scripts/zellij-slot-telemetry-real-blackbox.js +0 -20
  260. package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -81
  261. package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -202
@@ -67,6 +67,7 @@ import { crossRebaseIdleWorktrees } from '../git/git-worktree-cross-rebase.js';
67
67
  import { gitOutputLine, runGitCommand } from '../git/git-worktree-runner.js';
68
68
  import { writeParallelRuntimeProof } from './parallel-runtime-proof.js';
69
69
  import { enforceRetention } from '../retention.js';
70
+ import { APPROACHES, rank, scoreCandidate, summarizeTournament } from '../naruto/solution-tournament.js';
70
71
  export async function runNativeAgentOrchestrator(opts = {}) {
71
72
  const root = path.resolve(opts.root || process.cwd());
72
73
  const sessionKey = opts.sessionKey || null;
@@ -427,6 +428,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
427
428
  workerWorktree,
428
429
  runtime: gitWorktreeRuntime
429
430
  });
431
+ enforceWorkerQualityProtocolForSlice(result, runtimeSlice);
430
432
  const terminalClose = await closeAgentTerminalSession(ledgerRoot, agent, {
431
433
  exitCode: result.status === 'done' ? 0 : 1,
432
434
  status: result.status,
@@ -498,7 +500,9 @@ export async function runNativeAgentOrchestrator(opts = {}) {
498
500
  proofMode: opts.mock === true ? 'mock-process' : 'production',
499
501
  requireWorkerPids: opts.nativeCliSwarm !== false && targetActiveSlots >= 16
500
502
  });
501
- const results = scheduler.results;
503
+ let results = scheduler.results;
504
+ const tournamentSelection = await selectSolutionTournamentWinners(root, ledgerRoot, results);
505
+ results = tournamentSelection.results;
502
506
  const nativeCliSessionProof = await writeNativeCliSessionProof(ledgerRoot, {
503
507
  requestedAgents: Number(opts.agents || roster.agent_count || targetActiveSlots),
504
508
  targetActiveSlots,
@@ -596,8 +600,8 @@ export async function runNativeAgentOrchestrator(opts = {}) {
596
600
  route,
597
601
  routeCommand,
598
602
  routeBlackboxKind,
599
- requestedWorkItems: desiredWorkItemCount,
600
- minimumWorkItems,
603
+ requestedWorkItems: partition.task_graph?.desired_work_items || desiredWorkItemCount,
604
+ minimumWorkItems: partition.task_graph?.minimum_work_items || minimumWorkItems,
601
605
  targetActiveSlots,
602
606
  realParallel: backend === 'codex-sdk' && opts.mock !== true,
603
607
  visualLaneCount,
@@ -642,11 +646,11 @@ export async function runNativeAgentOrchestrator(opts = {}) {
642
646
  roster,
643
647
  partition: { ok: partition.ok, slice_count: partition.slices.length, lease_count: partition.leases.length, blockers: partition.blockers },
644
648
  task_graph: partition.task_graph?.route_work_count_summary || null,
645
- requested_work_items: desiredWorkItemCount,
649
+ requested_work_items: partition.task_graph?.desired_work_items || desiredWorkItemCount,
646
650
  actual_total_work_items: partition.task_graph?.total_work_items || partition.slices.length,
647
651
  target_active_slots: targetActiveSlots,
648
652
  visual_lane_count: visualLaneCount,
649
- minimum_work_items: minimumWorkItems,
653
+ minimum_work_items: partition.task_graph?.minimum_work_items || minimumWorkItems,
650
654
  scheduler,
651
655
  source_intelligence: sourceIntelligenceRef,
652
656
  goal_mode: goalModeRef,
@@ -699,6 +703,112 @@ function withFinalGptPatchEnvelopes(results, patchEnvelopes = []) {
699
703
  next[0] = { ...next[0], patch_envelopes: patchEnvelopes };
700
704
  return next;
701
705
  }
706
+ async function selectSolutionTournamentWinners(root, ledgerRoot, results) {
707
+ const groups = new Map();
708
+ for (const result of results || []) {
709
+ const groupId = String(result?.tournament?.group_id || result?.naruto_runtime?.tournament?.group_id || '');
710
+ if (!groupId || !Array.isArray(result?.patch_envelopes) || result.patch_envelopes.length === 0)
711
+ continue;
712
+ groups.set(groupId, [...(groups.get(groupId) || []), result]);
713
+ }
714
+ const tournamentReports = [];
715
+ for (const [groupId, rows] of groups) {
716
+ if (rows.length < 2)
717
+ continue;
718
+ const candidates = await Promise.all(rows.map(async (result, index) => {
719
+ const candidate = {
720
+ id: String(result?.task_slice_id || result?.naruto_runtime?.work_item_id || `${groupId}-cand${index + 1}`),
721
+ approach: String(result?.tournament?.approach || result?.naruto_runtime?.tournament?.approach || APPROACHES[index] || ''),
722
+ worktree: String(firstEnvelopeField(result, 'git_worktree')?.worktree_path || ''),
723
+ patch: { patch_envelopes: result.patch_envelopes || [] },
724
+ score: null,
725
+ result
726
+ };
727
+ candidate.score = await scoreCandidate(root, candidate).catch((err) => ({
728
+ machine_ok: false,
729
+ tests_passed: 0,
730
+ tests_failed: 1,
731
+ diff_lines: 999999,
732
+ new_symbols: 999,
733
+ impact_breaks: 999,
734
+ total: 999999,
735
+ error: err instanceof Error ? err.message : String(err)
736
+ }));
737
+ return candidate;
738
+ }));
739
+ const alive = candidates
740
+ .filter((candidate) => candidate.score?.machine_ok && candidate.score.impact_breaks === 0)
741
+ .sort((a, b) => rank(a.score) - rank(b.score));
742
+ const winner = alive[0] || null;
743
+ const tournamentResult = {
744
+ schema: 'sks.solution-tournament.v1',
745
+ winner,
746
+ reason: winner ? (alive.length === 1 ? 'single_survivor' : 'judge:deterministic-maintainer-score') : 'all_candidates_failed_machine_checks',
747
+ candidates
748
+ };
749
+ const summary = summarizeTournament(tournamentResult);
750
+ const reportRow = {
751
+ ...summary,
752
+ group_id: groupId,
753
+ judge_worker: alive.length > 1 ? 'deterministic-maintainer-score' : null,
754
+ loser_cleanup: []
755
+ };
756
+ tournamentReports.push(reportRow);
757
+ if (!winner) {
758
+ for (const candidate of candidates) {
759
+ candidate.result.status = 'blocked';
760
+ candidate.result.blockers = [...new Set([...(candidate.result.blockers || []), 'solution_tournament_all_candidates_failed'])];
761
+ }
762
+ continue;
763
+ }
764
+ for (const candidate of candidates) {
765
+ if (candidate === winner) {
766
+ candidate.result.tournament = { ...candidate.result.tournament, selection: summary, selected: true };
767
+ candidate.result.patch_envelopes = (candidate.result.patch_envelopes || []).map((envelope) => ({ ...envelope, tournament: summary }));
768
+ continue;
769
+ }
770
+ const cleanup = await cleanupTournamentLoserCandidate(root, candidate).catch((err) => ({ ok: false, blockers: ['tournament_loser_cleanup_failed:' + (err instanceof Error ? err.message : String(err))] }));
771
+ reportRow.loser_cleanup.push(cleanup);
772
+ candidate.result.patch_envelopes = [];
773
+ candidate.result.changed_files = [];
774
+ candidate.result.no_patch_reason = {
775
+ schema: 'sks.solution-tournament-loser.v1',
776
+ ok: true,
777
+ reason: 'solution_tournament_loser',
778
+ group_id: groupId,
779
+ winner_id: winner.id
780
+ };
781
+ candidate.result.tournament = { ...candidate.result.tournament, selection: summary, selected: false };
782
+ }
783
+ }
784
+ const report = {
785
+ schema: 'sks.solution-tournament-report.v1',
786
+ generated_at: nowIso(),
787
+ ok: tournamentReports.every((row) => row.winner_id),
788
+ tournament_count: tournamentReports.length,
789
+ tournaments: tournamentReports
790
+ };
791
+ await writeJsonAtomic(path.join(ledgerRoot, 'solution-tournament-report.json'), report);
792
+ return { results, report };
793
+ }
794
+ async function cleanupTournamentLoserCandidate(root, candidate) {
795
+ const envelope = (candidate.patch?.patch_envelopes || []).find((row) => row?.git_worktree?.worktree_path);
796
+ const meta = envelope?.git_worktree;
797
+ if (!meta?.worktree_path || !meta?.main_repo_root)
798
+ return { ok: true, action: 'no_worktree', candidate_id: candidate.id };
799
+ const remove = await runGitCommand(String(meta.main_repo_root || root), ['worktree', 'remove', '--force', String(meta.worktree_path)]);
800
+ if (remove.ok && meta.branch)
801
+ await runGitCommand(String(meta.main_repo_root || root), ['branch', '-D', String(meta.branch)]);
802
+ return {
803
+ schema: 'sks.solution-tournament-loser-cleanup.v1',
804
+ ok: remove.ok,
805
+ action: remove.ok ? 'removed' : 'remove_failed',
806
+ candidate_id: candidate.id,
807
+ worktree_path: meta.worktree_path,
808
+ branch: meta.branch || null,
809
+ blockers: remove.ok ? [] : ['git_worktree_remove_failed']
810
+ };
811
+ }
702
812
  function uniqueWritableSlicesForWorktrees(slices = [], limit) {
703
813
  const selected = [];
704
814
  const seenOwners = new Set();
@@ -723,65 +833,90 @@ function applyNarutoWorkGraphToPartition(partition, graph, roster, targetActiveS
723
833
  const sourceIntelligenceRefs = referenceWorkItem?.source_intelligence_refs || partition?.source_intelligence_refs || null;
724
834
  const goalModeRef = referenceWorkItem?.goal_mode_ref || partition?.goal_mode_ref || null;
725
835
  const strategyRefs = referenceWorkItem?.strategy_refs || partition?.strategy_refs || null;
726
- const slices = (graph.work_items || []).map((item, index) => {
836
+ const slices = (graph.work_items || []).flatMap((item, index) => {
837
+ const candidateCount = item?.write_allowed && Number(item?.tournament || 0) >= 2
838
+ ? Math.min(4, Math.max(2, Math.floor(Number(item.tournament))))
839
+ : 1;
727
840
  const requestedOwner = item.owner ? String(item.owner) : '';
728
- const owner = requestedOwner && activeAgentIds.has(requestedOwner)
729
- ? requestedOwner
730
- : String(fallbackOwners[index % fallbackOwners.length]?.id || requestedOwner || `naruto_clone_${String(index + 1).padStart(3, '0')}`);
731
841
  const sliceId = String(item.id || `NW-${String(index + 1).padStart(6, '0')}`);
732
842
  const writePaths = normalizePathList(item.write_paths);
733
843
  const readonlyPaths = normalizePathList(item.readonly_paths);
734
844
  const targetPaths = normalizePathList(item.target_paths);
735
- const verificationNodeId = writePaths.length ? `verify:${sliceId}` : null;
736
- const rollbackNodeId = writePaths.length ? `rollback:${sliceId}` : null;
737
845
  const parentObjective = normalizeWorkerPromptText(parentPrompt);
738
- return {
739
- id: sliceId,
740
- owner_agent_id: owner,
741
- owner,
742
- lane: owner,
743
- role: String(item.required_role || 'verifier'),
744
- domain: String(item.allocation_hints?.domains?.[0] || item.kind || 'naruto'),
745
- title: String(item.title || item.id || `Naruto work ${index + 1}`),
746
- dependencies: Array.isArray(item.dependencies) ? item.dependencies.map(String) : [],
747
- priority: index + 1,
748
- required_persona_category: String(item.required_role || 'verifier'),
749
- lease_requirements: Array.isArray(item.lease_requirements) ? item.lease_requirements : [],
750
- generated_by: 'sks.naruto-work-graph.v1',
751
- route_domain: String(item.kind || 'naruto'),
752
- work_item_kind: String(item.kind || 'verification'),
753
- target_paths: targetPaths,
754
- readonly_paths: readonlyPaths,
755
- write_paths: writePaths,
756
- allocation_reason: item.allocation_reason || null,
757
- allocation_score: item.allocation_score ?? null,
758
- allocation_hints: item.allocation_hints || null,
759
- allocation_original_owner: requestedOwner || null,
760
- allocation_owner_rebalanced: Boolean(requestedOwner && owner !== requestedOwner),
761
- micro_win_id: sliceId,
762
- verification_node_id: verificationNodeId,
763
- rollback_node_id: rollbackNodeId,
764
- verification_required: item.verification_required === true,
765
- source_intelligence_refs: sourceIntelligenceRefs,
766
- goal_mode_ref: goalModeRef,
767
- strategy_refs: strategyRefs,
768
- parent_prompt: parentObjective,
769
- max_attempts: 1,
770
- description: [
771
- parentObjective ? `Parent Naruto objective:\n${parentObjective}` : null,
772
- String(item.title || item.id || 'Naruto work item'),
773
- `Naruto owner: ${owner}`,
774
- item.allocation_reason ? `Allocation: ${item.allocation_reason}` : null,
775
- writePaths.length ? `Write paths: ${writePaths.join(', ')}` : 'Read-only or no-write work item.',
776
- writePaths.length ? null : 'Read-only instruction: inspect the requested files/artifacts and do not run package scripts, build commands, tests, or temp-file-creating checks unless the parent objective explicitly requires them.'
777
- ].filter(Boolean).join('\n')
778
- };
846
+ return Array.from({ length: candidateCount }, (_unused, candidateOffset) => {
847
+ const candidateIndex = candidateOffset + 1;
848
+ const candidateSliceId = candidateCount > 1 ? `${sliceId}-cand${candidateIndex}` : sliceId;
849
+ const owner = requestedOwner && activeAgentIds.has(requestedOwner) && candidateCount === 1
850
+ ? requestedOwner
851
+ : String(fallbackOwners[(index + candidateOffset) % fallbackOwners.length]?.id || requestedOwner || `naruto_clone_${String(index + candidateIndex).padStart(3, '0')}`);
852
+ const verificationNodeId = writePaths.length ? `verify:${candidateSliceId}` : null;
853
+ const rollbackNodeId = writePaths.length ? `rollback:${candidateSliceId}` : null;
854
+ const approachDirective = candidateCount > 1 ? APPROACHES[candidateOffset] || APPROACHES[APPROACHES.length - 1] || '' : null;
855
+ return {
856
+ id: candidateSliceId,
857
+ owner_agent_id: owner,
858
+ owner,
859
+ lane: owner,
860
+ role: String(item.required_role || 'verifier'),
861
+ domain: String(item.allocation_hints?.domains?.[0] || item.kind || 'naruto'),
862
+ title: candidateCount > 1
863
+ ? `${String(item.title || item.id || `Naruto work ${index + 1}`)} (candidate ${candidateIndex}/${candidateCount})`
864
+ : String(item.title || item.id || `Naruto work ${index + 1}`),
865
+ dependencies: Array.isArray(item.dependencies) ? item.dependencies.map(String) : [],
866
+ priority: index + 1,
867
+ required_persona_category: String(item.required_role || 'verifier'),
868
+ lease_requirements: Array.isArray(item.lease_requirements) ? item.lease_requirements : [],
869
+ generated_by: 'sks.naruto-work-graph.v1',
870
+ route_domain: String(item.kind || 'naruto'),
871
+ work_item_kind: String(item.kind || 'verification'),
872
+ tournament_group_id: candidateCount > 1 ? sliceId : null,
873
+ tournament_candidate_index: candidateCount > 1 ? candidateIndex : null,
874
+ tournament_candidate_count: candidateCount > 1 ? candidateCount : null,
875
+ approach_directive: approachDirective,
876
+ target_paths: targetPaths,
877
+ readonly_paths: readonlyPaths,
878
+ write_paths: writePaths,
879
+ allocation_reason: item.allocation_reason || null,
880
+ allocation_score: item.allocation_score ?? null,
881
+ allocation_hints: item.allocation_hints || null,
882
+ allocation_original_owner: requestedOwner || null,
883
+ allocation_owner_rebalanced: Boolean(requestedOwner && owner !== requestedOwner),
884
+ micro_win_id: sliceId,
885
+ verification_node_id: verificationNodeId,
886
+ rollback_node_id: rollbackNodeId,
887
+ verification_required: item.verification_required === true,
888
+ source_intelligence_refs: sourceIntelligenceRefs,
889
+ goal_mode_ref: goalModeRef,
890
+ strategy_refs: strategyRefs,
891
+ parent_prompt: parentObjective,
892
+ max_attempts: 1,
893
+ description: [
894
+ parentObjective ? `Parent Naruto objective:\n${parentObjective}` : null,
895
+ String(item.title || item.id || 'Naruto work item'),
896
+ approachDirective ? `Solution tournament approach: ${approachDirective}` : null,
897
+ `Naruto owner: ${owner}`,
898
+ item.allocation_reason ? `Allocation: ${item.allocation_reason}` : null,
899
+ writePaths.length ? `Write paths: ${writePaths.join(', ')}` : 'Read-only or no-write work item.',
900
+ writePaths.length ? null : 'Read-only instruction: inspect the requested files/artifacts and do not run package scripts, build commands, tests, or temp-file-creating checks unless the parent objective explicitly requires them.'
901
+ ].filter(Boolean).join('\n')
902
+ };
903
+ });
779
904
  });
780
- const workItems = (graph.work_items || []).map((item) => ({
781
- ...item,
782
- source_intelligence_refs: item.source_intelligence_refs || sourceIntelligenceRefs,
783
- goal_mode_ref: item.goal_mode_ref || goalModeRef,
784
- strategy_refs: item.strategy_refs || strategyRefs
905
+ const workItems = slices.map((slice) => ({
906
+ id: slice.id,
907
+ kind: slice.work_item_kind || slice.route_domain || 'verification',
908
+ title: slice.title,
909
+ target_paths: slice.target_paths || [],
910
+ readonly_paths: slice.readonly_paths || [],
911
+ write_paths: slice.write_paths || [],
912
+ owner: slice.owner_agent_id,
913
+ tournament_group_id: slice.tournament_group_id || null,
914
+ tournament_candidate_index: slice.tournament_candidate_index || null,
915
+ tournament_candidate_count: slice.tournament_candidate_count || null,
916
+ approach_directive: slice.approach_directive || null,
917
+ source_intelligence_refs: sourceIntelligenceRefs,
918
+ goal_mode_ref: goalModeRef,
919
+ strategy_refs: strategyRefs
785
920
  }));
786
921
  const leases = slices.flatMap((slice) => [
787
922
  ...slice.write_paths.map((file, index) => ({
@@ -793,6 +928,7 @@ function applyNarutoWorkGraphToPartition(partition, graph, roster, targetActiveS
793
928
  status: 'active',
794
929
  owner_agent: slice.owner_agent_id,
795
930
  write_paths: slice.write_paths,
931
+ tournament_group_id: slice.tournament_group_id || null,
796
932
  strategy_task_id: slice.id,
797
933
  micro_win_id: slice.micro_win_id || slice.id,
798
934
  verification_node_id: slice.verification_node_id || null,
@@ -808,6 +944,7 @@ function applyNarutoWorkGraphToPartition(partition, graph, roster, targetActiveS
808
944
  status: 'active',
809
945
  owner_agent: slice.owner_agent_id,
810
946
  write_paths: slice.write_paths,
947
+ tournament_group_id: slice.tournament_group_id || null,
811
948
  strategy_task_id: slice.id,
812
949
  micro_win_id: slice.micro_win_id || slice.id,
813
950
  verification_node_id: slice.verification_node_id || null,
@@ -821,6 +958,8 @@ function applyNarutoWorkGraphToPartition(partition, graph, roster, targetActiveS
821
958
  ? {
822
959
  ...partition.task_graph,
823
960
  total_work_items: slices.length,
961
+ desired_work_items: slices.length,
962
+ minimum_work_items: Math.max(Number(partition.task_graph.minimum_work_items || 0), slices.length),
824
963
  work_items: workItems,
825
964
  route_work_count_summary: {
826
965
  ...(partition.task_graph.route_work_count_summary || {}),
@@ -893,12 +1032,13 @@ function augmentVerificationRollbackDagForNaruto(dag, slices) {
893
1032
  function buildNarutoRuntimeWiringProof(partition, graph, roster, targetActiveSlots) {
894
1033
  const activeAgentIds = new Set((Array.isArray(roster?.roster) ? roster.roster : []).slice(0, Math.max(1, targetActiveSlots)).map((row) => String(row.id || '')).filter(Boolean));
895
1034
  const slices = Array.isArray(partition?.slices) ? partition.slices : [];
896
- const activeWriteConflicts = slices.flatMap((slice) => normalizePathList(slice.write_paths));
897
- const duplicateActiveWrites = activeWriteConflicts.filter((file, index, all) => all.indexOf(file) !== index);
1035
+ const activeWriteConflicts = slices.flatMap((slice) => normalizePathList(slice.write_paths).map((file) => ({ file, tournament_group_id: slice.tournament_group_id || null })));
1036
+ const duplicateActiveWrites = activeWriteConflicts.filter((entry, index, all) => all.some((other, otherIndex) => otherIndex !== index && other.file === entry.file && !sameTournamentGroupEntry(entry, other)));
898
1037
  const ownerPreserved = slices.every((slice) => !slice.allocation_original_owner || slice.allocation_owner_rebalanced || slice.owner_agent_id === slice.allocation_original_owner);
899
1038
  const inactiveOwnersRebalanced = slices.every((slice) => !slice.allocation_original_owner || activeAgentIds.has(slice.allocation_original_owner) || slice.allocation_owner_rebalanced);
1039
+ const expectedSliceCount = (graph?.work_items || []).reduce((sum, item) => sum + (item?.write_allowed && Number(item?.tournament || 0) >= 2 ? Math.min(4, Math.max(2, Math.floor(Number(item.tournament)))) : 1), 0);
900
1040
  const blockers = [
901
- ...(slices.length === Number(graph?.work_items?.length || 0) ? [] : ['naruto_runtime_slice_count_mismatch']),
1041
+ ...(slices.length === expectedSliceCount ? [] : ['naruto_runtime_slice_count_mismatch']),
902
1042
  ...(ownerPreserved ? [] : ['naruto_runtime_owner_not_preserved']),
903
1043
  ...(inactiveOwnersRebalanced ? [] : ['naruto_runtime_inactive_owner_not_rebalanced']),
904
1044
  ...(duplicateActiveWrites.length ? ['naruto_runtime_duplicate_write_paths_in_partition'] : [])
@@ -924,6 +1064,9 @@ function buildNarutoRuntimeWiringProof(partition, graph, roster, targetActiveSlo
924
1064
  blockers
925
1065
  };
926
1066
  }
1067
+ function sameTournamentGroupEntry(a, b) {
1068
+ return Boolean(a?.tournament_group_id && b?.tournament_group_id && a.tournament_group_id === b.tournament_group_id);
1069
+ }
927
1070
  function attachNarutoRuntimeProof(result, agent, slice) {
928
1071
  const controlPlane = result?.codex_child_report || result?.codex_sdk_thread || result?.backend_router_report || null;
929
1072
  const selectedBackend = String(result?.backend_router_report?.selected_backend || result?.backend || '');
@@ -935,6 +1078,13 @@ function attachNarutoRuntimeProof(result, agent, slice) {
935
1078
  source_of_truth: 'agent-orchestrator-scheduler',
936
1079
  actual_worker_control_plane: actualWorkerControlPlane,
937
1080
  work_item_id: String(slice?.id || result?.task_slice_id || ''),
1081
+ work_item_kind: String(slice?.work_item_kind || result?.work_item_kind || ''),
1082
+ tournament: slice?.tournament_group_id ? {
1083
+ group_id: String(slice.tournament_group_id),
1084
+ candidate_index: Number(slice.tournament_candidate_index || 1),
1085
+ candidate_count: Number(slice.tournament_candidate_count || 1),
1086
+ approach: String(slice.approach_directive || '')
1087
+ } : null,
938
1088
  owner: String(slice?.owner_agent_id || slice?.owner || agent?.id || ''),
939
1089
  allocation_reason: slice?.allocation_reason || null,
940
1090
  rebalance_generation: Number(slice?.allocation_owner_rebalanced === true ? 1 : 0),
@@ -950,6 +1100,17 @@ function attachNarutoRuntimeProof(result, agent, slice) {
950
1100
  }
951
1101
  : null
952
1102
  };
1103
+ if (slice?.work_item_kind)
1104
+ result.work_item_kind = String(slice.work_item_kind);
1105
+ if (slice?.tournament_group_id) {
1106
+ result.tournament = {
1107
+ schema: 'sks.solution-tournament-candidate.v1',
1108
+ group_id: String(slice.tournament_group_id),
1109
+ candidate_index: Number(slice.tournament_candidate_index || 1),
1110
+ candidate_count: Number(slice.tournament_candidate_count || 1),
1111
+ approach: String(slice.approach_directive || '')
1112
+ };
1113
+ }
953
1114
  if (result.naruto_runtime.control_plane_result)
954
1115
  result.control_plane_result = result.naruto_runtime.control_plane_result;
955
1116
  result.verification = {
@@ -957,6 +1118,34 @@ function attachNarutoRuntimeProof(result, agent, slice) {
957
1118
  checks: [...(result.verification?.checks || []), 'naruto-agent-orchestrator-scheduler-source-of-truth']
958
1119
  };
959
1120
  }
1121
+ function enforceWorkerQualityProtocolForSlice(result, slice) {
1122
+ const writesPatch = Boolean((result.patch_envelopes || []).length || (result.changed_files || []).length || (result.writes || []).length);
1123
+ if (!writesPatch)
1124
+ return;
1125
+ const kind = String(slice?.work_item_kind || result?.work_item_kind || '').toLowerCase();
1126
+ const text = [kind, slice?.id, slice?.title].join(' ').toLowerCase();
1127
+ const blockers = [];
1128
+ if ((kind === 'bugfix' || /\b(fix|bug|regression|broken|failure|crash|error)\b|버그|회귀/.test(text)) && !validRegressionProof(result.regression_proof || firstEnvelopeField(result, 'regression_proof'))) {
1129
+ blockers.push('tdd_evidence_missing');
1130
+ }
1131
+ if ((kind === 'conflict_resolution' || /\b(repair|conflict|rebase|rollback)\b|수리|충돌/.test(text)) && !(result.repair_hypothesis || firstEnvelopeField(result, 'repair_hypothesis'))) {
1132
+ blockers.push('repair_without_hypothesis');
1133
+ }
1134
+ if (!blockers.length)
1135
+ return;
1136
+ result.status = 'blocked';
1137
+ result.blockers = [...new Set([...(result.blockers || []), ...blockers])];
1138
+ result.verification = {
1139
+ status: 'failed',
1140
+ checks: [...(result.verification?.checks || []), 'naruto-worker-quality-protocol']
1141
+ };
1142
+ }
1143
+ function firstEnvelopeField(result, field) {
1144
+ return (Array.isArray(result?.patch_envelopes) ? result.patch_envelopes : []).find((envelope) => envelope?.[field])?.[field] || null;
1145
+ }
1146
+ function validRegressionProof(proof) {
1147
+ return Boolean(proof && proof.failed_before === true && proof.passed_after === true && String(proof.test_file || '').trim());
1148
+ }
960
1149
  function normalizePathList(values) {
961
1150
  return (Array.isArray(values) ? values : []).map((file) => String(file || '').replace(/\\/g, '/').replace(/^\.\/+/, '').replace(/\/+$/, '')).filter(Boolean);
962
1151
  }
@@ -1045,6 +1234,13 @@ async function finalizeWorkerGitWorktree(input) {
1045
1234
  generationIndex: Math.max(1, Math.floor(Number(input.agent.generation_index || 1))),
1046
1235
  checkpoint
1047
1236
  });
1237
+ envelope.task_slice_id = String(input.slice.id || '');
1238
+ if (input.result.regression_proof)
1239
+ envelope.regression_proof = input.result.regression_proof;
1240
+ if (input.result.repair_hypothesis)
1241
+ envelope.repair_hypothesis = input.result.repair_hypothesis;
1242
+ if (input.result.tournament)
1243
+ envelope.tournament = input.result.tournament;
1048
1244
  input.result.patch_envelopes = [...(Array.isArray(input.result.patch_envelopes) ? input.result.patch_envelopes : []), envelope];
1049
1245
  input.result.changed_files = [...new Set([...(input.result.changed_files || []), ...diff.changed_files])];
1050
1246
  input.result.artifacts = [...new Set([...(input.result.artifacts || []), path.relative(input.ledgerRoot, path.join(input.workerWorktree.artifactDir, 'git-worktree-diff.json')), path.relative(input.ledgerRoot, path.join(input.workerWorktree.artifactDir, 'git-worktree-checkpoint.json'))])];
@@ -1132,7 +1328,14 @@ async function runAgentPatchSwarmRuntime(root, ledgerRoot, input) {
1132
1328
  ...envelope,
1133
1329
  agent_id: envelope.agent_id || result.agent_id,
1134
1330
  session_id: envelope.session_id || result.session_id
1135
- }, { mission_id: input.missionId, route: input.route });
1331
+ }, {
1332
+ mission_id: input.missionId,
1333
+ route: input.route,
1334
+ root,
1335
+ work_item_kind: result.work_item_kind || result.naruto_runtime?.work_item_kind,
1336
+ regression_proof: result.regression_proof,
1337
+ repair_hypothesis: result.repair_hypothesis
1338
+ });
1136
1339
  result.patch_queue_refs = [...(result.patch_queue_refs || []), entry.id];
1137
1340
  }
1138
1341
  }
@@ -1741,6 +1944,7 @@ async function runAgentByBackend(backend, agent, slice, opts) {
1741
1944
  model: agent.model || null,
1742
1945
  reasoningEffort: agent.reasoning_effort || null,
1743
1946
  modelReasoningEffort: agent.model_reasoning_effort || agent.reasoning_effort || null,
1947
+ serviceTier: agent.service_tier || opts.serviceTier || 'fast',
1744
1948
  inputFiles: Array.isArray(opts.inputFiles) ? opts.inputFiles.map(String) : [],
1745
1949
  inputImages: Array.isArray(opts.inputImages) ? opts.inputImages.map(String) : [],
1746
1950
  outputSchemaId: CODEX_AGENT_WORKER_RESULT_SCHEMA_ID,
@@ -1832,9 +2036,11 @@ function buildDirectSdkWorkerPrompt(slice) {
1832
2036
  const write = sdkWritePaths(slice, {});
1833
2037
  return [
1834
2038
  String(slice?.description || slice?.title || 'Complete the assigned worker task.'),
2039
+ slice?.work_item_kind ? `Work item kind: ${String(slice.work_item_kind)}.` : '',
2040
+ slice?.approach_directive ? `Solution tournament candidate directive: ${String(slice.approach_directive)}.` : '',
1835
2041
  '',
1836
2042
  write.length
1837
- ? `Write-capable slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}; include patch_envelopes for write_paths=${JSON.stringify(write)}. Each patch envelope must include schema, source "model_authored", agent_id, session_id, slot_id, generation_index, task_slice_id, lease_id, allowed_paths, operations, and rationale. Each operation must include op, path, search, replace, content, and diff; use empty strings for operation fields that do not apply.`
2043
+ ? `Write-capable slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}; include patch_envelopes for write_paths=${JSON.stringify(write)}. Each patch envelope must include schema, source "model_authored", agent_id, session_id, slot_id, generation_index, task_slice_id, lease_id, allowed_paths, operations, and rationale. Each operation must include op, path, search, replace, content, and diff; use empty strings for operation fields that do not apply. Impact-scan, machine-feedback, diff-quality, and mistake-rule gates run before queue acceptance; exported signature changes require cochanged callers or cochange_acknowledged_reason. Bugfixes require regression_proof failed_before true and passed_after true; repair patches require repair_hypothesis.`
1838
2044
  : `Read-only slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}; inspect relevant files/artifacts, do not mutate files, do not create temporary/build outputs, do not run package scripts/build/test commands unless explicitly required, and do not report pre-existing repository dirtiness as changed_files.`,
1839
2045
  'Required JSON fields: status, summary, findings, changed_files, patch_envelopes, verification, rollback_notes, blockers.'
1840
2046
  ].join('\n');
@@ -32,6 +32,7 @@ export const AGENT_RESULT_RUNTIME_SCHEMA = {
32
32
  session_id: { type: 'string', minLength: 1 },
33
33
  persona_id: { type: 'string' },
34
34
  task_slice_id: { type: 'string' },
35
+ work_item_kind: { type: 'string' },
35
36
  status: { enum: ['done', 'blocked', 'failed'] },
36
37
  backend: { enum: ['fake', 'process', 'codex-sdk', 'python-codex-sdk', 'zellij', 'ollama', 'local-llm'] },
37
38
  summary: { type: 'string' },
@@ -78,7 +79,7 @@ export const AGENT_RESULT_RUNTIME_SCHEMA = {
78
79
  required: ['schema', 'agent_id', 'session_id', 'slot_id', 'generation_index', 'operations'],
79
80
  properties: {
80
81
  schema: { const: 'sks.agent-patch-envelope.v1' },
81
- source: { enum: ['fixture', 'model_authored', 'process_generated', 'zellij_generated'] },
82
+ source: { enum: ['fixture', 'model_authored', 'process_generated', 'zellij_generated', 'git-worktree-diff'] },
82
83
  mission_id: { type: 'string' },
83
84
  route: { type: 'string' },
84
85
  agent_id: { type: 'string', minLength: 1 },
@@ -123,7 +124,7 @@ export const AGENT_RESULT_RUNTIME_SCHEMA = {
123
124
  type: 'object',
124
125
  required: ['op', 'path'],
125
126
  properties: {
126
- op: { enum: ['replace', 'write', 'unified_diff'] },
127
+ op: { enum: ['replace', 'write', 'unified_diff', 'git_apply_patch'] },
127
128
  path: { type: 'string', minLength: 1 },
128
129
  search: { type: 'string' },
129
130
  replace: { type: 'string' },
@@ -135,7 +136,13 @@ export const AGENT_RESULT_RUNTIME_SCHEMA = {
135
136
  },
136
137
  rationale: { type: 'string' },
137
138
  verification_hint: { type: 'object', additionalProperties: { type: 'string' } },
138
- rollback_hint: { type: 'object', additionalProperties: { type: 'string' } }
139
+ rollback_hint: { type: 'object', additionalProperties: { type: 'string' } },
140
+ cochange_acknowledged: { type: 'boolean' },
141
+ cochange_acknowledged_reason: { type: 'string' },
142
+ regression_proof: { type: 'object', additionalProperties: true },
143
+ repair_hypothesis: { type: 'object', additionalProperties: true },
144
+ tournament: { type: 'object', additionalProperties: true },
145
+ git_worktree: { type: 'object', additionalProperties: true }
139
146
  },
140
147
  additionalProperties: false
141
148
  }
@@ -151,6 +158,10 @@ export const AGENT_RESULT_RUNTIME_SCHEMA = {
151
158
  model_authored_patch_envelopes: { type: 'boolean' },
152
159
  fixture_patch_envelopes: { type: 'boolean' },
153
160
  no_patch_reason: { type: 'object', additionalProperties: true },
161
+ machine_feedback: { type: 'object', additionalProperties: true },
162
+ regression_proof: { type: 'object', additionalProperties: true },
163
+ repair_hypothesis: { type: 'object', additionalProperties: true },
164
+ tournament: { type: 'object', additionalProperties: true },
154
165
  follow_up_work_items: {
155
166
  type: 'array',
156
167
  items: {