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
@@ -0,0 +1,287 @@
1
+ import fsp from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import readline from 'node:readline/promises';
4
+ import { stdin as input, stdout as output } from 'node:process';
5
+ import { EMPTY_CODEX_INFO, getCodexInfo } from '../core/codex-adapter.js';
6
+ import { exists, globalSksRoot, PACKAGE_VERSION, runProcess, which } from '../core/fsx.js';
7
+ import { hasContext7ConfigText } from '../core/routes.js';
8
+ import { createRequestedScopeContract } from '../core/safety/requested-scope-contract.js';
9
+ import { guardedPackageInstall, guardContextForRoute } from '../core/safety/mutation-guard.js';
10
+ import { checkZellijCapability } from '../core/zellij/zellij-capability.js';
11
+ export async function ensureRelatedCliTools(args = []) {
12
+ const skip = args.includes('--skip-cli-tools') || process.env.SKS_SKIP_CLI_TOOLS === '1';
13
+ const codex = await ensureCodexCliTool({ skip, args });
14
+ const zellijRepair = skip ? { status: 'skipped', reason: 'SKS_SKIP_CLI_TOOLS=1 or --skip-cli-tools' } : await ensureZellijCliTool(args);
15
+ const zellij = await checkZellijCapability({ require: false, writeReport: false });
16
+ return {
17
+ codex,
18
+ zellij: {
19
+ ok: zellij.status === 'ok',
20
+ bin: zellij.bin,
21
+ version: zellij.version,
22
+ min_version: zellij.min_version,
23
+ current_session: false,
24
+ repair: zellijRepair,
25
+ install_hint: zellij.status === 'ok' ? null : zellijInstallHint(),
26
+ error: zellijRepair.error || zellij.blockers[0] || zellij.warnings[0] || null
27
+ }
28
+ };
29
+ }
30
+ export async function ensureMadLaunchDependencies(args = []) {
31
+ const skip = args.includes('--skip-cli-tools') || process.env.SKS_SKIP_CLI_TOOLS === '1';
32
+ const zellijRepair = skip ? { target: 'zellij', status: 'skipped', reason: 'SKS_SKIP_CLI_TOOLS=1 or --skip-cli-tools' } : await ensureZellijCliTool(args);
33
+ const zellij = await checkZellijCapability({ require: false, writeReport: false });
34
+ const ready = zellij.status === 'ok';
35
+ return {
36
+ ready,
37
+ actions: ready ? [] : [{
38
+ target: 'zellij',
39
+ status: zellijRepair.status,
40
+ command: zellijRepair.command || zellijInstallHint(),
41
+ error: zellijRepair.error || zellij.blockers[0] || zellij.warnings[0] || null,
42
+ repair: zellijRepair
43
+ }],
44
+ status: {
45
+ zellij: {
46
+ ok: ready,
47
+ status: zellij.status,
48
+ version: zellij.version,
49
+ min_version: zellij.min_version,
50
+ repair: zellijRepair,
51
+ install_hint: ready ? null : zellijInstallHint()
52
+ }
53
+ }
54
+ };
55
+ }
56
+ export function formatMadLaunchDependencyAction(action = {}) {
57
+ const command = action.command ? ` Run: ${action.command}.` : '';
58
+ const error = action.error ? ` ${action.error}` : '';
59
+ return `${action.target || 'dependency'} ${action.status || 'blocked'}.${command}${error}`.trim();
60
+ }
61
+ export async function ensureCodexCliTool({ skip = false, args = [] } = {}) {
62
+ if (skip)
63
+ return { status: 'skipped', reason: 'SKS_SKIP_CLI_TOOLS=1 or --skip-cli-tools' };
64
+ const before = await getCodexInfo().catch(() => EMPTY_CODEX_INFO);
65
+ if (before.bin)
66
+ return { status: 'present', bin: before.bin, version: before.version || null };
67
+ const npmBin = await which('npm');
68
+ if (!npmBin)
69
+ return { status: 'failed', error: 'npm not found on PATH; install Codex CLI manually with npm i -g @openai/codex@latest.' };
70
+ const command = 'npm i -g @openai/codex@latest';
71
+ if (args.includes('--dry-run'))
72
+ return { status: 'dry_run', command, error: 'Codex CLI not found on PATH.' };
73
+ if (!await confirmInstallYesDefault(`Codex CLI is missing. Install latest Codex CLI with ${command}?`, args)) {
74
+ return { status: 'needs_approval', command, error: 'Codex CLI not found on PATH.' };
75
+ }
76
+ const installRoot = globalSksRoot();
77
+ const installContract = createRequestedScopeContract({
78
+ route: 'install', userRequest: command, projectRoot: installRoot, overrides: { package_install: true }
79
+ });
80
+ const install = await guardedPackageInstall(guardContextForRoute(installRoot, installContract, command), '@openai/codex@latest', { confirmed: true, command: npmBin, args: ['i', '-g', '@openai/codex@latest'], timeoutMs: 120000 }).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
81
+ if (install.code !== 0)
82
+ return { status: 'failed', error: `${install.stderr || install.stdout || 'npm i -g @openai/codex@latest failed'}`.trim() };
83
+ const after = await getCodexInfo().catch(() => EMPTY_CODEX_INFO);
84
+ return {
85
+ status: after.bin ? 'installed' : 'installed_not_on_path',
86
+ bin: after.bin || null,
87
+ version: after.version || null,
88
+ hint: after.bin ? null : 'npm completed, but codex is not on PATH. Restart the shell or set SKS_CODEX_BIN.'
89
+ };
90
+ }
91
+ export async function ensureZellijCliTool(args = [], opts = {}) {
92
+ const before = await checkZellijCapability({ require: false, writeReport: false });
93
+ if (before.status === 'ok')
94
+ return { target: 'zellij', status: 'present', bin: before.bin, version: before.version || null };
95
+ const command = zellijInstallHint();
96
+ if (process.platform !== 'darwin')
97
+ return { target: 'zellij', status: 'manual_required', command, error: before.blockers[0] || before.warnings[0] || 'zellij not found' };
98
+ const brew = await which('brew').catch(() => null);
99
+ if (!brew)
100
+ return { target: 'zellij', status: 'manual_required', command: 'Install Homebrew, then run: brew install zellij', error: before.blockers[0] || before.warnings[0] || 'zellij not found' };
101
+ if (args.includes('--dry-run') || opts.dryRun)
102
+ return { target: 'zellij', status: 'dry_run', command, error: before.blockers[0] || before.warnings[0] || null };
103
+ const hasInstalledZellij = Boolean(before.version);
104
+ const question = hasInstalledZellij
105
+ ? `Homebrew Zellij ${before.version || 'unknown'} is not ready. Upgrade to latest Zellij with ${command}?`
106
+ : `Zellij is missing. Install latest Zellij with ${command}?`;
107
+ if (!await confirmInstallYesDefault(question, args))
108
+ return { target: 'zellij', status: 'needs_approval', command, error: before.blockers[0] || before.warnings[0] || null };
109
+ const brewArgs = hasInstalledZellij ? ['upgrade', 'zellij'] : ['install', 'zellij'];
110
+ const zellijRoot = globalSksRoot();
111
+ const zellijContract = createRequestedScopeContract({
112
+ route: 'install', userRequest: command, projectRoot: zellijRoot, overrides: { package_install: true, zellij_install: true }
113
+ });
114
+ const install = await guardedPackageInstall(guardContextForRoute(zellijRoot, zellijContract, command), 'zellij', { confirmed: true, command: brew, args: brewArgs, timeoutMs: 180000 }).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
115
+ if (install.code !== 0)
116
+ return { target: 'zellij', status: 'failed', command, error: `${install.stderr || install.stdout || command + ' failed'}`.trim() };
117
+ const after = await checkZellijCapability({ require: false, writeReport: false });
118
+ if (after.status !== 'ok')
119
+ return { target: 'zellij', status: 'installed_not_ready', command, error: after.blockers[0] || after.warnings[0] || 'zellij installed but not ready' };
120
+ return { target: 'zellij', status: hasInstalledZellij ? 'upgraded' : 'installed', command, bin: after.bin, version: after.version || null };
121
+ }
122
+ export async function maybePromptCodexUpdateForLaunch(args = [], opts = {}) {
123
+ if (hasFlag(args, '--json') || hasFlag(args, '--skip-cli-tools') || hasFlag(args, '--skip-codex-update') || process.env.SKS_SKIP_CODEX_UPDATE === '1')
124
+ return { status: 'skipped' };
125
+ const latest = await npmPackageVersion('@openai/codex');
126
+ const codex = await getCodexInfo().catch(() => EMPTY_CODEX_INFO);
127
+ const current = codexCliVersionNumber(codex.version);
128
+ const command = 'npm i -g @openai/codex@latest';
129
+ const label = opts.label || 'Zellij launch';
130
+ const missing = !codex.bin;
131
+ const updateAvailable = Boolean(latest.version && current && compareVersions(latest.version, current) > 0);
132
+ if (!missing && !updateAvailable)
133
+ return { status: 'current', latest: latest.version || null, current, bin: codex.bin || null, error: latest.error || null };
134
+ const prompt = missing
135
+ ? `Codex CLI missing. Install @openai/codex${latest.version ? ` ${latest.version}` : '@latest'} before ${label}? [Y/n] `
136
+ : `Codex CLI ${current} -> ${latest.version} update before ${label}? [Y/n] `;
137
+ if (shouldAutoApproveInstall(args))
138
+ return installCodexLatest(command, latest.version, current);
139
+ if (!canAskYesNo()) {
140
+ const reason = missing ? 'Codex CLI missing' : `Codex CLI update available: ${current} -> ${latest.version}`;
141
+ console.log(`${reason}. Run: ${command}`);
142
+ return { status: missing ? 'missing' : 'available', latest: latest.version || null, current, command, bin: codex.bin || null };
143
+ }
144
+ const answer = (await askQuestion(prompt)).trim();
145
+ if (!(answer === '' || /^(y|yes|예|네|응)$/i.test(answer)))
146
+ return { status: 'skipped_by_user', latest: latest.version || null, current, command, bin: codex.bin || null };
147
+ return installCodexLatest(command, latest.version, current);
148
+ }
149
+ export async function maybePromptSksUpdateForLaunch(args = [], opts = {}) {
150
+ void args;
151
+ void opts;
152
+ return { status: 'skipped', reason: 'manual_update_commands_only', current: PACKAGE_VERSION, latest: null, command: null };
153
+ }
154
+ export function shouldAutoApproveInstall(args = [], env = process.env) {
155
+ if (hasFlag(args, '--from-postinstall') && env.SKS_POSTINSTALL_AUTO_INSTALL_CLI_TOOLS !== '1')
156
+ return false;
157
+ if (hasFlag(args, '--from-postinstall') && env.SKS_POSTINSTALL_AUTO_INSTALL_CLI_TOOLS === '1')
158
+ return true;
159
+ return hasFlag(args, '--yes') || hasFlag(args, '-y') || isAgentRuntime(env);
160
+ }
161
+ export function canAskYesNo() {
162
+ return Boolean(input.isTTY && output.isTTY && process.env.CI !== 'true');
163
+ }
164
+ export function compareVersions(a, b) {
165
+ const pa = String(a || '').split(/[.-]/).map((value) => Number.parseInt(value, 10) || 0);
166
+ const pb = String(b || '').split(/[.-]/).map((value) => Number.parseInt(value, 10) || 0);
167
+ for (let index = 0; index < Math.max(pa.length, pb.length, 3); index += 1) {
168
+ if ((pa[index] || 0) > (pb[index] || 0))
169
+ return 1;
170
+ if ((pa[index] || 0) < (pb[index] || 0))
171
+ return -1;
172
+ }
173
+ return 0;
174
+ }
175
+ export async function isProjectSetupCandidate(root) {
176
+ for (const marker of ['package.json', '.git', 'AGENTS.md', '.codex', '.sneakoscope']) {
177
+ if (await exists(path.join(root, marker)))
178
+ return true;
179
+ }
180
+ return false;
181
+ }
182
+ export function hasTopLevelCodexModeLock(text = '') {
183
+ const lines = String(text || '').split('\n');
184
+ const firstTable = lines.findIndex((line) => /^\s*\[.+\]\s*$/.test(line));
185
+ const top = (firstTable === -1 ? lines : lines.slice(0, firstTable)).join('\n');
186
+ return /(^|\n)\s*model_reasoning_effort\s*=/.test(top);
187
+ }
188
+ export function hasDeprecatedCodexHooksFeatureFlag(text = '') {
189
+ const lines = String(text || '').split('\n');
190
+ const start = lines.findIndex((line) => line.trim() === '[features]');
191
+ if (start === -1)
192
+ return false;
193
+ const end = lines.findIndex((line, index) => index > start && /^\s*\[.+\]\s*$/.test(line));
194
+ return lines.slice(start + 1, end === -1 ? lines.length : end).some((line) => /^\s*codex_hooks\s*=/.test(line));
195
+ }
196
+ export function hasCodexUnstableFeatureWarningSuppression(text = '') {
197
+ return /(^|\n)\s*suppress_unstable_features_warning\s*=\s*true\s*(?:#.*)?(?=\n|$)/.test(String(text || ''));
198
+ }
199
+ export async function checkContext7(root) {
200
+ const projectPath = path.join(root, '.codex', 'config.toml');
201
+ const globalPath = path.join(process.env.HOME || '', '.codex', 'config.toml');
202
+ const [projectText, globalText] = await Promise.all([safeReadText(projectPath), safeReadText(globalPath)]);
203
+ const codex = await getCodexInfo().catch(() => EMPTY_CODEX_INFO);
204
+ let list = { checked: false, ok: false, stdout: '', stderr: '' };
205
+ if (codex.bin) {
206
+ const out = await runProcess(codex.bin, ['mcp', 'list'], { timeoutMs: 8000, maxOutputBytes: 32 * 1024 }).catch((err) => ({ code: 1, stderr: err.message, stdout: '' }));
207
+ list = { checked: true, ok: out.code === 0 && /context7/i.test(`${out.stdout}\n${out.stderr}`), stdout: out.stdout || '', stderr: out.stderr || '' };
208
+ }
209
+ const result = {
210
+ ok: false,
211
+ project: { path: projectPath, ok: hasContext7ConfigText(projectText) },
212
+ global: { path: globalPath, ok: hasContext7ConfigText(globalText) },
213
+ codex_mcp_list: list
214
+ };
215
+ result.ok = result.project.ok || result.codex_mcp_list.ok || (result.global.ok && !list.checked);
216
+ return result;
217
+ }
218
+ function zellijInstallHint() {
219
+ return process.platform === 'darwin' ? 'brew install zellij' : 'Install Zellij from https://zellij.dev/documentation/installation.html';
220
+ }
221
+ async function confirmInstallYesDefault(question, args = []) {
222
+ if (hasFlag(args, '--from-postinstall') && process.env.SKS_POSTINSTALL_AUTO_INSTALL_CLI_TOOLS !== '1')
223
+ return false;
224
+ if (shouldAutoApproveInstall(args))
225
+ return true;
226
+ if (!canAskYesNo())
227
+ return false;
228
+ const answer = (await askQuestion(`${question} [Y/n] `)).trim();
229
+ return answer === '' || /^(y|yes|예|네|응)$/i.test(answer);
230
+ }
231
+ async function askQuestion(question) {
232
+ const rl = readline.createInterface({ input, output });
233
+ try {
234
+ return await rl.question(question);
235
+ }
236
+ finally {
237
+ rl.close();
238
+ }
239
+ }
240
+ function hasFlag(args = [], name) {
241
+ return args.includes(name);
242
+ }
243
+ function isAgentRuntime(env = process.env) {
244
+ return ['SKS_OPENCLAW', 'OPENCLAW', 'OPENCLAW_AGENT', 'OPENCLAW_RUN_ID', 'OPENCLAW_SESSION_ID', 'SKS_HERMES', 'HERMES_AGENT', 'HERMES_RUN_ID', 'HERMES_SESSION_ID']
245
+ .some((key) => /^(1|true|yes|y)$/i.test(String(env[key] || '').trim()));
246
+ }
247
+ async function installCodexLatest(command, latestVersion, previousVersion = null) {
248
+ const npm = await which('npm').catch(() => null);
249
+ if (!npm)
250
+ return { status: 'failed', latest: latestVersion || null, previous: previousVersion || null, command, error: 'npm not found on PATH' };
251
+ const install = await runProcess(npm, ['i', '-g', '@openai/codex@latest'], { timeoutMs: 180000, maxOutputBytes: 128 * 1024 }).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
252
+ if (install.code !== 0)
253
+ return { status: 'failed', latest: latestVersion || null, previous: previousVersion || null, command, error: `${install.stderr || install.stdout || command + ' failed'}`.trim() };
254
+ const after = await getCodexInfo().catch(() => EMPTY_CODEX_INFO);
255
+ const afterVersion = codexCliVersionNumber(after.version);
256
+ if (!after.bin)
257
+ return { status: 'updated_not_reflected', latest: latestVersion || null, previous: previousVersion || null, version: afterVersion || null, command, error: 'npm completed, but codex is not on PATH. Restart the shell or set SKS_CODEX_BIN.' };
258
+ if (latestVersion && afterVersion && compareVersions(afterVersion, latestVersion) < 0) {
259
+ return { status: 'updated_not_reflected', latest: latestVersion, previous: previousVersion || null, version: afterVersion, bin: after.bin, command, error: `npm completed, but PATH still resolves Codex CLI ${afterVersion}; expected ${latestVersion}.` };
260
+ }
261
+ console.log(`Codex CLI ready: ${previousVersion || 'missing'} -> ${after.version || after.bin}`);
262
+ return { status: previousVersion ? 'updated' : 'installed', latest: latestVersion || null, previous: previousVersion || null, version: afterVersion || null, raw_version: after.version || null, bin: after.bin || null, command };
263
+ }
264
+ function codexCliVersionNumber(versionText = '') {
265
+ return String(versionText || '').match(/(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)/)?.[1] || null;
266
+ }
267
+ async function npmPackageVersion(name) {
268
+ const envName = `SKS_NPM_VIEW_${String(name || '').replace(/[^A-Za-z0-9]+/g, '_').toUpperCase()}_VERSION`;
269
+ if (process.env[envName])
270
+ return { version: process.env[envName] };
271
+ const npm = await which('npm').catch(() => null);
272
+ if (!npm)
273
+ return { error: 'npm not found' };
274
+ const result = await runProcess(npm, ['view', name, 'version'], { timeoutMs: 5000, maxOutputBytes: 4096 });
275
+ if (result.code !== 0)
276
+ return { error: `${result.stderr || result.stdout || 'npm view failed'}`.trim() };
277
+ return { version: result.stdout.trim().split(/\s+/).pop() };
278
+ }
279
+ async function safeReadText(file) {
280
+ try {
281
+ return await fsp.readFile(file, 'utf8');
282
+ }
283
+ catch {
284
+ return '';
285
+ }
286
+ }
287
+ //# sourceMappingURL=install-tool-helpers.js.map
@@ -73,6 +73,8 @@ async function dispatchInner(argv) {
73
73
  command: raw,
74
74
  reason: 'unknown_command',
75
75
  };
76
+ if (argv.includes('--json'))
77
+ console.log(JSON.stringify(result, null, 2));
76
78
  return result;
77
79
  }
