sneakoscope 6.0.3 → 6.1.2

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 (378) hide show
  1. package/README.md +29 -12
  2. package/config/codex-releases/{rust-v0.142.0.json → rust-v0.144.1.json} +6 -6
  3. package/crates/sks-core/Cargo.lock +1 -1
  4. package/crates/sks-core/Cargo.toml +1 -1
  5. package/dist/bin/fast-inline.js +18 -14
  6. package/dist/bin/sks-dispatch.js +2 -4
  7. package/dist/cli/args.js +2 -0
  8. package/dist/cli/command-manifest-lite.js +2 -3
  9. package/dist/cli/command-registry.js +3 -4
  10. package/dist/cli/help-fast.js +1 -1
  11. package/dist/cli/install-helpers.js +348 -763
  12. package/dist/cli/install-tool-helpers.js +287 -0
  13. package/dist/cli/router.js +91 -6
  14. package/dist/commands/codex-lb.js +188 -53
  15. package/dist/commands/codex.js +44 -5
  16. package/dist/commands/doctor.js +302 -46
  17. package/dist/commands/tmux.js +5 -1
  18. package/dist/commands/versioning.js +7 -0
  19. package/dist/commands/zellij-monitor-pane.js +2 -0
  20. package/dist/commands/zellij-viewport-pane.js +3 -1
  21. package/dist/commands/zellij.js +1 -1
  22. package/dist/config/skills-manifest.json +59 -59
  23. package/dist/core/agent-bridge/agent-manifest.js +48 -0
  24. package/dist/core/agents/agent-central-ledger.js +9 -0
  25. package/dist/core/agents/agent-cleanup-executor.js +334 -41
  26. package/dist/core/agents/agent-cleanup.js +20 -1
  27. package/dist/core/agents/agent-command-surface.js +3 -1
  28. package/dist/core/agents/agent-effort-policy.js +30 -38
  29. package/dist/core/agents/agent-janitor.js +9 -10
  30. package/dist/core/agents/agent-namespace-safety.js +56 -0
  31. package/dist/core/agents/agent-orchestrator.js +25 -3
  32. package/dist/core/agents/agent-output-validator.js +1 -1
  33. package/dist/core/agents/agent-plan.js +100 -21
  34. package/dist/core/agents/agent-role-config.js +43 -49
  35. package/dist/core/agents/agent-runner-codex-exec.js +18 -3
  36. package/dist/core/agents/agent-runner-process.js +1 -0
  37. package/dist/core/agents/agent-schema.js +3 -2
  38. package/dist/core/agents/fast-mode-policy.js +3 -5
  39. package/dist/core/agents/native-cli-session-swarm.js +1 -1
  40. package/dist/core/agents/native-worker-backend-router.js +2 -1
  41. package/dist/core/agents/work-partition/repo-inventory.js +68 -7
  42. package/dist/core/agents/zellij-right-lane-cockpit.js +2 -2
  43. package/dist/core/code-structure.js +5 -4
  44. package/dist/core/codex/agent-config-file-repair.js +94 -193
  45. package/dist/core/codex/codex-cli-update.js +723 -0
  46. package/dist/core/codex/codex-config-guard.js +38 -11
  47. package/dist/core/codex/codex-project-config-policy.js +3 -6
  48. package/dist/core/codex/codex-startup-config-postcheck.js +52 -42
  49. package/dist/core/codex-adapter.js +35 -22
  50. package/dist/core/codex-app/codex-agent-role-sync.js +13 -54
  51. package/dist/core/codex-app/codex-app-fast-ui-repair.js +51 -20
  52. package/dist/core/codex-app/codex-app-launcher.js +48 -17
  53. package/dist/core/codex-app/codex-app-restart.js +23 -2
  54. package/dist/core/codex-app/codex-app-ui-state-snapshot.js +11 -3
  55. package/dist/core/codex-app/sks-menubar.js +136 -5
  56. package/dist/core/codex-app.js +35 -14
  57. package/dist/core/codex-compat/codex-hook-warning-detector.js +10 -1
  58. package/dist/core/codex-compat/codex-release-manifest.js +6 -6
  59. package/dist/core/codex-control/codex-0139-doctor-real-probe.js +7 -1
  60. package/dist/core/codex-control/codex-0139-image-path-real-probe.js +29 -12
  61. package/dist/core/codex-control/codex-0139-probe-runner.js +103 -28
  62. package/dist/core/codex-control/codex-0139-real-probe-summary.js +7 -3
  63. package/dist/core/codex-control/codex-0139-real-probes.js +21 -6
  64. package/dist/core/codex-control/codex-0139-sandbox-real-probe.js +39 -13
  65. package/dist/core/codex-control/codex-0139-web-search-probe.js +28 -14
  66. package/dist/core/codex-control/{codex-0142-capability.js → codex-0144-capability.js} +22 -22
  67. package/dist/core/codex-control/codex-0144-collab-agent-real-probe.js +63 -0
  68. package/dist/core/codex-control/codex-lb-launch-recovery.js +278 -0
  69. package/dist/core/codex-control/codex-multi-agent-event-normalizer.js +5 -1
  70. package/dist/core/codex-control/codex-reliability-shield.js +93 -30
  71. package/dist/core/codex-control/codex-sdk-adapter.js +96 -13
  72. package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
  73. package/dist/core/codex-control/codex-sdk-sandbox-policy.js +6 -3
  74. package/dist/core/codex-control/codex-task-runner.js +62 -9
  75. package/dist/core/codex-control/python-codex-sdk-adapter.js +30 -3
  76. package/dist/core/codex-exec-output-schema.js +35 -6
  77. package/dist/core/codex-lb/codex-lb-env.js +30 -1
  78. package/dist/core/codex-lb/codex-lb-tool-catalog.js +478 -0
  79. package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +291 -0
  80. package/dist/core/codex-native/codex-native-feature-broker.js +31 -38
  81. package/dist/core/codex-native/codex-native-feature-matrix.js +2 -2
  82. package/dist/core/codex-native/codex-native-repair-transaction.js +1 -1
  83. package/dist/core/codex-native/core-skill-manifest.js +8 -4
  84. package/dist/core/codex-native/native-capability-postcheck.js +16 -8
  85. package/dist/core/codex-native/native-capability-repair-matrix.js +76 -27
  86. package/dist/core/codex-plugins/codex-plugin-json.js +67 -21
  87. package/dist/core/codex-plugins/codex-plugin-repair.js +118 -0
  88. package/dist/core/codex-runtime/codex-desktop-config-policy.js +305 -0
  89. package/dist/core/commands/agent-bridge-command.js +23 -2
  90. package/dist/core/commands/agent-command.js +38 -5
  91. package/dist/core/commands/basic-cli.js +77 -30
  92. package/dist/core/commands/command-utils.js +1 -1
  93. package/dist/core/commands/gc-command.js +27 -4
  94. package/dist/core/commands/image-ux-review-command.js +55 -24
  95. package/dist/core/commands/mad-sks-command.js +182 -137
  96. package/dist/core/commands/naruto-command.js +643 -1153
  97. package/dist/core/commands/pipeline-command.js +1 -0
  98. package/dist/core/commands/research-command.js +293 -231
  99. package/dist/core/commands/run-command.js +100 -23
  100. package/dist/core/commands/team-command.js +2 -3
  101. package/dist/core/commands/team-legacy-observe-command.js +94 -359
  102. package/dist/core/commands/wiki-command.js +179 -83
  103. package/dist/core/computer-use-live-evidence.js +166 -3
  104. package/dist/core/computer-use-status.js +5 -2
  105. package/dist/core/daemon/sksd-hook-daemon-entrypoint.js +2 -2
  106. package/dist/core/daemon/sksd-hook-daemon.js +171 -28
  107. package/dist/core/daemon/sksd-hook-dispatch.js +2 -2
  108. package/dist/core/db-safety.js +2 -2
  109. package/dist/core/decision-lattice.js +6 -6
  110. package/dist/core/dfix/verification-selector.js +6 -4
  111. package/dist/core/doctor/browser-use-repair.js +54 -13
  112. package/dist/core/doctor/codex-0139-doctor.js +3 -2
  113. package/dist/core/doctor/codex-startup-config-repair.js +8 -3
  114. package/dist/core/doctor/computer-use-repair.js +28 -39
  115. package/dist/core/doctor/doctor-codex-startup-repair.js +24 -149
  116. package/dist/core/doctor/doctor-context7-repair.js +1 -1
  117. package/dist/core/doctor/doctor-dirty-planner.js +1 -1
  118. package/dist/core/doctor/doctor-native-capability-repair.js +74 -3
  119. package/dist/core/doctor/imagegen-repair.js +47 -12
  120. package/dist/core/doctor/legacy-global-hook-cleanup.js +179 -0
  121. package/dist/core/feature-fixture-executor.js +71 -7
  122. package/dist/core/feature-fixture-runner.js +53 -12
  123. package/dist/core/feature-fixtures.js +47 -14
  124. package/dist/core/feature-registry.js +53 -58
  125. package/dist/core/fsx.js +54 -6
  126. package/dist/core/harness-conflicts.js +19 -10
  127. package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +5 -4
  128. package/dist/core/hooks-runtime/hook-invocation-dedupe.js +147 -0
  129. package/dist/core/hooks-runtime/hook-io.js +14 -4
  130. package/dist/core/hooks-runtime/light-turn.js +70 -0
  131. package/dist/core/hooks-runtime/payload-signals.js +270 -0
  132. package/dist/core/hooks-runtime/team-digest.js +0 -1
  133. package/dist/core/hooks-runtime/tool-output-quarantine.js +93 -0
  134. package/dist/core/hooks-runtime.js +418 -250
  135. package/dist/core/image/image-artifact-path-contract.js +8 -6
  136. package/dist/core/image/image-artifact-registry.js +5 -1
  137. package/dist/core/image-ux-review/imagegen-adapter.js +5 -2
  138. package/dist/core/imagegen/imagegen-capability.js +10 -13
  139. package/dist/core/imagegen/require-imagegen.js +37 -11
  140. package/dist/core/init/skills.js +16 -30
  141. package/dist/core/init.js +144 -36
  142. package/dist/core/managed-assets/managed-assets-manifest.js +417 -14
  143. package/dist/core/mission.js +24 -1
  144. package/dist/core/naruto/naruto-work-graph.js +70 -4
  145. package/dist/core/ops/reporting.js +3 -0
  146. package/dist/core/pipeline-internals/runtime-core.js +578 -180
  147. package/dist/core/pipeline-internals/runtime-gates.js +191 -49
  148. package/dist/core/ppt/style-tokens.js +1 -1
  149. package/dist/core/ppt-review/index.js +1 -1
  150. package/dist/core/ppt-review/slide-exporter.js +23 -17
  151. package/dist/core/ppt-review/slide-imagegen-review.js +1 -1
  152. package/dist/core/ppt-review/slide-issue-extraction.js +4 -2
  153. package/dist/core/preflight/parallel-preflight-engine.js +50 -1
  154. package/dist/core/product-design-plugin.js +2 -2
  155. package/dist/core/proof/route-finalizer.js +1 -1
  156. package/dist/core/proof/route-proof-gate.js +7 -2
  157. package/dist/core/proof-field.js +3 -3
  158. package/dist/core/provider/model-router.js +38 -32
  159. package/dist/core/recallpulse/policy.js +12 -28
  160. package/dist/core/recallpulse.js +11 -6
  161. package/dist/core/release/gate-manifest.js +18 -12
  162. package/dist/core/release/gate-pack-manifest.js +1 -1
  163. package/dist/core/release/npm-pack-proof.js +247 -0
  164. package/dist/core/release/package-dist-snapshot.js +151 -0
  165. package/dist/core/release/package-size-budget.js +5 -0
  166. package/dist/core/release/release-authorization-snapshot.js +115 -0
  167. package/dist/core/release/release-gate-affected-selector.js +15 -3
  168. package/dist/core/release/release-gate-cache-v2.js +30 -0
  169. package/dist/core/release/release-gate-contract.js +161 -0
  170. package/dist/core/release/release-gate-dag.js +44 -3
  171. package/dist/core/release/release-gate-hermetic-env.js +28 -17
  172. package/dist/core/release/release-real-contract.js +496 -0
  173. package/dist/core/release-parallel-full-coverage.js +31 -143
  174. package/dist/core/research/claim-evidence-matrix.js +41 -6
  175. package/dist/core/research/experiment-plan.js +14 -10
  176. package/dist/core/research/falsification.js +9 -2
  177. package/dist/core/research/implementation-blueprint-densifier.js +82 -60
  178. package/dist/core/research/implementation-blueprint.js +32 -26
  179. package/dist/core/research/mock-result.js +122 -11
  180. package/dist/core/research/replication-pack.js +15 -8
  181. package/dist/core/research/research-adversarial-review.js +1068 -0
  182. package/dist/core/research/research-claim-builder.js +69 -17
  183. package/dist/core/research/research-claim-synthesizer.js +343 -0
  184. package/dist/core/research/research-cycle-runner.js +53 -3
  185. package/dist/core/research/research-falsification-runner.js +176 -0
  186. package/dist/core/research/research-final-reviewer.js +44 -125
  187. package/dist/core/research/research-realistic-report.js +14 -6
  188. package/dist/core/research/research-review-artifact-digest.js +66 -0
  189. package/dist/core/research/research-source-evidence.js +144 -0
  190. package/dist/core/research/research-source-layer-catalog.js +68 -0
  191. package/dist/core/research/research-source-ledger-merge.js +250 -12
  192. package/dist/core/research/research-source-shards.js +26 -70
  193. package/dist/core/research/research-stage-runner.js +237 -247
  194. package/dist/core/research/research-super-search.js +184 -0
  195. package/dist/core/research/research-synthesis-prompt.js +20 -1
  196. package/dist/core/research/research-synthesis-writer.js +86 -5
  197. package/dist/core/research/research-work-graph.js +25 -18
  198. package/dist/core/research/source-quality-report.js +21 -0
  199. package/dist/core/research.js +429 -280
  200. package/dist/core/retention/retention-budget.js +25 -6
  201. package/dist/core/retention.js +980 -101
  202. package/dist/core/routes/constants.js +1 -1
  203. package/dist/core/routes/dollar-manifest-lite.js +11 -11
  204. package/dist/core/routes/evidence.js +4 -4
  205. package/dist/core/routes/ppt-policy.js +1 -1
  206. package/dist/core/routes.js +92 -64
  207. package/dist/core/runtime/task-profile.js +66 -0
  208. package/dist/core/runtime/verification-budget.js +12 -0
  209. package/dist/core/secret-redaction.js +4 -0
  210. package/dist/core/security/high-risk-contracts.js +6 -6
  211. package/dist/core/stop-gate/stop-gate-check.js +49 -12
  212. package/dist/core/subagents/agent-catalog.js +215 -0
  213. package/dist/core/subagents/model-policy.js +118 -0
  214. package/dist/core/subagents/naruto-help-contract.js +40 -0
  215. package/dist/core/subagents/official-subagent-config.js +488 -0
  216. package/dist/core/subagents/official-subagent-preparation.js +251 -0
  217. package/dist/core/subagents/official-subagent-prompt.js +137 -0
  218. package/dist/core/subagents/official-subagent-runner.js +129 -0
  219. package/dist/core/subagents/subagent-evidence.js +663 -0
  220. package/dist/core/subagents/terminology.js +16 -0
  221. package/dist/core/subagents/thread-budget.js +21 -0
  222. package/dist/core/subagents/triwiki-attention.js +65 -0
  223. package/dist/core/super-search/runtime-helpers.js +173 -19
  224. package/dist/core/super-search/runtime.js +140 -15
  225. package/dist/core/super-search/source-records.js +49 -8
  226. package/dist/core/team-review-policy.js +15 -0
  227. package/dist/core/triwiki/code-pack.js +8 -2
  228. package/dist/core/triwiki/triwiki-cache-key.js +108 -29
  229. package/dist/core/triwiki/triwiki-module-card.js +1 -1
  230. package/dist/core/triwiki-attention.js +13 -6
  231. package/dist/core/triwiki-provenance.js +274 -0
  232. package/dist/core/triwiki-runtime.js +21 -7
  233. package/dist/core/triwiki-wrongness/wrongness-ledger.js +187 -61
  234. package/dist/core/triwiki-wrongness/wrongness-retrieval.js +11 -2
  235. package/dist/core/triwiki-wrongness/wrongness-trust-policy.js +2 -0
  236. package/dist/core/update-check.js +23 -15
  237. package/dist/core/version-manager.js +51 -1
  238. package/dist/core/version.js +1 -1
  239. package/dist/core/wiki-coordinate.js +128 -12
  240. package/dist/core/work-order-ledger.js +208 -10
  241. package/dist/core/zellij/zellij-command.js +12 -1
  242. package/dist/core/zellij/zellij-dashboard-pane.js +3 -3
  243. package/dist/core/zellij/zellij-fake-adapter.js +3 -1
  244. package/dist/core/zellij/zellij-launcher.js +51 -21
  245. package/dist/core/zellij/zellij-layout-builder.js +14 -5
  246. package/dist/core/zellij/zellij-official-subagent-activity.js +477 -0
  247. package/dist/core/zellij/zellij-official-subagent-telemetry.js +264 -0
  248. package/dist/core/zellij/zellij-pane-proof.js +32 -6
  249. package/dist/core/zellij/zellij-slot-pane-renderer.js +17 -5
  250. package/dist/core/zellij/zellij-slot-telemetry.js +15 -3
  251. package/dist/core/zellij/zellij-ui-mode.js +1 -1
  252. package/dist/core/zellij/zellij-viewport-binder.js +3 -0
  253. package/dist/core/zellij/zellij-worker-pane-manager.js +5 -3
  254. package/dist/scripts/agent-fast-mode-default-check.js +48 -29
  255. package/dist/scripts/agent-role-config-repair-check.js +34 -15
  256. package/dist/scripts/agent-wiki-context-proof-check.js +16 -2
  257. package/dist/scripts/all-feature-deep-completion-check.js +14 -4
  258. package/dist/scripts/architecture-guard-check.js +8 -1
  259. package/dist/scripts/build-dist.js +17 -5
  260. package/dist/scripts/canonical-test-runner.js +188 -0
  261. package/dist/scripts/check-command-module-budget.js +38 -16
  262. package/dist/scripts/check-legacy-free.js +1 -1
  263. package/dist/scripts/check-route-modularity.js +0 -1
  264. package/dist/scripts/check-ts-contracts.js +1 -1
  265. package/dist/scripts/codex-0139-interrupt-agent-check.js +5 -1
  266. package/dist/scripts/{codex-0142-app-server-v2-check.js → codex-0144-app-server-v2-check.js} +11 -10
  267. package/dist/scripts/{codex-0142-binary-identity-check.js → codex-0144-binary-identity-check.js} +4 -4
  268. package/dist/scripts/codex-0144-capability-check.js +21 -0
  269. package/dist/scripts/{codex-0139-real-probes-check.js → codex-0144-core-real-probes-check.js} +19 -5
  270. package/dist/scripts/{codex-0142-doctor-wiring-check.js → codex-0144-doctor-wiring-check.js} +6 -6
  271. package/dist/scripts/{codex-0142-manifest-check.js → codex-0144-manifest-check.js} +11 -3
  272. package/dist/scripts/{codex-0142-policy-check.js → codex-0144-policy-check.js} +2 -2
  273. package/dist/scripts/{codex-0142-thread-store-check.js → codex-0144-thread-store-check.js} +3 -3
  274. package/dist/scripts/codex-app-provider-model-ui-check.js +53 -19
  275. package/dist/scripts/codex-app-ui-preservation-check.js +35 -4
  276. package/dist/scripts/codex-control-all-pipelines-check.js +7 -3
  277. package/dist/scripts/codex-control-side-effect-scope-check.js +2 -2
  278. package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +27 -0
  279. package/dist/scripts/codex-effort-auto-discovery-check.js +1 -1
  280. package/dist/scripts/codex-lb-fast-mode-truth-check.js +1 -0
  281. package/dist/scripts/{codex-lb-gpt55-fast-profile-check.js → codex-lb-gpt56-fast-profile-check.js} +56 -5
  282. package/dist/scripts/codex-model-metadata-check.js +1 -1
  283. package/dist/scripts/codex-native-agent-role-content-check.js +15 -7
  284. package/dist/scripts/codex-native-repair-transaction-check.js +3 -1
  285. package/dist/scripts/codex-sdk-all-pipelines-check.js +7 -4
  286. package/dist/scripts/codex-sdk-research-pipeline-check.js +30 -8
  287. package/dist/scripts/codex-sdk-sandbox-policy-check.js +5 -1
  288. package/dist/scripts/codex-sdk-version-compat-check.js +2 -1
  289. package/dist/scripts/db-route-materialization-check.js +33 -0
  290. package/dist/scripts/dfix-fixture-check.js +1 -1
  291. package/dist/scripts/docs-truthfulness-check.js +4 -2
  292. package/dist/scripts/doctor-codex-startup-repair-check.js +47 -25
  293. package/dist/scripts/doctor-context7-repair-check.js +2 -1
  294. package/dist/scripts/doctor-fix-production-blackbox.js +12 -2
  295. package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +34 -7
  296. package/dist/scripts/doctor-imagegen-repair-check.js +14 -4
  297. package/dist/scripts/doctor-startup-config-repair-blackbox.js +9 -3
  298. package/dist/scripts/doctor-startup-config-repair-check.js +13 -3
  299. package/dist/scripts/install-update-preserves-config-check.js +7 -2
  300. package/dist/scripts/legacy-gate-inventory-check.js +7 -5
  301. package/dist/scripts/legacy-strong-inventory-check.js +7 -5
  302. package/dist/scripts/legacy-upgrade-matrix-check.js +4 -4
  303. package/dist/scripts/lib/native-cli-session-swarm-check-lib.js +173 -13
  304. package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +165 -6
  305. package/dist/scripts/managed-role-manifest-parity-check.js +5 -4
  306. package/dist/scripts/mutation-callsite-coverage-check.js +0 -11
  307. package/dist/scripts/naruto-codex-e2e-check.js +14 -7
  308. package/dist/scripts/naruto-shadow-clone-swarm-check.js +4 -201
  309. package/dist/scripts/npm-publish-performance-check.js +20 -12
  310. package/dist/scripts/official-subagent-workflow-check.js +145 -0
  311. package/dist/scripts/package-published-contract-check.js +6 -20
  312. package/dist/scripts/packlist-performance-check.js +17 -3
  313. package/dist/scripts/parallel-verification-engine-check.js +2 -2
  314. package/dist/scripts/postinstall-safe-side-effects-check.js +8 -3
  315. package/dist/scripts/ppt-no-mock-as-real-check.js +3 -1
  316. package/dist/scripts/prepublish-release-check-or-fast.js +23 -86
  317. package/dist/scripts/product-design-plugin-routing-check.js +1 -1
  318. package/dist/scripts/release-affected-selector-check.js +74 -1
  319. package/dist/scripts/release-check-stamp.js +324 -239
  320. package/dist/scripts/release-dag-full-coverage-check.js +7 -15
  321. package/dist/scripts/release-dynamic-presets-check.js +10 -1
  322. package/dist/scripts/release-gate-dag-runner-check.js +3 -3
  323. package/dist/scripts/release-gate-dag-runner.js +35 -11
  324. package/dist/scripts/release-gate-existence-audit.js +1 -2
  325. package/dist/scripts/release-gate-script-parity-check.js +1 -1
  326. package/dist/scripts/release-parallel-full-coverage-check.js +12 -6
  327. package/dist/scripts/release-parallel-speed-budget-check.js +18 -2
  328. package/dist/scripts/release-real-check.js +390 -157
  329. package/dist/scripts/release-registry-check.js +61 -16
  330. package/dist/scripts/release-runtime-truth-matrix-check.js +22 -0
  331. package/dist/scripts/research-blueprint-densifier-check.js +2 -2
  332. package/dist/scripts/research-real-cycle-no-legacy-final-md-check.js +11 -7
  333. package/dist/scripts/route-proof-artifact-structure-check.js +1 -0
  334. package/dist/scripts/search-visibility-gate-lib.js +1 -1
  335. package/dist/scripts/seo-geo-route-identity-check.js +30 -4
  336. package/dist/scripts/sizecheck.js +4 -4
  337. package/dist/scripts/sks-1-11-gate-lib.js +53 -6
  338. package/dist/scripts/sks-3-1-4-directive-check-lib.js +8 -2
  339. package/dist/scripts/sks-3-1-5-directive-check-lib.js +3 -2
  340. package/dist/scripts/sks-3-1-6-directive-check-lib.js +5 -3
  341. package/dist/scripts/sks-menubar-install-check.js +8 -0
  342. package/dist/scripts/sks-uninstall-regression-check.js +1 -1
  343. package/dist/scripts/sksd-daemon-check.js +16 -6
  344. package/dist/scripts/trust-fixture-check.js +32 -10
  345. package/dist/scripts/write-build-manifest.js +2 -1
  346. package/dist/scripts/wrongness-fixture-check.js +1 -1
  347. package/dist/scripts/zellij-layout-valid-check.js +36 -11
  348. package/dist/scripts/zellij-pane-proof-check.js +33 -2
  349. package/dist/scripts/zellij-real-session-cleanup-check.js +122 -2
  350. package/dist/scripts/zellij-real-session-launch-check.js +76 -5
  351. package/dist/scripts/zellij-slot-pane-renderer-check.js +4 -4
  352. package/dist/scripts/zellij-spawn-on-demand-layout-check.js +3 -3
  353. package/docs/demo.tape +1 -1
  354. package/infra-harness-gates.json +1486 -0
  355. package/package.json +32 -19
  356. package/release-gates.v2.json +4060 -0
  357. package/runtime-required-scripts.json +9 -0
  358. package/schemas/codex/{app-server-0.142 → app-server-0.144}/codex_app_server_protocol.v2.schemas.json +1146 -781
  359. package/schemas/codex/codex-0139-real-probe-result.schema.json +39 -5
  360. package/schemas/codex/ppt-slide-issue-ledger.schema.json +2 -1
  361. package/dist/commands/db.js +0 -6
  362. package/dist/core/codex-control/codex-0139-multi-agent-real-probe.js +0 -107
  363. package/dist/core/commands/db-command.js +0 -146
  364. package/dist/core/research/prompt.js +0 -15
  365. package/dist/scripts/agent-native-release-gate.js +0 -274
  366. package/dist/scripts/codex-0142-capability-check.js +0 -21
  367. package/dist/scripts/codex-control-tool-call-sequence-repair-check.js +0 -14
  368. package/dist/scripts/command-performance-scorecard-check.js +0 -204
  369. package/dist/scripts/config-managed-merge-callsite-coverage-check.js +0 -212
  370. package/dist/scripts/dollar-performance-scorecard-check.js +0 -257
  371. package/dist/scripts/gate-timing-check.js +0 -16
  372. package/dist/scripts/ops-maturity-scorecard-check.js +0 -12
  373. package/dist/scripts/performance-baseline-check.js +0 -12
  374. package/dist/scripts/performance-improvement-report-check.js +0 -58
  375. package/dist/scripts/release-parallel-check.js +0 -389
  376. package/dist/scripts/release-runner-efficiency-check.js +0 -15
  377. package/dist/scripts/retention-long-run-smoke-check.js +0 -299
  378. package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
@@ -16,9 +16,20 @@ import { appendMissionStatus } from './recallpulse.js';
16
16
  import { scanAgentTextForRecursion } from './agents/agent-recursion-guard.js';
17
17
  import { evaluateLoopContinuation } from './loops/loop-continuation-enforcer.js';
18
18
  import { diagnosticPromptAllowedDuringNoQuestions } from './routes/diagnostic-allowlist.js';
19
+ import { closeWorkOrderLedgerForRouteResult } from './work-order-ledger.js';
19
20
  import { maybeReconcileProjectSkillsPreflight } from './hooks-runtime/skill-reconcile-preflight.js';
20
21
  import { codePackFreshnessNote } from './hooks-runtime/code-pack-freshness-preflight.js';
22
+ import { claimHookInvocation } from './hooks-runtime/hook-invocation-dedupe.js';
21
23
  import { joinSystemMessages, teamLiveDigest } from './hooks-runtime/team-digest.js';
24
+ import { armLightTurnStopBypass, clearLightTurnStopBypass, consumeLightTurnStopBypass, hasMatchingLightTurnStopBypass } from './hooks-runtime/light-turn.js';
25
+ import { classifyTaskProfile } from './runtime/task-profile.js';
26
+ import { resolveSubagentThreadBudget } from './subagents/thread-budget.js';
27
+ import { readOfficialSubagentConfig } from './subagents/official-subagent-config.js';
28
+ import { withFileLock } from './locks/file-lock.js';
29
+ import { NARUTO_PARENT_EFFORT, NARUTO_PARENT_MODEL } from './subagents/model-policy.js';
30
+ import { officialSubagentRolePlan } from './subagents/agent-catalog.js';
31
+ import { recordOfficialSubagentParentOutcomesTelemetry, recordOfficialSubagentZellijTelemetry } from './zellij/zellij-official-subagent-telemetry.js';
32
+ import { bindTrustworthySubagentParentSummaryToRun, normalizeSubagentParentSummary, persistOrReuseTrustworthySubagentParentSummary, readSubagentEvents, recordSubagentEvent, SUBAGENT_EVIDENCE_FILENAME, SUBAGENT_PARENT_SUMMARY_FILENAME, writeSubagentEvidence } from './subagents/subagent-evidence.js';
22
33
  const STOP_REPEAT_GUARD_ARTIFACT = 'stop-hook-repeat-guard.json';