78
80
  const entry = COMMAND_MANIFEST_BY_NAME[command];
@@ -80,6 +82,16 @@ async function dispatchInner(argv) {
80
82
  if (!helpRequest) {
81
83
  const commandGate = await ensureActiveRouteCommandGate(command, rest);
82
84
  if (!commandGate.ok) {
85
+ if ('command_result' in commandGate && commandGate.command_result) {
86
+ process.exitCode = 1;
87
+ if (argv.includes('--json'))
88
+ console.log(JSON.stringify(commandGate.command_result, null, 2));
89
+ else
90
+ printHandledCommandBlock(commandGate.command_result);
91
+ return commandGate.command_result;
92
+ }
93
+ if (argv.includes('--json'))
94
+ console.log(JSON.stringify(commandGate, null, 2));
83
95
  console.error(commandGate.message);
84
96
  process.exitCode = 1;
85
97
  return commandGate;
@@ -92,7 +104,11 @@ async function dispatchInner(argv) {
92
104
  const migrationGate = await ensureCurrentMigrationBeforeCommand({
93
105
  command,
94
106
  args: rest,
95
- skipMigrationGate: entry.skipMigrationGate === true || entry.readonly === true
107
+ skipMigrationGate: entry.skipMigrationGate === true
108
+ || entry.readonly === true
109
+ || safeReadOnlySubcommand(command, rest)
110
+ || safeActiveRouteVisualQuery(command, rest)
111
+ || safeActiveRouteRecoverySubcommand(command, rest)
96
112
  });
97
113
  if (!migrationGate.ok) {
98
114
  console.error('SKS project migration blocked.');
@@ -106,6 +122,8 @@ async function dispatchInner(argv) {
106
122
  console.error(`Optional warning: ${warning}`);
107
123
  console.error(`Receipt: ${migrationGate.receipt_path}`);
108
124
  console.error('Remedies: run `sks doctor --fix --yes`, then retry; diagnostics that must bypass this gate are marked skipMigrationGate in the command registry.');
125
+ if (argv.includes('--json'))
126
+ console.log(JSON.stringify(migrationGate, null, 2));
109
127
  process.exitCode = 1;
110
128
  return migrationGate;
111
129
  }
@@ -134,19 +152,30 @@ async function ensureActiveRouteCommandGate(command, args) {
134
152
  }
135
153
  if (entry.mutatesRouteState !== true)
136
154
  return { ok: true, status: 'allowed' };
137
- if (safeReadOnlySubcommand(args))
155
+ if (safeReadOnlySubcommand(command, args))
138
156
  return { ok: true, status: 'allowed_status_subcommand' };
139
- if (process.env.SKS_TEST_ISOLATION === '1' && process.env.SKS_RELEASE_FIXTURE_ACTIVE_ROUTE_BYPASS === '1') {
140
- return { ok: true, status: 'allowed_release_fixture_isolation' };
141
- }
157
+ if (safeActiveRouteVisualQuery(command, args))
158
+ return { ok: true, status: 'allowed_visual_query' };
159
+ if (safeActiveRouteRecoverySubcommand(command, args))
160
+ return { ok: true, status: 'allowed_active_route_recovery' };
142
161
  const [{ projectRoot, readJson }, { stateFile }] = await Promise.all([
143
162
  import('../core/fsx.js'),
144
163
  import('../core/mission.js')
145
164
  ]);
146
165
  const root = await projectRoot(process.cwd()).catch(() => process.cwd());
147
166
  const state = await readJson(stateFile(root), {}).catch(() => ({}));
167
+ if (safeActiveRouteContinuation(command, args, state))
168
+ return { ok: true, status: 'allowed_active_route_continuation' };
148
169
  if (!activeRouteStateBlocksCommand(state))
149
170
  return { ok: true, status: 'allowed' };
171
+ const visualPreflight = await blockedVisualSourcePreflight(command, args);
172
+ if (visualPreflight) {
173
+ return {
174
+ ok: false,
175
+ status: 'handled_non_mutating_visual_preflight',
176
+ command_result: visualPreflight
177
+ };
178
+ }
150
179
  return {
151
180
  schema: 'sks.command-gate-active-route.v1',
152
181
  ok: false,
@@ -158,12 +187,68 @@ async function ensureActiveRouteCommandGate(command, args) {
158
187
  message: `SKS command gate blocked '${command}' because active route mission ${state.mission_id} is not closed. Run: sks route close --mission ${state.mission_id}`
159
188
  };
160
189
  }
161
- function safeReadOnlySubcommand(args) {
190
+ function safeActiveRouteVisualQuery(command, args) {
191
+ if (command !== 'computer-use')
192
+ return false;
162
193
  const sub = String(args.find((arg) => !String(arg).startsWith('-')) || '').toLowerCase();
194
+ if (sub !== 'require')
195
+ return false;
196
+ return !args.some((arg) => ['--fix', '--yes', '-y', '--write', '--apply', '--execute', '--force', '--real'].includes(String(arg)));
197
+ }
198
+ async function blockedVisualSourcePreflight(command, args) {
199
+ if (command !== 'image-ux-review' || String(args[0] || '').toLowerCase() !== 'run')
200
+ return null;
201
+ if (!args.includes('--from-chrome-extension') && !args.includes('--from-computer-use'))
202
+ return null;
203
+ const { imageUxReviewSourcePreflight } = await import('../core/commands/image-ux-review-command.js');
204
+ const preflight = await imageUxReviewSourcePreflight([...args.slice(1)]);
205
+ return preflight.result;
206
+ }
207
+ function printHandledCommandBlock(result) {
208
+ console.error(`SKS command blocked: ${result?.blocker || result?.status || 'preflight_failed'}`);
209
+ for (const line of Array.isArray(result?.guidance) ? result.guidance : [])
210
+ console.error(`- ${line}`);
211
+ }
212
+ export function safeReadOnlySubcommand(command, args) {
213
+ const sub = String(args[0] || '').toLowerCase();
214
+ if (command === 'naruto' && ['status', 'subagents', 'workers', 'proof'].includes(sub)) {
215
+ return !args.some((arg) => ['--fix', '--yes', '-y', '--write', '--apply', '--execute', '--force', '--real'].includes(String(arg)));
216
+ }
163
217
  if (!['status', 'show', 'list', 'observe', 'watch', 'doctor', 'help'].includes(sub))
164
218
  return false;
165
219
  return !args.some((arg) => ['--fix', '--yes', '-y', '--write', '--apply', '--execute', '--force', '--real'].includes(String(arg)));
166
220
  }
221
+ function safeActiveRouteRecoverySubcommand(command, args) {
222
+ if (command !== 'agent')
223
+ return false;
224
+ const sub = String(args.find((arg) => !String(arg).startsWith('-')) || '').toLowerCase();
225
+ return ['close', 'cleanup', 'rollback-patches'].includes(sub);
226
+ }
227
+ function safeActiveRouteContinuation(command, args, state = {}) {
228
+ const expectedRoutes = new Map([
229
+ ['research', ['RESEARCH']],
230
+ ['autoresearch', ['AUTORESEARCH', 'RESEARCH']],
231
+ ['qa-loop', ['QALOOP']]
232
+ ]).get(command);
233
+ if (!expectedRoutes)
234
+ return false;
235
+ const subcommand = String(args[0] || '').toLowerCase();
236
+ const activeRoute = String(state.route || state.route_command || state.mode || '').replace(/^\$/, '').replace(/[-_]/g, '').toUpperCase();
237
+ if (!expectedRoutes.includes(activeRoute))
238
+ return false;
239
+ if (subcommand === 'prepare') {
240
+ const parentMissionId = String(process.env.SKS_RUN_PARENT_MISSION_ID || '').trim();
241
+ return command !== 'autoresearch'
242
+ && String(state.mode || '').toUpperCase() === 'RUN'
243
+ && String(state.phase || '').toUpperCase() === 'RUN_ROUTE_SELECTED'
244
+ && Boolean(parentMissionId)
245
+ && parentMissionId === String(state.mission_id || '');
246
+ }
247
+ if (subcommand !== 'run')
248
+ return false;
249
+ const requestedMission = String(args[1] || '').trim();
250
+ return Boolean(state.mission_id) && (requestedMission === String(state.mission_id) || requestedMission === 'latest');
251
+ }
167
252
  function activeRouteStateBlocksCommand(state = {}) {
168
253
  if (!state?.mission_id || state.route_closed === true)
169
254
  return false;