23
34
  const LIGHT_ROUTE_STOP_ARTIFACT = 'light-route-stop.json';
24
35
  const CODEX_GIT_ACTION_STOP_ARTIFACT = 'codex-git-action-stop-bypass.json';
@@ -31,6 +42,8 @@ const UPDATE_CHECK_HOOK_INVOCATION_POLICY = 'function-only:no-runSksUpdateCheck-
31
42
  // by release readiness so ordinary Codex hook flow cannot grow a hidden update
32
43
  // prompt path.
33
44
  import { loadHookPayload, normalizeHookResult, visibleHookMessage } from './hooks-runtime/hook-io.js';
45
+ import { codexGitActionMetadataSignal, codexGitActionMetadataText, compactAnswerContext, conversationId, explicitConversationId, extractCommand, extractLastMessage, extractUserPrompt, hookTurnId, looksLikeCodexGitAction, looksLikeCodexGitActionStopCompletion, looksLikeCodexUiSettingsEvent, looksLikeMadSksConfirmationPrompt, observedParentModel, observedParentModelMismatch, toolFailed } from './hooks-runtime/payload-signals.js';
46
+ import { interruptedToolOutputRecoveryBlockReason, missingToolOutputCallId, missingToolOutputCallIdFromPayload, quarantineMissingToolOutput, readToolOutputQuarantine } from './hooks-runtime/tool-output-quarantine.js';
34
47
  export { loadHookPayload, normalizeHookResult };
35
48
  async function loadState(root, payload = {}) {
36
49
  return loadStateForSession(root, conversationId(payload));
@@ -39,142 +52,39 @@ function isNoQuestionRunning(state) {
39
52
  return (state.mode === 'RESEARCH' && state.phase === 'RESEARCH_RUNNING_NO_QUESTIONS')
40
53
  || (state.mode === 'QALOOP' && state.phase === 'QALOOP_RUNNING_NO_QUESTIONS');
41
54
  }
42
- function extractLastMessage(payload) {
43
- return payload.last_assistant_message || payload.assistant_message || payload.message || payload.response || payload.raw || '';
44
- }
45
- function extractUserPrompt(payload) {
46
- return payload.prompt
47
- || payload.user_prompt
48
- || payload.userPrompt
49
- || payload.message
50
- || payload.input?.prompt
51
- || payload.input?.message
52
- || payload.raw
53
- || '';
54
- }
55
- function conversationId(payload) {
56
- return String(payload.conversation_id || payload.thread_id || payload.session_id || payload.chat_id || payload.cwd || 'default');
57
- }
58
- function explicitConversationId(payload = {}) {
59
- return payload.conversation_id || payload.thread_id || payload.session_id || payload.chat_id || null;
60
- }
61
- function extractCommand(payload) {
62
- return payload.command || payload.tool_input?.command || payload.toolInput?.command || payload.input?.command || payload.tool?.input?.command || '';
55
+ export async function hookMain(name) {
56
+ const payload = await loadHookPayload();
57
+ const root = await projectRoot(payload.cwd || process.cwd());
58
+ return evaluateHookPayloadOnce(name, payload, { root });
63
59
  }
64
- function codexGitActionMetadataText(payload = {}) {
65
- const seen = new Set();
66
- const out = [];
67
- const interesting = new Set([
68
- 'action',
69
- 'intent',
70
- 'operation',
71
- 'permission',
72
- 'description',
73
- 'kind',
74
- 'type',
75
- 'feature',
76
- 'tool_name',
77
- 'toolName',
78
- 'name',
79
- 'label',
80
- 'title',
81
- 'source',
82
- 'event',
83
- 'hook',
84
- 'hook_name',
85
- 'hookName',
86
- 'hook_event_name',
87
- 'hookEventName',
88
- 'id',
89
- 'command'
90
- ]);
91
- const noisy = new Set([
92
- 'prompt',
93
- 'user_prompt',
94
- 'userPrompt',
95
- 'message',
96
- 'assistant_message',
97
- 'last_assistant_message',
98
- 'response',
99
- 'raw',
100
- 'stdout',
101
- 'stderr'
102
- ]);
103
- function walk(value, depth = 0, parentKey = '') {
104
- if (!value || typeof value !== 'object' || depth > 5 || seen.has(value))
105
- return;
106
- seen.add(value);
107
- for (const [key, candidate] of Object.entries(value)) {
108
- if (noisy.has(key))
109
- continue;
110
- if (typeof candidate === 'string') {
111
- if (interesting.has(key) || /\b(?:codex[_\s-]*app|git[_\s-]*actions?|codex_git_|gitCommit|gitPush|pull\s+request)\b/i.test(candidate)) {
112
- out.push(`${key}:${candidate}`);
113
- }
114
- continue;
115
- }
116
- if (candidate && typeof candidate === 'object') {
117
- const allowedContainer = interesting.has(key)
118
- || /^(?:input|metadata|context|client|thread|session|request|payload|tool|tool_input|toolInput|permission_request|permissionRequest)$/i.test(key)
119
- || parentKey;
120
- if (allowedContainer)
121
- walk(candidate, depth + 1, key);
122
- }
123
- }
60
+ export async function evaluateHookPayloadOnce(name, payload = {}, opts = {}) {
61
+ const root = opts.root || await projectRoot(payload.cwd || process.cwd());
62
+ if (name === 'user-prompt-submit' && hookPayloadIsLightTurnCandidate(payload)) {
63
+ return evaluateHookPayload(name, payload, { root });
124
64
  }
125
- walk(payload);
126
- return out.join(' ');
65
+ const claim = await claimHookInvocation(root, name, payload).catch(() => ({ duplicate: false }));
66
+ if (claim.duplicate)
67
+ return { continue: true, suppressedDuplicate: true };
68
+ return evaluateHookPayload(name, payload, { root });
127
69
  }
128
- function codexGitActionMetadataSignal(text = '') {
129
- const s = String(text || '');
130
- if (!s)
70
+ function hookPayloadIsLightTurnCandidate(payload = {}) {
71
+ const prompt = stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload));
72
+ if (dollarCommand(prompt))
131
73
  return false;
132
- const action = String(s)
133
- .replace(/([a-z])([A-Z])/g, '$1 $2')
134
- .replace(/[_-]+/g, ' ');
135
- if (/\bcodex\s*app\b[\s\S]{0,120}\bgit\b[\s\S]{0,120}\b(?:action|actions|commit|push|pr|pull request)\b/i.test(action))
136
- return true;
137
- if (/\bgit\s*actions?\b[\s\S]{0,120}\b(?:commit|push|pr|pull request|commit\s*(?:and|&)\s*push)\b/i.test(action))
138
- return true;
139
- if (/\bcodex\s*git\s*(?:commit|push|pr|pull request|commit\s*(?:and|&)\s*push)\b/i.test(action))
140
- return true;
141
- if (/\b(?:git\s*)?(?:commit|push|commit\s*(?:and|&)\s*push|create\s+(?:a\s+)?pull\s+request|pull\s+request|pr)\b/i.test(action)) {
142
- return /\b(?:action|intent|operation|permission|feature|tool\s*name|source|event|hook|name|label|title|type|kind|id)\s*:/i.test(action);
143
- }
144
- return false;
145
- }
146
- function toolFailed(payload = {}) {
147
- const candidates = [
148
- payload.exit_code,
149
- payload.exitCode,
150
- payload.tool_response?.exit_code,
151
- payload.toolResponse?.exitCode,
152
- payload.result?.exit_code,
153
- payload.result?.exitCode
154
- ];
155
- for (const candidate of candidates) {
156
- if (candidate === undefined || candidate === null || candidate === '')
157
- continue;
158
- const n = Number(candidate);
159
- if (Number.isFinite(n))
160
- return n !== 0;
161
- }
162
- if (payload.isError === true || payload.tool_response?.isError === true || payload.toolResponse?.isError === true || payload.result?.isError === true)
163
- return true;
164
- if (payload.success === false || payload.tool_response?.success === false || payload.toolResponse?.success === false || payload.result?.success === false)
165
- return true;
166
- if (payload.executed === false)
74
+ const profile = classifyTaskProfile(prompt);
75
+ if (profile === 'passthrough')
167
76
  return true;
168
- return false;
169
- }
170
- export async function hookMain(name) {
171
- const payload = await loadHookPayload();
172
- return evaluateHookPayload(name, payload);
77
+ return routePrompt(prompt)?.id === 'Answer';
173
78
  }
174
79
  export async function evaluateHookPayload(name, payload = {}, opts = {}) {
175
80
  const root = opts.root || await projectRoot(payload.cwd || process.cwd());
176
81
  const sessionKey = conversationId(payload);
177
- if (!explicitConversationId(payload)) {
82
+ const greetingFastPath = name === 'user-prompt-submit'
83
+ && !dollarCommand(stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload)))
84
+ && classifyTaskProfile(stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload))) === 'passthrough';
85
+ const matchingLightStop = name === 'stop'
86
+ && await hasMatchingLightTurnStopBypass(root, { sessionKey, turnId: hookTurnId(payload) }).catch(() => false);
87
+ if (!explicitConversationId(payload) && !greetingFastPath && !matchingLightStop) {
178
88
  await appendJsonl(path.join(root, '.sneakoscope', 'state', 'session-id-fallback-warning.jsonl'), {
179
89
  ts: nowIso(),
180
90
  warning: 'hook_payload_missing_explicit_session_id',
@@ -183,7 +93,11 @@ export async function evaluateHookPayload(name, payload = {}, opts = {}) {
183
93
  hook: name
184
94
  }).catch(() => null);
185
95
  }
186
- const loadedState = opts.state || payload.state || await loadState(root, payload);
96
+ // Hook decisions use persisted session state. Codex hook payloads do not
97
+ // define a trusted `state` field; accepting a partial/spoofed value can hide
98
+ // an active mission or bypass route gates. Explicit opts.state remains for
99
+ // internal replay and focused tests.
100
+ const loadedState = opts.state || await loadState(root, payload);
187
101
  const state = { ...loadedState, _session_key: loadedState?._session_key || sessionKey };
188
102
  const noQuestion = isNoQuestionRunning(state);
189
103
  if (name === 'user-prompt-submit') {
@@ -198,46 +112,166 @@ export async function evaluateHookPayload(name, payload = {}, opts = {}) {
198
112
  if (name === 'stop')
199
113
  return hookStop(root, state, payload, noQuestion, sessionKey);
200
114
  if (name === 'subagent-start')
201
- return hookSubagentStart(root, state, sessionKey);
115
+ return hookSubagentStart(root, state, payload, sessionKey);
116
+ if (name === 'subagent-stop')
117
+ return hookSubagentStop(root, state, payload, sessionKey);
202
118
  return { continue: true };
203
119
  }
204
- async function hookSubagentStart(root, state, sessionKey = null) {
205
- void sessionKey;
206
- const active = await activeRouteContext(root, state).catch(() => '');
120
+ async function hookSubagentStart(root, state, payload = {}, sessionKey = null) {
121
+ const artifactDir = officialSubagentArtifactDir(root, state, sessionKey);
122
+ await recordAndRefreshSubagentEvidence(root, artifactDir, state, payload, 'SubagentStart').catch(() => null);
123
+ const config = await readOfficialSubagentConfig(root);
124
+ const budget = resolveSubagentThreadBudget({ configuredMaxThreads: config.maxThreads });
125
+ const active = subagentRouteContext(state);
207
126
  const resourceGuard = [
208
- 'SKS resource guard: keep at most 4 active subagents in this session.',
209
- 'Subagents must not spawn nested subagents or duplicate an already assigned audit lane.',
210
- 'Queue additional independent work instead of increasing active fan-out.'
127
+ `SKS subagent policy: Codex [agents].max_threads is ${budget.maxThreads}.`,
128
+ 'Use max_depth=1. Subagents must not spawn subagents.',
129
+ 'Do not duplicate an already assigned slice.',
130
+ 'Parallel writes require disjoint paths; serialize overlapping paths.',
131
+ 'Close completed agent threads when no longer needed.'
211
132
  ].join(' ');
212
133
  const additionalContext = [leanEngineeringCompactText(), resourceGuard, active].filter(Boolean).join('\n\n');
213
134
  return { continue: true, additionalContext };
214
135
  }
215
- function looksLikeCodexUiSettingsEvent(payload = {}) {
216
- const prompt = stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload));
217
- const haystack = [
218
- payload.action,
219
- payload.intent,
220
- payload.operation,
221
- payload.permission,
222
- payload.description,
223
- payload.kind,
224
- payload.type,
225
- payload.feature,
226
- payload.source,
227
- payload.event,
228
- payload.hook,
229
- payload.hook_name,
230
- payload.metadata?.action,
231
- payload.metadata?.intent,
232
- payload.metadata?.operation,
233
- payload.metadata?.feature,
234
- payload.metadata?.source,
235
- payload.context?.surface,
236
- payload.session?.surface
237
- ].filter(Boolean).join(' ');
238
- return !prompt && /\b(?:settings|preferences|profile|speed|fast[_\s-]*mode|reasoning|model[_\s-]*select|codex[_\s-]*app)\b/i.test(haystack);
136
+ function subagentRouteContext(state = {}) {
137
+ if (!state?.route && !state?.mode)
138
+ return '';
139
+ const route = state.route_command || state.route || state.mode;
140
+ const mission = state.mission_id ? ` for mission ${state.mission_id}` : '';
141
+ const artifacts = state.mission_id
142
+ ? ` Read only the route artifacts relevant to your assigned slice under .sneakoscope/missions/${state.mission_id}/.`
143
+ : '';
144
+ const databaseBoundary = String(state.mode || state.route || '').toUpperCase() === 'DB'
145
+ ? ' Keep database inspection read-only unless the parent supplied a separately sealed mutation contract.'
146
+ : '';
147
+ return `You are a child thread on ${route}${mission}. Execute only the slice assigned by the parent.${artifacts} Do not spawn or delegate other agents, wait for sibling threads, integrate sibling results, close the parent route, or author the sks.subagent-parent-summary.v1 parent result. Return a concise slice result to the parent.${databaseBoundary}`;
148
+ }
149
+ async function hookSubagentStop(root, state, payload = {}, sessionKey = null) {
150
+ const artifactDir = officialSubagentArtifactDir(root, state, sessionKey);
151
+ await recordAndRefreshSubagentEvidence(root, artifactDir, state, payload, 'SubagentStop').catch(() => null);
152
+ // SubagentStop is evidence collection only. It must never reuse the parent
153
+ // Stop hook's route gate or block a child thread from returning its result.
154
+ return { continue: true, silent: true };
155
+ }
156
+ function officialSubagentArtifactDir(root, state = {}, sessionKey = null) {
157
+ if (state?.mission_id)
158
+ return missionDir(root, state.mission_id);
159
+ return path.join(root, '.sneakoscope', 'state', 'subagents', sha256(String(sessionKey || 'default')).slice(0, 32));
160
+ }
161
+ async function recordAndRefreshSubagentEvidence(root, artifactDir, state, payload, eventName) {
162
+ return withFileLock({
163
+ lockPath: path.join(artifactDir, '.subagent-evidence.lock'),
164
+ timeoutMs: 5_000,
165
+ staleMs: 60_000
166
+ }, async () => {
167
+ const plan = await readJson(path.join(artifactDir, 'subagent-plan.json'), {});
168
+ const workflowRunId = String(plan?.workflow_run_id || state?.official_subagent_run_id || '').trim();
169
+ const eventPayload = workflowRunId && payload && typeof payload === 'object' && !Array.isArray(payload)
170
+ ? { ...payload, workflow_run_id: workflowRunId }
171
+ : payload;
172
+ const event = await recordSubagentEvent(artifactDir, eventPayload, eventName);
173
+ if (!event)
174
+ return null;
175
+ const zellijTelemetry = await recordOfficialSubagentZellijTelemetry({
176
+ root,
177
+ routeMissionId: plan?.mission_id || state?.mission_id || null,
178
+ event,
179
+ payload: eventPayload,
180
+ plan
181
+ }).catch(async (error) => {
182
+ await appendJsonl(path.join(artifactDir, 'zellij-telemetry-warnings.jsonl'), {
183
+ ts: nowIso(),
184
+ warning: 'official_subagent_zellij_telemetry_failed',
185
+ event_name: eventName,
186
+ thread_id: event.thread_id,
187
+ error: String(error?.message || error)
188
+ }).catch(() => null);
189
+ return null;
190
+ });
191
+ if (zellijTelemetry?.blocker) {
192
+ await appendJsonl(path.join(artifactDir, 'zellij-telemetry-warnings.jsonl'), {
193
+ ts: nowIso(),
194
+ warning: 'official_subagent_zellij_telemetry_incomplete',
195
+ event_name: eventName,
196
+ thread_id: event.thread_id,
197
+ blocker: zellijTelemetry.blocker,
198
+ failed_mission_ids: 'failed_mission_ids' in zellijTelemetry ? zellijTelemetry.failed_mission_ids : []
199
+ }).catch(() => null);
200
+ }
201
+ const existing = await readJson(path.join(artifactDir, SUBAGENT_EVIDENCE_FILENAME), {});
202
+ const parentSummary = await readJson(path.join(artifactDir, SUBAGENT_PARENT_SUMMARY_FILENAME), null);
203
+ const requestedSubagents = Number(plan?.requested_subagents
204
+ || state?.requested_subagents
205
+ || existing?.requested_subagents
206
+ || 0);
207
+ if (!Number.isFinite(requestedSubagents) || requestedSubagents < 1)
208
+ return event;
209
+ await writeSubagentEvidence(artifactDir, {
210
+ requestedSubagents,
211
+ parentSummary,
212
+ parentSummaryPresent: parentSummary !== null,
213
+ workflowStatus: 'running',
214
+ preparationOnly: false,
215
+ runId: workflowRunId || null,
216
+ additionalBlockers: Array.isArray(plan?.config_blockers)
217
+ ? plan.config_blockers.map((item) => `official_subagent_config:${String(item)}`)
218
+ : []
219
+ });
220
+ return event;
221
+ });
239
222
  }
240
223
  async function hookUserPrompt(root, state, payload, noQuestion, sessionKey = null) {
224
+ // A receipt is scoped to exactly one submitted turn. Every later prompt,
225
+ // including Codex App git/settings events, invalidates it before returning.
226
+ await clearLightTurnStopBypass(root, { sessionKey }).catch(() => undefined);
227
+ const submittedPrompt = stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload));
228
+ const explicitSession = explicitConversationId(payload);
229
+ const detectedMissingCallId = missingToolOutputCallId(submittedPrompt)
230
+ || missingToolOutputCallIdFromPayload(payload);
231
+ let toolOutputQuarantine = explicitSession
232
+ ? await readToolOutputQuarantine(root, sessionKey).catch(() => null)
233
+ : null;
234
+ if (detectedMissingCallId && explicitSession) {
235
+ toolOutputQuarantine = await quarantineMissingToolOutput({
236
+ root,
237
+ sessionKey,
238
+ callId: detectedMissingCallId,
239
+ missionId: state?.mission_id,
240
+ turnId: hookTurnId(payload)
241
+ }).catch(() => toolOutputQuarantine);
242
+ }
243
+ if (submittedPrompt && (detectedMissingCallId || toolOutputQuarantine)) {
244
+ return {
245
+ decision: 'block',
246
+ reason: interruptedToolOutputRecoveryBlockReason({
247
+ callId: detectedMissingCallId || toolOutputQuarantine?.call_id,
248
+ missionId: state?.mission_id || toolOutputQuarantine?.mission_id
249
+ })
250
+ };
251
+ }
252
+ const parentLaunchMissionId = process.env.SKS_NARUTO_PARENT_LAUNCH === '1'
253
+ ? String(process.env.SKS_NARUTO_PARENT_MISSION_ID || '').trim()
254
+ : '';
255
+ if (parentLaunchMissionId) {
256
+ const attachedState = {
257
+ ...state,
258
+ mission_id: parentLaunchMissionId,
259
+ mode: 'NARUTO',
260
+ route: 'Naruto',
261
+ route_command: '$Naruto',
262
+ route_closed: false,
263
+ subagents_required: true,
264
+ native_sessions_required: false
265
+ };
266
+ await setCurrent(root, attachedState, { sessionKey, replace: true });
267
+ const activeContext = await activeRouteContext(root, attachedState);
268
+ return {
269
+ continue: true,
270
+ additionalContext: activeContext,
271
+ systemMessage: visibleHookMessage('user-prompt-submit', activeContext),
272
+ attached_parent_mission_id: parentLaunchMissionId
273
+ };
274
+ }
241
275
  if (looksLikeCodexGitAction(payload)) {
242
276
  await armCodexGitActionStopBypass(root, payload).catch(() => null);
243
277
  return {
@@ -251,15 +285,63 @@ async function hookUserPrompt(root, state, payload, noQuestion, sessionKey = nul
251
285
  systemMessage: 'SKS: Codex App settings/profile event ignored; route gates unchanged.'
252
286
  };
253
287
  }
254
- await maybeReconcileProjectSkillsPreflight(root).catch(() => null);
255
288
  if (!noQuestion) {
256
- const prompt = stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload));
257
- const madSksConfirmation = await handleMadSksUserConfirmation(root, state, prompt);
289
+ const prompt = submittedPrompt;
290
+ const taskProfile = classifyTaskProfile(prompt);
291
+ const explicitCommand = Boolean(dollarCommand(prompt));
292
+ const lightRoute = explicitCommand ? null : routePrompt(prompt);
293
+ const clarificationPending = isBlockingClarificationAwaiting(state);
294
+ const madConfirmationPrompt = looksLikeMadSksConfirmationPrompt(prompt);
295
+ const activeContinuation = Boolean(state?.mission_id && state?.route_closed !== true && looksLikeActiveContinuationPrompt(prompt));
296
+ if (!explicitCommand && !clarificationPending && !madConfirmationPrompt && !activeContinuation && taskProfile === 'passthrough') {
297
+ const turnId = hookTurnId(payload);
298
+ if (turnId) {
299
+ await armLightTurnStopBypass(root, {
300
+ sessionKey,
301
+ turnId,
302
+ prompt,
303
+ profile: 'passthrough',
304
+ ttlMs: 60_000
305
+ });
306
+ }
307
+ return { continue: true, silent: true, sksTaskProfile: taskProfile };
308
+ }
309
+ if (!explicitCommand && !clarificationPending && !madConfirmationPrompt && !activeContinuation && lightRoute?.id === 'Answer') {
310
+ const turnId = hookTurnId(payload);
311
+ if (turnId) {
312
+ await armLightTurnStopBypass(root, {
313
+ sessionKey,
314
+ turnId,
315
+ prompt,
316
+ profile: 'answer',
317
+ ttlMs: 5 * 60_000
318
+ });
319
+ }
320
+ const additionalContext = compactAnswerContext(prompt);
321
+ return { continue: true, additionalContext, sksTaskProfile: 'answer' };
322
+ }
323
+ const madSksConfirmation = madConfirmationPrompt
324
+ ? await handleMadSksUserConfirmation(root, state, prompt)
325
+ : null;
258
326
  if (madSksConfirmation?.handled) {
259
327
  const teamDigest = await teamLiveDigest(root, state);
260
328
  const additionalContext = [madSksConfirmation.additionalContext, teamDigest?.context].filter(Boolean).join('\n\n');
261
329
  return { continue: true, additionalContext, systemMessage: joinSystemMessages(visibleHookMessage('user-prompt-submit', additionalContext), teamDigest?.system) };
262
330
  }
331
+ if (activeContinuation) {
332
+ const activeContext = await activeRouteContext(root, state);
333
+ const teamDigest = await teamLiveDigest(root, state);
334
+ const additionalContext = [
335
+ activeContext,
336
+ teamDigest?.context
337
+ ].filter(Boolean).join('\n\n');
338
+ return {
339
+ continue: true,
340
+ additionalContext,
341
+ systemMessage: joinSystemMessages(visibleHookMessage('user-prompt-submit', activeContext), teamDigest?.system)
342
+ };
343
+ }
344
+ await maybeReconcileProjectSkillsPreflight(root).catch(() => null);
263
345
  const updateContext = '';
264
346
  const command = dollarCommand(prompt);
265
347
  const route = routePrompt(prompt);
@@ -290,7 +372,10 @@ async function hookUserPrompt(root, state, payload, noQuestion, sessionKey = nul
290
372
  if (activeContext && shouldLoadActiveContext)
291
373
  contexts.push(routePipelineContext(prompt), activeContext);
292
374
  else
293
- contexts.push((await prepareRoute(root, prompt, state, { sessionKey })).additionalContext);
375
+ contexts.push((await prepareRoute(root, prompt, state, {
376
+ sessionKey,
377
+ parentModel: observedParentModel(payload)
378
+ })).additionalContext);
294
379
  if (goalOverlay)
295
380
  contexts.push(goalOverlay);
296
381
  if (teamDigest?.context)
@@ -330,10 +415,13 @@ function shouldPrepareFreshRouteOnActivePrompt(prompt, route = null, opts = {})
330
415
  return routeRequiresSubagents(route, prompt);
331
416
  }
332
417
  function looksLikeActiveContinuationPrompt(prompt = '') {
333
- const text = stripVisibleDecisionAnswerBlocks(String(prompt || '')).trim();
418
+ const text = stripVisibleDecisionAnswerBlocks(String(prompt || ''))
419
+ .trim()
420
+ .replace(/[.!?。!?…,:;]+$/u, '')
421
+ .trim();
334
422
  if (!text)
335
423
  return false;
336
- return /^(?:keep\s+going|continue|resume|go\s+on|proceed|carry\s+on|계속|이어\s*서|이어서|진행|계속\s*해|마저\s*해|다음|next)$/i.test(text);
424
+ return /^(?:(?:please\s+)?(?:keep\s+going|continue|resume|go\s+on|proceed|carry\s+on)(?:\s+please)?|계속(?:\s*진행)?(?:\s*해\s*줘|\s*해주세요|\s*해)?|이어\s*서(?:\s*해\s*줘|\s*해주세요|\s*진행해)?|이어서(?:\s*해\s*줘|\s*해주세요|\s*진행해)?|진행(?:\s*해\s*줘|\s*해주세요|\s*해)?|마저\s*해(?:\s*줘|\s*주세요)?|다음|next)$/i.test(text);
337
425
  }
338
426
  function isClarificationAwaiting(state = {}) {
339
427
  const phase = String(state.phase || '');
@@ -613,6 +701,11 @@ function clarificationPauseBlockReason(state = {}) {
613
701
  }
614
702
  async function hookStop(root, state, payload, noQuestion, sessionKey = null) {
615
703
  const last = extractLastMessage(payload);
704
+ if (!noQuestion) {
705
+ const lightTurn = await consumeLightTurnStopBypass(root, { sessionKey, turnId: hookTurnId(payload) });
706
+ if (lightTurn.accepted)
707
+ return { continue: true, action: 'light_turn', silent: true };
708
+ }
616
709
  if (state?.mode === 'LOOP' || state?.route === 'Loop' || state?.route_command === '$Loop') {
617
710
  const missionId = state?.mission_id;
618
711
  if (missionId) {
@@ -643,6 +736,9 @@ async function hookStop(root, state, payload, noQuestion, sessionKey = null) {
643
736
  systemMessage: 'SKS: DFix ultralight finalization accepted; full-route Honest Mode loopback is not required.'
644
737
  };
645
738
  }
739
+ if (state?.subagents_required === true) {
740
+ await refreshOfficialSubagentCompletionArtifacts(root, state, last, sessionKey).catch(() => null);
741
+ }
646
742
  const routeDecision = await evaluateStop(root, state, payload, { noQuestion });
647
743
  if (routeDecision)
648
744
  return routeDecision;
@@ -680,6 +776,163 @@ async function hookStop(root, state, payload, noQuestion, sessionKey = null) {
680
776
  reason: 'SKS no-question run is not done. Continue autonomously, fix failing checks, update the active gate file, and do not ask the user.'
681
777
  };
682
778
  }
779
+ async function refreshOfficialSubagentCompletionArtifacts(root, state = {}, parentSummary = '', sessionKey = null) {
780
+ const id = state?.mission_id;
781
+ if (!id)
782
+ return null;
783
+ const dir = missionDir(root, id);
784
+ const plan = await readJson(path.join(dir, 'subagent-plan.json'), null).catch(() => null);
785
+ if (plan?.workflow !== 'official_codex_subagent')
786
+ return null;
787
+ const requestedSubagents = Number(plan.requested_subagents || state.requested_subagents || 0);
788
+ const workflowRunId = String(plan.workflow_run_id || state.official_subagent_run_id || '').trim();
789
+ const events = await readSubagentEvents(dir);
790
+ const runBoundParentSummary = bindTrustworthySubagentParentSummaryToRun(parentSummary, workflowRunId);
791
+ const effectiveParentSummary = await persistOrReuseTrustworthySubagentParentSummary(dir, runBoundParentSummary, {
792
+ workflowStatus: 'parent_completed',
793
+ runId: workflowRunId || null
794
+ });
795
+ const structuredParentSummary = normalizeSubagentParentSummary(effectiveParentSummary);
796
+ const evidence = await writeSubagentEvidence(dir, {
797
+ requestedSubagents,
798
+ events,
799
+ parentSummary: effectiveParentSummary,
800
+ workflowStatus: 'parent_completed',
801
+ preparationOnly: false,
802
+ runId: workflowRunId || null,
803
+ additionalBlockers: Array.isArray(plan.config_blockers)
804
+ ? plan.config_blockers.map((item) => `official_subagent_config:${String(item)}`)
805
+ : []
806
+ });
807
+ if (structuredParentSummary.trustworthy) {
808
+ const parentTelemetry = await recordOfficialSubagentParentOutcomesTelemetry({
809
+ root,
810
+ routeMissionId: id,
811
+ parentSummary: structuredParentSummary.raw,
812
+ plan
813
+ }).catch(async (error) => {
814
+ await appendJsonl(path.join(dir, 'zellij-telemetry-warnings.jsonl'), {
815
+ ts: nowIso(),
816
+ warning: 'official_subagent_parent_outcome_telemetry_failed',
817
+ error: String(error?.message || error)
818
+ }).catch(() => null);
819
+ return null;
820
+ });
821
+ if (parentTelemetry?.blocker) {
822
+ await appendJsonl(path.join(dir, 'zellij-telemetry-warnings.jsonl'), {
823
+ ts: nowIso(),
824
+ warning: 'official_subagent_parent_outcome_telemetry_incomplete',
825
+ blocker: parentTelemetry.blocker,
826
+ failed_mission_ids: 'failed_mission_ids' in parentTelemetry ? parentTelemetry.failed_mission_ids : [],
827
+ skipped_thread_ids: 'skipped_thread_ids' in parentTelemetry ? parentTelemetry.skipped_thread_ids : []
828
+ }).catch(() => null);
829
+ }
830
+ }
831
+ const isNaruto = String(state?.mode || '').toUpperCase() === 'NARUTO'
832
+ || String(state?.route || state?.route_command || '').replace(/^\$/, '').toUpperCase() === 'NARUTO';
833
+ if (!isNaruto) {
834
+ await setCurrent(root, {
835
+ subagents_spawned: evidence.started_threads > 0,
836
+ subagents_reported: evidence.completed_threads > 0,
837
+ subagents_verified: evidence.ok,
838
+ subagent_evidence_file: SUBAGENT_EVIDENCE_FILENAME,
839
+ parent_summary_present: evidence.parent_summary_present
840
+ }, { sessionKey: sessionKey || state._session_key });
841
+ return evidence;
842
+ }
843
+ const previousGate = await readJson(path.join(dir, 'naruto-gate.json'), {}).catch(() => ({}));
844
+ const parentModel = plan.observed_parent_model || state.observed_parent_model || null;
845
+ const parentModelMismatch = previousGate.parent_model_match === false || observedParentModelMismatch(parentModel, NARUTO_PARENT_MODEL);
846
+ const blockers = [...new Set([
847
+ ...evidence.blockers,
848
+ ...(Array.isArray(previousGate.config_blockers) ? previousGate.config_blockers.map(String) : []),
849
+ ...(Array.isArray(plan.config_blockers) ? plan.config_blockers.map((item) => `official_subagent_config:${String(item)}`) : []),
850
+ ...(parentModelMismatch ? [`parent_model_mismatch:${String(parentModel || 'unknown')}`] : [])
851
+ ])];
852
+ const passed = evidence.ok === true && blockers.length === 0;
853
+ const updatedAt = nowIso();
854
+ const summary = {
855
+ schema: 'sks.naruto-subagent-workflow.v1',
856
+ ok: passed,
857
+ workflow: 'official_codex_subagent',
858
+ workflow_run_id: workflowRunId || null,
859
+ mission_id: id,
860
+ route: '$Naruto',
861
+ status: passed ? 'completed' : evidence.status,
862
+ parent: {
863
+ model: NARUTO_PARENT_MODEL,
864
+ model_reasoning_effort: NARUTO_PARENT_EFFORT,
865
+ observed_model: parentModel,
866
+ observed_model_match: parentModel ? !parentModelMismatch : null
867
+ },
868
+ requested_subagents: requestedSubagents,
869
+ max_threads: Number(plan.max_threads || state.subagent_max_threads || 0),
870
+ max_depth: 1,
871
+ started_subagents: evidence.started_threads,
872
+ completed_subagents: evidence.completed_threads,
873
+ failed_subagents: evidence.failed_threads,
874
+ agents: officialSubagentRolePlan(),
875
+ verification: {
876
+ budget: plan.verification?.budget || plan.verification_budget || 'affected',
877
+ checks: Array.isArray(plan.verification?.checks)
878
+ ? plan.verification.checks
879
+ : Array.isArray(plan.verification_checks)
880
+ ? plan.verification_checks
881
+ : []
882
+ },
883
+ legacy_process_swarm_used: false,
884
+ parent_summary_present: evidence.parent_summary_present,
885
+ parent_summary: structuredParentSummary.summary,
886
+ parent_thread_outcomes: structuredParentSummary.raw?.thread_outcomes || [],
887
+ subagent_evidence: SUBAGENT_EVIDENCE_FILENAME,
888
+ blockers,
889
+ updated_at: updatedAt
890
+ };
891
+ await writeJsonAtomic(path.join(dir, 'naruto-summary.json'), summary);
892
+ await writeJsonAtomic(path.join(dir, 'naruto-gate.json'), {
893
+ ...previousGate,
894
+ schema: 'sks.naruto-gate.v1',
895
+ workflow: 'official_codex_subagent',
896
+ workflow_run_id: workflowRunId || null,
897
+ mission_id: id,
898
+ status: passed ? 'passed' : 'blocked',
899
+ passed,
900
+ terminal: passed,
901
+ terminal_state: passed ? 'completed' : 'blocked',
902
+ subagent_plan_ready: true,
903
+ official_subagent_evidence: evidence.ok === true,
904
+ parent_summary_present: evidence.parent_summary_present,
905
+ session_cleanup: evidence.failed_threads === 0 && evidence.completed_threads >= requestedSubagents,
906
+ subagent_evidence_ready: evidence.ok === true,
907
+ requested_subagents: evidence.requested_subagents,
908
+ started_subagents: evidence.started_threads,
909
+ completed_subagents: evidence.completed_threads,
910
+ failed_subagents: evidence.failed_threads,
911
+ event_sources: evidence.event_sources,
912
+ evidence: {
913
+ ...(previousGate.evidence || {}),
914
+ official_subagent_evidence: SUBAGENT_EVIDENCE_FILENAME,
915
+ parent_summary: SUBAGENT_PARENT_SUMMARY_FILENAME,
916
+ requested_subagents: requestedSubagents,
917
+ started_threads: evidence.started_threads,
918
+ completed_threads: evidence.completed_threads,
919
+ failed_threads: evidence.failed_threads
920
+ },
921
+ blockers,
922
+ missing_fields: blockers,
923
+ updated_at: updatedAt
924
+ });
925
+ if (passed)
926
+ await closeWorkOrderLedgerForRouteResult(dir, { ok: true }).catch(() => null);
927
+ await setCurrent(root, {
928
+ subagents_spawned: evidence.started_threads > 0,
929
+ subagents_reported: evidence.completed_threads > 0,
930
+ subagents_verified: evidence.ok,
931
+ subagent_evidence_file: SUBAGENT_EVIDENCE_FILENAME,
932
+ parent_summary_present: evidence.parent_summary_present
933
+ }, { sessionKey: sessionKey || state._session_key });
934
+ return evidence;
935
+ }
683
936
  async function consumeLightRouteStop(root, payload = {}) {
684
937
  const file = path.join(root, '.sneakoscope', 'state', LIGHT_ROUTE_STOP_ARTIFACT);
685
938
  const record = await readJson(file, null).catch(() => null);
@@ -713,91 +966,6 @@ function hasDfixLightCompletion(text) {
713
966
  const gap = /(미검증|남은|문제|gap|remaining|not verified|not run|blocker|차단|불가|없음|none)/i.test(s);
714
967
  return verification && gap;
715
968
  }
716
- function looksLikeCodexGitAction(payload = {}) {
717
- const prompt = stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload));
718
- const metadataText = codexGitActionMetadataText(payload);
719
- const haystack = [
720
- metadataText,
721
- payload.action,
722
- payload.intent,
723
- payload.operation,
724
- payload.permission,
725
- payload.description,
726
- payload.kind,
727
- payload.type,
728
- payload.feature,
729
- payload.tool_name,
730
- payload.toolName,
731
- payload.source,
732
- payload.event,
733
- payload.hook,
734
- payload.hook_name,
735
- payload.input?.action,
736
- payload.input?.intent,
737
- payload.input?.operation,
738
- payload.input?.feature,
739
- payload.input?.source,
740
- payload.metadata?.action,
741
- payload.metadata?.intent,
742
- payload.metadata?.operation,
743
- payload.metadata?.feature,
744
- payload.metadata?.source
745
- ].filter(Boolean).join(' ');
746
- const codexAppGitSignal = /\bcodex[_\s-]*app\b[\s\S]{0,80}\bgit\b[\s\S]{0,80}\b(?:action|actions|commit|push|pr)\b/i.test(haystack);
747
- const gitActionSignal = /\bgit[_\s-]*actions?\b[\s\S]{0,80}\b(?:commit|push|commit[\s_-]*(?:and|&)?[\s_-]*push)\b/i.test(haystack);
748
- const appSignal = codexGitActionMetadataSignal(metadataText)
749
- || codexAppGitSignal
750
- || gitActionSignal
751
- || /\b(?:codex[_\s-]*(?:app[_\s-]*)?)?(?:git[_\s-]*)?(?:commit[_\s-]*message|git[_\s-]*commit|git[_\s-]*push|git[_\s-]*pr|codex_git_commit|codex_git_push|codex_git_pr)\b/i.test(haystack)
752
- || /커밋\s*메시지\s*생성/i.test(haystack);
753
- const promptSignal = /\bgenerate(?:\s+a)?(?:\s+git)?\s+commit\s+message\b/i.test(prompt)
754
- || /\bcommit\s+message\b[\s\S]{0,80}\b(?:staged|diff|changes?|git)\b/i.test(prompt)
755
- || looksLikeStockCodexGitActionPrompt(prompt)
756
- || /커밋\s*메시지\s*생성/i.test(prompt);
757
- if (!appSignal && !promptSignal)
758
- return false;
759
- if (looksLikeStockCodexGitActionPrompt(prompt))
760
- return true;
761
- if (appSignal)
762
- return true;
763
- return !looksLikeUserImplementationRequest(prompt);
764
- }
765
- function looksLikeStockCodexGitActionPrompt(prompt = '') {
766
- const text = String(prompt || '').trim();
767
- if (!text || text.length > 120)
768
- return false;
769
- return /^(?:generate\s+(?:a\s+)?git\s+commit\s+message(?:\s+for\s+(?:the\s+)?(?:staged\s+)?diff)?|commit\s+changes|commit\s+and\s+push\s+changes|push\s+changes|create\s+(?:a\s+)?commit|create\s+(?:a\s+)?pull\s+request)\.?$/i.test(text);
770
- }
771
- function looksLikeCodexGitActionStopCompletion(last = '', payload = {}) {
772
- const text = String(last || '').trim();
773
- const metadataText = codexGitActionMetadataText(payload);
774
- const haystack = [
775
- metadataText,
776
- payload.action,
777
- payload.intent,
778
- payload.operation,
779
- payload.kind,
780
- payload.type,
781
- payload.feature,
782
- payload.source,
783
- payload.event,
784
- payload.metadata?.action,
785
- payload.metadata?.intent,
786
- payload.metadata?.operation,
787
- payload.metadata?.feature,
788
- payload.metadata?.source
789
- ].filter(Boolean).join(' ');
790
- if (codexGitActionMetadataSignal(metadataText))
791
- return true;
792
- if (/\bcodex[_\s-]*app\b[\s\S]{0,80}\bgit\b[\s\S]{0,80}\b(?:action|commit|push|pr)\b/i.test(haystack))
793
- return true;
794
- if (!text || text.length > 180)
795
- return false;
796
- return /^(?:commit(?:ted)?(?:\s+and\s+pushed)?(?:\s+changes)?(?:\s+complete[.!]?)?|push(?:ed)?(?:\s+changes)?(?:\s+complete[.!]?)?|created\s+(?:a\s+)?pull\s+request[.!]?)$/i.test(text);
797
- }
798
- function looksLikeUserImplementationRequest(text = '') {
799
- return /(fix|bug|broken|error|issue|implement|change|update|repair|수정|버그|오류|에러|문제|고쳐|고치|해결|변경|수리|패치|안생기|안\s*생기)/i.test(String(text || ''));
800
- }
801
969
  async function armCodexGitActionStopBypass(root, payload = {}) {
802
970
  const nowMs = Date.now();
803
971
  const record = {