sneakoscope 7.0.0 → 7.0.3

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 (471) hide show
  1. package/README.md +7 -5
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/dist/bin/sks-dispatch.js +0 -3
  5. package/dist/cli/command-registry.js +0 -2
  6. package/dist/cli/install-helpers-codex-lb-chain.js +24 -2
  7. package/dist/cli/install-helpers-codex-lb-config.js +0 -7
  8. package/dist/cli/install-helpers-codex-lb-selftest-chain.js +0 -3
  9. package/dist/cli/install-helpers-codex-lb-selftest.js +0 -17
  10. package/dist/cli/install-helpers.js +81 -96
  11. package/dist/cli/router.js +0 -22
  12. package/dist/commands/codex-lb.js +176 -22
  13. package/dist/commands/codex.js +3 -8
  14. package/dist/commands/doctor.js +4 -14
  15. package/dist/commands/perf.js +5 -1
  16. package/dist/commands/zellij-slot-column-anchor.js +0 -2
  17. package/dist/commands/zellij-slot-pane.js +0 -7
  18. package/dist/commands/zellij.js +0 -2
  19. package/dist/config/skills-manifest.json +52 -52
  20. package/dist/core/agent-bridge/agent-manifest.js +192 -1
  21. package/dist/core/agent-bridge/agent-mode.js +0 -5
  22. package/dist/core/agent-bridge/host-capability-policy.js +189 -0
  23. package/dist/core/agent-bridge/host-capability-runtime.js +1395 -0
  24. package/dist/core/agent-bridge/mcp-server.js +1 -11
  25. package/dist/core/agents/agent-effort-policy.js +0 -3
  26. package/dist/core/agents/agent-orchestrator.js +0 -4
  27. package/dist/core/agents/agent-proof-evidence.js +0 -2
  28. package/dist/core/agents/agent-runner-ollama.js +0 -3
  29. package/dist/core/agents/agent-scheduler.js +0 -5
  30. package/dist/core/agents/native-cli-worker-runtime.js +5 -17
  31. package/dist/core/agents/work-partition/repo-inventory.js +0 -2
  32. package/dist/core/auto-review.js +0 -13
  33. package/dist/core/bench.js +0 -14
  34. package/dist/core/code-structure.js +0 -3
  35. package/dist/core/codex/agent-config-file-repair.js +0 -8
  36. package/dist/core/codex/codex-cli-update.js +122 -20
  37. package/dist/core/codex/codex-config-eperm-repair.js +0 -4
  38. package/dist/core/codex/codex-config-guard.js +0 -3
  39. package/dist/core/codex/codex-config-readability.js +0 -13
  40. package/dist/core/codex/codex-project-config-policy.js +0 -33
  41. package/dist/core/codex/official-goal-mode.js +0 -2
  42. package/dist/core/codex-app/codex-app-fast-ui-repair.js +5 -7
  43. package/dist/core/codex-app/codex-app-ui-state-snapshot.js +44 -7
  44. package/dist/core/codex-app/sks-menubar.js +0 -1
  45. package/dist/core/codex-app.js +0 -9
  46. package/dist/core/codex-compat/codex-hook-output-builders.js +9 -1
  47. package/dist/core/codex-compat/codex-hook-output-normalizer.js +1 -1
  48. package/dist/core/codex-compat/codex-hook-semantic-validator.js +3 -2
  49. package/dist/core/codex-compat/codex-hook-warning-detector.js +10 -2
  50. package/dist/core/codex-control/codex-lb-launch-recovery.js +0 -3
  51. package/dist/core/codex-control/codex-reliability-shield.js +0 -8
  52. package/dist/core/codex-control/codex-sdk-adapter.js +0 -3
  53. package/dist/core/codex-control/codex-sdk-config-policy.js +0 -2
  54. package/dist/core/codex-control/codex-sdk-env-policy.js +61 -16
  55. package/dist/core/codex-control/codex-task-runner.js +0 -7
  56. package/dist/core/codex-control/codex-thread-registry.js +0 -4
  57. package/dist/core/codex-lb/codex-lb-env.js +118 -20
  58. package/dist/core/codex-lb/codex-lb-tool-catalog.js +0 -4
  59. package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +1 -1
  60. package/dist/core/codex-model-guard.js +0 -14
  61. package/dist/core/codex-native/codex-native-feature-broker.js +67 -22
  62. package/dist/core/codex-native/codex-native-interop-policy.js +81 -9
  63. package/dist/core/codex-native/confined-report-writer.js +21 -0
  64. package/dist/core/codex-native/core-skill-integrity.js +169 -20
  65. package/dist/core/codex-native/project-skill-dedupe.js +55 -13
  66. package/dist/core/codex-native/skill-registry-ledger.js +137 -16
  67. package/dist/core/codex-native/sks-skill-paths.js +185 -0
  68. package/dist/core/codex-runtime/codex-desktop-config-policy.js +0 -2
  69. package/dist/core/commands/agent-bridge-command.js +28 -8
  70. package/dist/core/commands/basic-cli.js +67 -26
  71. package/dist/core/commands/bench-command.js +5 -1
  72. package/dist/core/commands/command-utils.js +0 -5
  73. package/dist/core/commands/image-ux-review-command.js +0 -9
  74. package/dist/core/commands/mad-sks-command.js +0 -38
  75. package/dist/core/commands/naruto-command.js +69 -17
  76. package/dist/core/commands/ppt-command.js +0 -9
  77. package/dist/core/commands/run-command.js +8 -2
  78. package/dist/core/commands/seo-command.js +0 -6
  79. package/dist/core/commands/wiki-command.js +0 -14
  80. package/dist/core/computer-use-live-evidence.js +0 -5
  81. package/dist/core/config/secret-preservation.js +0 -11
  82. package/dist/core/daemon/sksd-hook-daemon-entrypoint.js +0 -2
  83. package/dist/core/daemon/sksd-hook-daemon.js +1 -29
  84. package/dist/core/daemon/sksd-hook-dispatch.js +0 -17
  85. package/dist/core/db-safety.js +0 -7
  86. package/dist/core/doctor/browser-use-repair.js +0 -2
  87. package/dist/core/doctor/doctor-codex-startup-repair.js +0 -3
  88. package/dist/core/doctor/doctor-readiness-matrix.js +12 -0
  89. package/dist/core/doctor/doctor-skill-reconcile.js +32 -0
  90. package/dist/core/doctor/imagegen-repair.js +0 -2
  91. package/dist/core/doctor/mcp-transport-collision-repair.js +0 -3
  92. package/dist/core/doctor/retired-managed-residue-private.js +0 -1
  93. package/dist/core/doctor/supabase-mcp-repair.js +0 -11
  94. package/dist/core/feature-fixture-executor.js +0 -48
  95. package/dist/core/feature-fixtures.js +0 -5
  96. package/dist/core/fsx.js +11 -12
  97. package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +0 -5
  98. package/dist/core/hooks-runtime/hook-context.js +202 -0
  99. package/dist/core/hooks-runtime/hook-io.js +1 -12
  100. package/dist/core/hooks-runtime/light-turn.js +0 -2
  101. package/dist/core/hooks-runtime/naruto-decision-gate.js +4 -1
  102. package/dist/core/hooks-runtime/naruto-terminal-finalization.js +91 -0
  103. package/dist/core/hooks-runtime/official-subagent-lifecycle.js +370 -0
  104. package/dist/core/hooks-runtime/standalone-parent-host-capability.js +98 -0
  105. package/dist/core/hooks-runtime/subagent-context.js +59 -0
  106. package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +29 -0
  107. package/dist/core/hooks-runtime/subagent-skill-availability-evidence.js +195 -0
  108. package/dist/core/hooks-runtime/subagent-skill-availability-guards.js +316 -0
  109. package/dist/core/hooks-runtime/subagent-skill-availability.js +217 -0
  110. package/dist/core/hooks-runtime.js +259 -535
  111. package/dist/core/image-ux-review/codex-app-generated-image-discovery.js +0 -17
  112. package/dist/core/image-ux-review/imagegen-adapter.js +0 -14
  113. package/dist/core/imagegen/imagegen-auth-readiness.js +0 -9
  114. package/dist/core/imagegen/imagegen-capability.js +0 -3
  115. package/dist/core/init/managed-skill-install.js +42 -0
  116. package/dist/core/init/skills.js +247 -74
  117. package/dist/core/init.js +15 -40
  118. package/dist/core/lean-engineering-policy.js +0 -2
  119. package/dist/core/locks/file-lock.js +0 -21
  120. package/dist/core/loops/loop-planner.js +0 -6
  121. package/dist/core/loops/loop-runtime.js +0 -1
  122. package/dist/core/loops/loop-worker-runtime.js +0 -19
  123. package/dist/core/mad-sks/executors/db-write-executor.js +0 -4
  124. package/dist/core/mad-sks/executors/executor-base.js +0 -10
  125. package/dist/core/mad-sks/immutable-harness-guard.js +0 -5
  126. package/dist/core/mad-sks/sql-plane/coordinator.js +0 -5
  127. package/dist/core/mad-sks/sql-plane/ledger.js +0 -4
  128. package/dist/core/mad-sks/sql-plane/lock.js +0 -4
  129. package/dist/core/mad-sks/sql-plane/mcp-executor.js +0 -9
  130. package/dist/core/mad-sks/sql-plane/policy-resolver.js +0 -2
  131. package/dist/core/mad-sks/sql-plane/postconditions.js +0 -4
  132. package/dist/core/mad-sks/sql-plane/recovery.js +0 -2
  133. package/dist/core/mad-sks/sql-plane/runtime-profile.js +0 -8
  134. package/dist/core/managed-assets/managed-assets-manifest.js +1 -7
  135. package/dist/core/mcp-config/health-check.js +10 -3
  136. package/dist/core/migration/migration-transaction-journal.js +0 -8
  137. package/dist/core/mission.js +74 -6
  138. package/dist/core/naruto/naruto-active-pool.js +0 -2
  139. package/dist/core/naruto/naruto-concurrency-governor.js +0 -1
  140. package/dist/core/naruto/naruto-real-write-proof.js +0 -4
  141. package/dist/core/naruto/naruto-write-e2e.js +0 -1
  142. package/dist/core/perf/perf-budget.js +0 -5
  143. package/dist/core/permission-gates.js +0 -2
  144. package/dist/core/pipeline-internals/runtime-core.js +15 -5
  145. package/dist/core/pipeline-internals/runtime-gates.js +0 -12
  146. package/dist/core/preflight/parallel-preflight-engine.js +0 -11
  147. package/dist/core/proof/evidence-collector.js +0 -2
  148. package/dist/core/proof/route-finalizer.js +0 -1
  149. package/dist/core/proof/selftest-proof-fixtures.js +0 -5
  150. package/dist/core/providers/glm/bench/glm-benchmark-runner.js +0 -2
  151. package/dist/core/providers/glm/glm-request-cache.js +0 -3
  152. package/dist/core/providers/glm/naruto/glm-naruto-command.js +0 -1
  153. package/dist/core/providers/glm/naruto/glm-naruto-decomposer.js +0 -1
  154. package/dist/core/providers/glm/naruto/glm-naruto-orchestrator.js +0 -6
  155. package/dist/core/providers/glm/naruto/glm-naruto-trace.js +0 -1
  156. package/dist/core/providers/glm/naruto/glm-naruto-worker-pool.js +0 -1
  157. package/dist/core/providers/glm/naruto/glm-naruto-worktree.js +0 -1
  158. package/dist/core/providers/openrouter/openrouter-secret-store.js +0 -1
  159. package/dist/core/providers/openrouter/openrouter-stream.js +0 -2
  160. package/dist/core/questions.js +3 -3
  161. package/dist/core/release/gate-manifest.js +0 -5
  162. package/dist/core/release/package-size-budget.js +1 -1
  163. package/dist/core/release/release-gate-batch-runner.js +11 -2
  164. package/dist/core/release/release-gate-cache-v2.js +0 -4
  165. package/dist/core/release/release-gate-hermetic-env.js +0 -5
  166. package/dist/core/release-parallel-full-coverage.js +0 -2
  167. package/dist/core/remote/ssh-worker-client.js +0 -3
  168. package/dist/core/research/research-adversarial-review.js +6 -2
  169. package/dist/core/responses-retry-policy.js +0 -10
  170. package/dist/core/retention.js +0 -7
  171. package/dist/core/routes/constants.js +0 -3
  172. package/dist/core/routes.js +89 -15
  173. package/dist/core/safety/command-contract/contracts.js +2 -0
  174. package/dist/core/safety/mutation-guard.js +0 -25
  175. package/dist/core/safety/mutation-ledger.js +0 -9
  176. package/dist/core/safety/requested-scope-contract.js +0 -0
  177. package/dist/core/security/high-risk-contracts.js +0 -1
  178. package/dist/core/skills/core-skill-card.js +0 -0
  179. package/dist/core/skills/core-skill-deployment.js +0 -13
  180. package/dist/core/skills/core-skill-epoch.js +0 -11
  181. package/dist/core/skills/core-skill-meta-update.js +0 -6
  182. package/dist/core/skills/core-skill-patch-apply.js +0 -7
  183. package/dist/core/skills/core-skill-patch.js +0 -8
  184. package/dist/core/skills/core-skill-reflection.js +0 -16
  185. package/dist/core/skills/core-skill-runtime.js +0 -6
  186. package/dist/core/skills/core-skill-scorer.js +0 -7
  187. package/dist/core/skills/core-skill-trainer.js +0 -11
  188. package/dist/core/skills/core-skill-types.js +0 -9
  189. package/dist/core/skills/core-skill-validation.js +0 -5
  190. package/dist/core/skills/rejected-skill-patch-buffer.js +0 -2
  191. package/dist/core/stop-gate/stop-gate-check.js +0 -8
  192. package/dist/core/stop-gate/stop-gate-resolver.js +0 -7
  193. package/dist/core/stop-gate/stop-gate-writer.js +0 -5
  194. package/dist/core/subagents/model-policy.js +0 -7
  195. package/dist/core/subagents/naruto-help-contract.js +1 -1
  196. package/dist/core/subagents/naruto-proof-projection.js +582 -14
  197. package/dist/core/subagents/official-subagent-config.js +0 -8
  198. package/dist/core/subagents/official-subagent-preparation.js +6 -5
  199. package/dist/core/subagents/official-subagent-prompt.js +29 -0
  200. package/dist/core/subagents/official-subagent-runner.js +351 -38
  201. package/dist/core/subagents/subagent-evidence.js +378 -9
  202. package/dist/core/subagents/thread-budget.js +5 -2
  203. package/dist/core/subagents/triwiki-attention.js +0 -4
  204. package/dist/core/subagents/wave-parent-guidance.js +54 -9
  205. package/dist/core/telegram/runtime.js +0 -1
  206. package/dist/core/triwiki/code-index-scanner.js +0 -3
  207. package/dist/core/triwiki/code-pack-head-freshness.js +0 -10
  208. package/dist/core/triwiki/code-pack.js +0 -2
  209. package/dist/core/triwiki/triwiki-cache-key.js +0 -1
  210. package/dist/core/triwiki/triwiki-proof-bank.js +0 -1
  211. package/dist/core/triwiki-attention.js +0 -10
  212. package/dist/core/triwiki-provenance.js +0 -5
  213. package/dist/core/triwiki-runtime.js +0 -12
  214. package/dist/core/triwiki-wrongness/wrongness-ledger.js +0 -7
  215. package/dist/core/triwiki-wrongness/wrongness-schema.js +0 -3
  216. package/dist/core/trust-kernel/trust-report.js +0 -7
  217. package/dist/core/update/update-migration-state.js +21 -39
  218. package/dist/core/update-check.js +2 -14
  219. package/dist/core/version-manager.js +2 -0
  220. package/dist/core/version.js +1 -1
  221. package/dist/core/work-order-ledger.js +0 -17
  222. package/dist/core/zellij/zellij-clipboard-config.js +0 -18
  223. package/dist/core/zellij/zellij-lane-renderer.js +5 -46
  224. package/dist/core/zellij/zellij-lane-runtime.js +0 -1
  225. package/dist/core/zellij/zellij-launcher.js +0 -26
  226. package/dist/core/zellij/zellij-official-subagent-activity.js +0 -5
  227. package/dist/core/zellij/zellij-official-subagent-telemetry.js +0 -5
  228. package/dist/core/zellij/zellij-screen-proof.js +0 -7
  229. package/dist/core/zellij/zellij-slot-column-anchor.js +0 -1
  230. package/dist/core/zellij/zellij-slot-pane-renderer.js +0 -9
  231. package/dist/core/zellij/zellij-slot-telemetry.js +0 -12
  232. package/dist/core/zellij/zellij-ui-mode.js +0 -7
  233. package/dist/core/zellij/zellij-update.js +0 -29
  234. package/dist/core/zellij/zellij-worker-pane-manager.js +0 -39
  235. package/dist/native/sks-menubar/Sources/AlertFactory.swift +21 -2
  236. package/dist/native/sks-menubar/Sources/AppDelegate.swift +3 -0
  237. package/dist/native/sks-menubar/Sources/AppIdentity.swift +25 -0
  238. package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +254 -21
  239. package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +95 -12
  240. package/dist/scripts/agent-message-bus-reader-check.js +0 -1
  241. package/dist/scripts/all-feature-deep-completion-check.js +0 -1
  242. package/dist/scripts/appshots-thread-attachment-discovery-check.js +0 -1
  243. package/dist/scripts/architecture-guard-check.js +0 -1
  244. package/dist/scripts/build-dist.js +0 -1
  245. package/dist/scripts/build-once-runner-check.js +0 -1
  246. package/dist/scripts/canonical-test-runner.js +0 -2
  247. package/dist/scripts/certificate-sla-check.js +0 -1
  248. package/dist/scripts/changelog-check.js +0 -1
  249. package/dist/scripts/check-cli-entrypoint.js +0 -1
  250. package/dist/scripts/check-command-module-budget.js +0 -7
  251. package/dist/scripts/check-feature-quality.js +0 -1
  252. package/dist/scripts/check-legacy-free.js +0 -1
  253. package/dist/scripts/check-pipeline-runtime.js +0 -1
  254. package/dist/scripts/check-runtime-schemas.js +0 -1
  255. package/dist/scripts/codex-0-134-runner-truth-check.js +0 -1
  256. package/dist/scripts/codex-0-137-compat-check.js +0 -1
  257. package/dist/scripts/codex-0138-capability-artifact-check.js +0 -1
  258. package/dist/scripts/codex-0138-capability-check.js +0 -1
  259. package/dist/scripts/codex-0138-doctor-check.js +0 -1
  260. package/dist/scripts/codex-0138-feature-probes-check.js +0 -1
  261. package/dist/scripts/codex-0144-core-real-probes-check.js +0 -1
  262. package/dist/scripts/codex-app-handoff-check.js +0 -1
  263. package/dist/scripts/codex-app-handoff-launch-check.js +0 -1
  264. package/dist/scripts/codex-config-load-probe.js +0 -5
  265. package/dist/scripts/codex-control-all-pipelines-check.js +0 -1
  266. package/dist/scripts/codex-control-event-stream-ledger-check.js +0 -1
  267. package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +0 -1
  268. package/dist/scripts/codex-permission-profiles-check.js +0 -1
  269. package/dist/scripts/codex-plugin-app-template-policy-check.js +0 -1
  270. package/dist/scripts/codex-project-config-policy-splitter-check.js +0 -1
  271. package/dist/scripts/codex-sdk-all-pipelines-check.js +0 -1
  272. package/dist/scripts/codex-sdk-backend-router-check.js +0 -1
  273. package/dist/scripts/codex-sdk-capability-check.js +0 -1
  274. package/dist/scripts/codex-sdk-event-stream-ledger-check.js +0 -1
  275. package/dist/scripts/codex-sdk-real-smoke-check.js +0 -1
  276. package/dist/scripts/concurrent-session-collision-check.js +9 -0
  277. package/dist/scripts/context7-evidence-dedupe-check.js +0 -1
  278. package/dist/scripts/core-skill-card-schema-check.js +0 -11
  279. package/dist/scripts/core-skill-deployment-snapshot-check.js +0 -10
  280. package/dist/scripts/core-skill-heldout-validation-check.js +0 -11
  281. package/dist/scripts/core-skill-no-inference-optimizer-check.js +0 -11
  282. package/dist/scripts/core-skill-patch-check.js +0 -11
  283. package/dist/scripts/core-skill-route-runtime-integration-check.js +0 -11
  284. package/dist/scripts/current-surface-update-e2e-check.js +0 -4
  285. package/dist/scripts/current-upgrade-matrix-check.js +0 -1
  286. package/dist/scripts/dfix-fixture-check.js +0 -1
  287. package/dist/scripts/dfix-patch-handoff-check.js +0 -1
  288. package/dist/scripts/dfix-verification-check.js +0 -1
  289. package/dist/scripts/dfix-verification-recommendation-check.js +0 -1
  290. package/dist/scripts/docs-truthfulness-check.js +3 -3
  291. package/dist/scripts/doctor-fastpath-check.js +0 -1
  292. package/dist/scripts/doctor-fix-proves-codex-read-check.js +0 -11
  293. package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +0 -4
  294. package/dist/scripts/doctor-idempotence-check.js +0 -1
  295. package/dist/scripts/doctor-ops-semantics-check.js +0 -1
  296. package/dist/scripts/ensure-bin-executable.js +0 -1
  297. package/dist/scripts/evidence-flagship-coverage-check.js +0 -1
  298. package/dist/scripts/fast-codex-service-tier-proof-check.js +0 -1
  299. package/dist/scripts/fixtures/fake-codex-config-loader.js +0 -5
  300. package/dist/scripts/fsx-hotpath-check.js +0 -1
  301. package/dist/scripts/gate-policy-audit-check.js +1 -1
  302. package/dist/scripts/geo-claim-evidence-check.js +0 -1
  303. package/dist/scripts/geo-cli-blackbox-check.js +0 -1
  304. package/dist/scripts/geo-crawler-policy-check.js +0 -1
  305. package/dist/scripts/git-worktree-diff-envelope-check.js +0 -1
  306. package/dist/scripts/git-worktree-dirty-lock-check.js +0 -1
  307. package/dist/scripts/git-worktree-dirty-main-detection-check.js +0 -1
  308. package/dist/scripts/git-worktree-integration-primary-check.js +0 -1
  309. package/dist/scripts/git-worktree-manifest-append-check.js +0 -1
  310. package/dist/scripts/git-worktree-untracked-diff-check.js +0 -1
  311. package/dist/scripts/high-risk-contracts-check.js +0 -1
  312. package/dist/scripts/hook-latency-budget-check.js +0 -1
  313. package/dist/scripts/hook-latency-quantum-check.js +0 -1
  314. package/dist/scripts/image-artifact-path-contract-check.js +0 -1
  315. package/dist/scripts/imagegen-real-smoke-check.js +0 -1
  316. package/dist/scripts/import-graph-budget-check.js +0 -1
  317. package/dist/scripts/installed-package-smoke-check.js +0 -1
  318. package/dist/scripts/legacy-gate-purge-check.js +0 -1
  319. package/dist/scripts/lib/codex-sdk-gate-lib.js +0 -3
  320. package/dist/scripts/lib/ensure-dist-fresh.js +0 -1
  321. package/dist/scripts/lib/valid-png-fixture.js +0 -1
  322. package/dist/scripts/local-collab-all-pipelines-final-gpt-check.js +0 -1
  323. package/dist/scripts/loop-directive-check-lib.js +0 -1
  324. package/dist/scripts/loop-worker-fixture-child.js +0 -1
  325. package/dist/scripts/mad-preflight-blocks-unreadable-config-check.js +0 -10
  326. package/dist/scripts/mad-sks-sql-plane-lifecycle-hook-decision-check.js +0 -1
  327. package/dist/scripts/mad-sks-sql-plane-result-lifecycle-check.js +0 -1
  328. package/dist/scripts/mcp-plugin-inventory-check.js +0 -1
  329. package/dist/scripts/mcp-tool-naming-parity-check.js +0 -1
  330. package/dist/scripts/model-call-concurrency-check.js +0 -1
  331. package/dist/scripts/mutation-callsite-coverage-check.js +0 -5
  332. package/dist/scripts/naruto-codex-e2e-check.js +0 -1
  333. package/dist/scripts/naruto-worktree-coding-blackbox.js +0 -1
  334. package/dist/scripts/official-subagent-workflow-check.js +3 -1
  335. package/dist/scripts/ops-diagnostics-bundle-check.js +0 -1
  336. package/dist/scripts/packlist-performance-check.js +1 -3
  337. package/dist/scripts/perf-budget-check.js +0 -1
  338. package/dist/scripts/ppt-full-e2e-blackbox-check.js +0 -1
  339. package/dist/scripts/ppt-real-export-adapter-check.js +0 -1
  340. package/dist/scripts/ppt-real-imagegen-smoke-check.js +0 -1
  341. package/dist/scripts/ppt-real-imagegen-wiring-check.js +0 -1
  342. package/dist/scripts/ppt-reexport-rereview-check.js +0 -1
  343. package/dist/scripts/prepublish-fast-check.js +0 -23
  344. package/dist/scripts/prepublish-release-check-or-fast.js +0 -7
  345. package/dist/scripts/probe-memoization-check.js +0 -1
  346. package/dist/scripts/product-design-plugin-routing-check.js +0 -1
  347. package/dist/scripts/project-skill-dedupe-blackbox.js +36 -9
  348. package/dist/scripts/prompt-placeholder-guard-check.js +0 -1
  349. package/dist/scripts/python-codex-sdk-all-pipelines-check.js +0 -3
  350. package/dist/scripts/qa-loop-app-handoff-capability-check.js +0 -1
  351. package/dist/scripts/qa-loop-app-handoff-check.js +0 -1
  352. package/dist/scripts/qa-loop-app-handoff-cli-check.js +0 -1
  353. package/dist/scripts/qa-loop-app-handoff-confirmation-check.js +0 -1
  354. package/dist/scripts/qa-loop-app-handoff-gate-lifecycle-check.js +0 -1
  355. package/dist/scripts/qa-loop-app-handoff-launch-check.js +0 -1
  356. package/dist/scripts/qa-loop-app-handoff-status-lifecycle-check.js +0 -1
  357. package/dist/scripts/qa-loop-budget-policy-check.js +0 -1
  358. package/dist/scripts/qa-loop-effort-escalation-check.js +0 -1
  359. package/dist/scripts/qa-loop-image-path-exposure-check.js +0 -1
  360. package/dist/scripts/qa-loop-image-path-prompt-injection-check.js +0 -1
  361. package/dist/scripts/release-cache-glob-hashing-check.js +0 -1
  362. package/dist/scripts/release-cache-input-classifier-check.js +0 -1
  363. package/dist/scripts/release-cache-neutralization-report-check.js +0 -1
  364. package/dist/scripts/release-cache-version-neutral-fixture-check.js +0 -1
  365. package/dist/scripts/release-check-stamp.js +0 -4
  366. package/dist/scripts/release-dist-freshness-check.js +0 -1
  367. package/dist/scripts/release-full-parallelism-blackbox.js +3 -3
  368. package/dist/scripts/release-gate-batch-runner-check.js +22 -0
  369. package/dist/scripts/release-gate-budget-check.js +0 -6
  370. package/dist/scripts/release-gate-dag-runner-check.js +0 -1
  371. package/dist/scripts/release-latency-slo-check.js +0 -1
  372. package/dist/scripts/release-metadata-1-19-check.js +0 -1
  373. package/dist/scripts/release-metadata-check.js +0 -3
  374. package/dist/scripts/release-parallel-speed-budget-check.js +0 -5
  375. package/dist/scripts/release-proof-truth-check.js +0 -1
  376. package/dist/scripts/release-provenance-check.js +0 -1
  377. package/dist/scripts/release-real-check.js +0 -1
  378. package/dist/scripts/release-runtime-truth-matrix-check.js +0 -1
  379. package/dist/scripts/release-version-truth-check.js +0 -1
  380. package/dist/scripts/research-blueprint-densifier-check.js +0 -1
  381. package/dist/scripts/research-claim-builder-check.js +0 -1
  382. package/dist/scripts/research-complete-package-fixture-check.js +0 -1
  383. package/dist/scripts/research-final-reviewer-blackbox.js +0 -1
  384. package/dist/scripts/responses-retry-policy-centralized-check.js +0 -1
  385. package/dist/scripts/retention-apply-smoke-check.js +0 -1
  386. package/dist/scripts/retention-budget-check.js +0 -1
  387. package/dist/scripts/retention-dry-run-check.js +0 -1
  388. package/dist/scripts/rollback-recovery-smoke-check.js +0 -1
  389. package/dist/scripts/route-intent-regression-check.js +0 -1
  390. package/dist/scripts/runtime-current-terminal-check.js +0 -1
  391. package/dist/scripts/runtime-dist-parity-check.js +0 -1
  392. package/dist/scripts/runtime-no-src-mjs-check.js +0 -1
  393. package/dist/scripts/runtime-proof-summary-check.js +0 -1
  394. package/dist/scripts/runtime-ts-rust-boundary-check.js +0 -15
  395. package/dist/scripts/runtime-ts-source-of-truth-check.js +0 -1
  396. package/dist/scripts/scheduler-batch-dispatch-check.js +0 -1
  397. package/dist/scripts/scheduler-parallel-proof-consistency-check.js +0 -1
  398. package/dist/scripts/scheduler-utilization-integral-check.js +0 -1
  399. package/dist/scripts/search-visibility-gate-lib.js +0 -1
  400. package/dist/scripts/seo-audit-fixture-check.js +0 -1
  401. package/dist/scripts/seo-cli-blackbox-check.js +0 -1
  402. package/dist/scripts/seo-geo-geo-disambiguation-check.js +0 -1
  403. package/dist/scripts/seo-geo-route-identity-check.js +0 -1
  404. package/dist/scripts/seo-geo-skill-rich-content-check.js +0 -1
  405. package/dist/scripts/seo-marketing-truthfulness-check.js +0 -1
  406. package/dist/scripts/seo-metadata-sync-check.js +0 -1
  407. package/dist/scripts/seo-no-mutation-by-default-check.js +0 -1
  408. package/dist/scripts/shared-memory-fixture-check.js +0 -1
  409. package/dist/scripts/side-effect-runtime-report-check.js +0 -1
  410. package/dist/scripts/sizecheck.js +0 -1
  411. package/dist/scripts/sks-1-11-gate-lib.js +0 -1
  412. package/dist/scripts/sks-1-12-real-execution-check-lib.js +0 -1
  413. package/dist/scripts/sks-1-18-gate-lib.js +0 -1
  414. package/dist/scripts/sks-menubar-install-check.js +0 -3
  415. package/dist/scripts/sksd-daemon-check.js +0 -1
  416. package/dist/scripts/super-search-live-smoke-check.js +0 -1
  417. package/dist/scripts/super-search-local-http-smoke-check.js +0 -1
  418. package/dist/scripts/super-search-offline-contract-check.js +0 -1
  419. package/dist/scripts/super-search-provider-interface-check.js +0 -1
  420. package/dist/scripts/triwiki-cache-key-check.js +0 -1
  421. package/dist/scripts/triwiki-proof-bank-blackbox.js +0 -1
  422. package/dist/scripts/triwiki-proof-bank-check.js +0 -1
  423. package/dist/scripts/triwiki-proof-card-check.js +0 -1
  424. package/dist/scripts/trust-fixture-check.js +0 -1
  425. package/dist/scripts/ultra-router-auto-router-check.js +0 -1
  426. package/dist/scripts/update-fastpath-check.js +0 -1
  427. package/dist/scripts/upgrade-migration-matrix-check.js +0 -1
  428. package/dist/scripts/ux-review-extract-wires-real-extractor-check.js +0 -1
  429. package/dist/scripts/ux-review-imagegen-blackbox-check.js +0 -1
  430. package/dist/scripts/ux-review-patch-diff-recheck-check.js +0 -1
  431. package/dist/scripts/ux-review-real-imagegen-smoke-check.js +0 -1
  432. package/dist/scripts/ux-review-run-wires-imagegen-check.js +0 -1
  433. package/dist/scripts/write-build-manifest.js +0 -1
  434. package/dist/scripts/wrongness-fixture-check.js +0 -1
  435. package/dist/scripts/zellij-capability-check.js +0 -1
  436. package/dist/scripts/zellij-developer-controls-check.js +0 -1
  437. package/dist/scripts/zellij-doctor-readiness-check.js +0 -13
  438. package/dist/scripts/zellij-dynamic-pane-lifecycle-check.js +0 -1
  439. package/dist/scripts/zellij-fake-adapter-check.js +0 -1
  440. package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -1
  441. package/dist/scripts/zellij-lane-renderer-check.js +0 -1
  442. package/dist/scripts/zellij-launch-command-truth-check.js +0 -12
  443. package/dist/scripts/zellij-layout-valid-check.js +0 -1
  444. package/dist/scripts/zellij-pane-creation-lock-metrics-check.js +0 -1
  445. package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -1
  446. package/dist/scripts/zellij-pane-lock-does-not-block-worker-check.js +0 -1
  447. package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -1
  448. package/dist/scripts/zellij-pane-proof-check.js +0 -1
  449. package/dist/scripts/zellij-qa-app-handoff-status-check.js +0 -1
  450. package/dist/scripts/zellij-real-session-cleanup-check.js +0 -1
  451. package/dist/scripts/zellij-real-session-launch-check.js +0 -1
  452. package/dist/scripts/zellij-right-column-geometry-proof.js +0 -1
  453. package/dist/scripts/zellij-right-column-headless-overflow-check.js +0 -1
  454. package/dist/scripts/zellij-right-column-manager-check.js +0 -1
  455. package/dist/scripts/zellij-screen-proof-check.js +0 -1
  456. package/dist/scripts/zellij-slot-only-ui-check.js +0 -1
  457. package/dist/scripts/zellij-slot-pane-renderer-check.js +0 -1
  458. package/dist/scripts/zellij-slot-pane-stale-detection-check.js +0 -7
  459. package/dist/scripts/zellij-slot-telemetry-incremental-check.js +0 -1
  460. package/dist/scripts/zellij-slot-telemetry-live-flush-check.js +0 -1
  461. package/dist/scripts/zellij-slot-telemetry-performance-check.js +0 -1
  462. package/dist/scripts/zellij-stacked-capability-routing-check.js +0 -1
  463. package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -1
  464. package/dist/scripts/zellij-stacked-version-matrix-check.js +0 -1
  465. package/dist/scripts/zellij-stacked-version-parser-check.js +0 -1
  466. package/dist/scripts/zellij-ui-design-check.js +0 -12
  467. package/dist/scripts/zellij-update-prompt-matrix-check.js +0 -1
  468. package/dist/scripts/zellij-update-prompt-mode-check.js +0 -1
  469. package/dist/scripts/zellij-update-prompt-safety-check.js +0 -1
  470. package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -2
  471. package/package.json +1 -1
@@ -67,6 +67,7 @@ export async function readCodexLbModelCatalog(opts = {}) {
67
67
  try {
68
68
  const response = await fetchImpl(`${loaded.base_url}/models`, {
69
69
  headers: { Authorization: `Bearer ${loaded.secret_api_key}` },
70
+ redirect: 'error',
70
71
  signal: AbortSignal.timeout(Math.max(250, Number(opts.timeoutMs || 5000)))
71
72
  });
72
73
  const payload = await response.json().catch(() => null);
@@ -156,11 +157,12 @@ export function codexLbBaseUrlSecurityBlocker(input) {
156
157
  }
157
158
  export async function loadCodexLbEnv(opts = {}) {
158
159
  const home = opts.home || process.env.HOME || os.homedir();
160
+ const metadataPath = opts.metadataPath || codexLbMetadataPath(home);
159
161
  const envPaths = [
160
162
  opts.envPath || codexLbEnvPath(home),
161
163
  opts.legacyEnvPath || legacyCodexLbEnvPath(home)
162
164
  ];
163
- const sourcePriority = ['process.env', 'keychain', 'env-file', 'legacy-env-file'];
165
+ const sourcePriority = ['process.env', 'env-file', 'keychain', 'legacy-env-file'];
164
166
  if (opts.allowProjectSecrets)
165
167
  sourcePriority.push('project-local');
166
168
  const processEnv = pickEnv(opts.processEnv || process.env);
@@ -168,37 +170,54 @@ export async function loadCodexLbEnv(opts = {}) {
168
170
  const legacyEnv = await readEnvFile(envPaths[1]);
169
171
  const keychain = await readMacKeychain(opts);
170
172
  const projectLocal = opts.allowProjectSecrets ? await readEnvFile(path.join(opts.root || process.cwd(), '.env')) : {};
171
- const keySource = processEnv.apiKey ? 'process.env'
172
- : keychain.apiKey ? 'keychain'
173
- : envFile.apiKey ? 'env-file'
174
- : legacyEnv.apiKey ? 'legacy-env-file'
175
- : projectLocal.apiKey ? 'project-local'
176
- : 'missing';
177
- const baseUrlSource = processEnv.baseUrl ? 'process.env'
178
- : envFile.baseUrl ? 'env-file'
179
- : legacyEnv.baseUrl ? 'legacy-env-file'
180
- : projectLocal.baseUrl ? 'project-local'
181
- : 'missing';
182
- const apiKey = processEnv.apiKey || keychain.apiKey || envFile.apiKey || legacyEnv.apiKey || projectLocal.apiKey || '';
183
- const baseUrl = normalizeCodexLbBaseUrl(processEnv.baseUrl || envFile.baseUrl || legacyEnv.baseUrl || projectLocal.baseUrl || '');
173
+ const metadata = await readCodexLbCredentialMetadata(metadataPath);
174
+ const apiKeyCandidates = [
175
+ { source: 'process.env', apiKey: processEnv.apiKey },
176
+ { source: 'env-file', apiKey: envFile.apiKey },
177
+ { source: 'keychain', apiKey: keychain.apiKey },
178
+ { source: 'legacy-env-file', apiKey: legacyEnv.apiKey },
179
+ ...(opts.allowProjectSecrets ? [{ source: 'project-local', apiKey: String(projectLocal.apiKey || '') }] : [])
180
+ ].filter((candidate) => Boolean(candidate.apiKey));
181
+ const candidateFingerprints = await Promise.all(apiKeyCandidates.map(async (candidate) => ({
182
+ ...candidate,
183
+ sha256: await sha256Full(candidate.apiKey)
184
+ })));
185
+ const selectedApiKey = metadata.valid
186
+ ? candidateFingerprints.find((candidate) => candidate.sha256 === metadata.apiKeySha256) || candidateFingerprints[0]
187
+ : candidateFingerprints[0];
188
+ const keySource = selectedApiKey?.source || 'missing';
189
+ const apiKey = selectedApiKey?.apiKey || '';
190
+ const configuredBaseUrl = normalizeCodexLbBaseUrl(processEnv.baseUrl || envFile.baseUrl || legacyEnv.baseUrl || projectLocal.baseUrl || '');
191
+ const apiKeySha256 = selectedApiKey?.sha256 || '';
192
+ const binding = evaluateCodexLbCredentialBinding({
193
+ metadata,
194
+ metadataPath,
195
+ apiKeySha256,
196
+ configuredBaseUrl
197
+ });
198
+ const baseUrl = binding.present && metadata.baseUrl ? metadata.baseUrl : configuredBaseUrl;
199
+ const apiKeyUsable = Boolean(apiKey) && binding.blockers.length === 0;
184
200
  const missing = [
185
201
  ...(apiKey ? [] : ['CODEX_LB_API_KEY']),
186
- ...(baseUrl ? [] : ['CODEX_LB_BASE_URL'])
202
+ ...(baseUrl ? [] : ['CODEX_LB_BASE_URL']),
203
+ ...(binding.blockers.length ? ['CODEX_LB_CREDENTIAL_BINDING'] : [])
187
204
  ];
188
205
  return {
189
206
  schema: 'sks.codex-lb-env.v1',
190
- configured: missing.length === 0,
207
+ configured: missing.length === 0 && apiKeyUsable,
191
208
  missing,
192
209
  source: apiKey ? keySource : 'missing',
193
210
  source_priority: sourcePriority,
194
211
  base_url: baseUrl || null,
195
212
  api_key: {
196
213
  present: Boolean(apiKey),
214
+ usable: apiKeyUsable,
197
215
  source: apiKey ? keySource : null,
198
216
  redacted: true,
199
- fingerprint: apiKey ? await sha256Prefix(apiKey) : null
217
+ fingerprint: apiKeySha256 ? apiKeySha256.slice(0, 16) : null
200
218
  },
201
- secret_api_key: apiKey || null,
219
+ secret_api_key: apiKeyUsable ? apiKey : null,
220
+ credential_binding: binding,
202
221
  env_paths: envPaths,
203
222
  keychain: {
204
223
  checked: keychain.checked,
@@ -207,6 +226,85 @@ export async function loadCodexLbEnv(opts = {}) {
207
226
  }
208
227
  };
209
228
  }
229
+ async function readCodexLbCredentialMetadata(file) {
230
+ if (!(await exists(file)))
231
+ return { present: false, valid: false, baseUrl: '', apiKeySha256: '' };
232
+ const value = await readJson(file, null).catch(() => null);
233
+ const baseUrl = normalizeCodexLbBaseUrl(value?.base_url || '');
234
+ const apiKeySha256 = String(value?.api_key?.sha256 || '').trim().toLowerCase();
235
+ const valid = value?.schema === 'sks.codex-lb-metadata.v1'
236
+ && Boolean(baseUrl)
237
+ && codexLbBaseUrlSecurityBlocker(baseUrl) === null
238
+ && /^[a-f0-9]{64}$/.test(apiKeySha256);
239
+ return { present: true, valid, baseUrl, apiKeySha256 };
240
+ }
241
+ function evaluateCodexLbCredentialBinding(input) {
242
+ const base = {
243
+ checked: input.metadata.present,
244
+ present: input.metadata.present,
245
+ metadata_path: input.metadataPath
246
+ };
247
+ if (!input.metadata.present) {
248
+ return {
249
+ ...base,
250
+ valid: false,
251
+ status: 'missing',
252
+ api_key_matches: null,
253
+ base_url_matches: null,
254
+ blockers: []
255
+ };
256
+ }
257
+ if (!input.metadata.valid) {
258
+ return {
259
+ ...base,
260
+ valid: false,
261
+ status: 'invalid_metadata',
262
+ api_key_matches: null,
263
+ base_url_matches: null,
264
+ blockers: ['codex_lb_credential_metadata_invalid']
265
+ };
266
+ }
267
+ if (!input.apiKeySha256) {
268
+ return {
269
+ ...base,
270
+ valid: false,
271
+ status: 'key_missing',
272
+ api_key_matches: false,
273
+ base_url_matches: input.configuredBaseUrl ? input.configuredBaseUrl === input.metadata.baseUrl : true,
274
+ blockers: []
275
+ };
276
+ }
277
+ const apiKeyMatches = input.apiKeySha256 === input.metadata.apiKeySha256;
278
+ const baseUrlMatches = input.configuredBaseUrl ? input.configuredBaseUrl === input.metadata.baseUrl : true;
279
+ if (!apiKeyMatches) {
280
+ return {
281
+ ...base,
282
+ valid: false,
283
+ status: 'api_key_mismatch',
284
+ api_key_matches: false,
285
+ base_url_matches: baseUrlMatches,
286
+ blockers: ['codex_lb_credential_key_fingerprint_mismatch']
287
+ };
288
+ }
289
+ if (!baseUrlMatches) {
290
+ return {
291
+ ...base,
292
+ valid: false,
293
+ status: 'base_url_mismatch',
294
+ api_key_matches: true,
295
+ base_url_matches: false,
296
+ blockers: ['codex_lb_credential_base_url_mismatch']
297
+ };
298
+ }
299
+ return {
300
+ ...base,
301
+ valid: true,
302
+ status: 'matched',
303
+ api_key_matches: true,
304
+ base_url_matches: true,
305
+ blockers: []
306
+ };
307
+ }
210
308
  export async function writeCodexLbKeychain(apiKey, opts = {}) {
211
309
  const key = String(apiKey || '').trim();
212
310
  if (!key)
@@ -273,9 +371,9 @@ export function parseShellEnvValue(text = '', key = '') {
273
371
  return '';
274
372
  return raw;
275
373
  }
276
- async function sha256Prefix(value) {
374
+ async function sha256Full(value) {
277
375
  const { createHash } = await import('node:crypto');
278
- return createHash('sha256').update(value).digest('hex').slice(0, 16);
376
+ return createHash('sha256').update(value).digest('hex');
279
377
  }
280
378
  function redactSecret(text, secret) {
281
379
  return String(text || '').split(String(secret || '')).join('[redacted]');
@@ -26,8 +26,6 @@ const REQUIRED_CODEX_0144_MODEL_FIELDS = {
26
26
  supports_parallel_tool_calls: ['boolean'],
27
27
  experimental_supported_tools: ['array']
28
28
  };
29
- // Exact union observed in Codex CLI 0.144.5's native cache and codex-lb catalog.
30
- // Unknown response fields are deliberately not persisted into a Codex-owned file.
31
29
  const CODEX_0144_MODEL_FIELD_TYPES = {
32
30
  ...REQUIRED_CODEX_0144_MODEL_FIELDS,
33
31
  description: ['string'],
@@ -94,8 +92,6 @@ export function normalizeCodexLbToolCatalog(payload, opts = {}) {
94
92
  return sanitized;
95
93
  if (row.use_responses_lite !== false)
96
94
  patchedModels.push(model);
97
- // Codex 0.144.5 omits the request's `tools` field for Responses Lite.
98
- // Preserve the provider's tool_mode contract, but force full Responses.
99
95
  return { ...sanitized, use_responses_lite: false };
100
96
  });
101
97
  const compatibleRows = models.filter((row) => isCodexLbGpt56Model(row.slug));
@@ -57,7 +57,7 @@ export async function probeCodexLbToolOutputRecovery(opts = {}) {
57
57
  const response = await fetchImpl(healthUrl, {
58
58
  method: 'GET',
59
59
  headers: { accept: 'application/json' },
60
- redirect: 'follow',
60
+ redirect: 'error',
61
61
  signal: controller.signal
62
62
  });
63
63
  if (!response.ok) {
@@ -1,30 +1,16 @@
1
- /**
2
- * Codex owns the model catalog. SKS must never maintain a finite allowlist or
3
- * silently replace a model selected by the user, workspace, or Codex client.
4
- *
5
- * Reasoning effort remains an SKS scheduling hint because it is independent of
6
- * the model identifier and can be ignored by clients that do not advertise it.
7
- */
8
1
  export const DEFAULT_CODEX_REASONING_EFFORT = 'high';
9
2
  function copyArgs(args = []) {
10
3
  return Array.isArray(args) ? args.map((value) => String(value)) : [];
11
4
  }
12
- /** Return Codex arguments exactly as supplied, including future model IDs. */
13
5
  export function preserveCodexModelArgs(args = []) {
14
6
  return copyArgs(args);
15
7
  }
16
- /**
17
- * Backward-compatible aliases for callers compiled against older SKS builds.
18
- * Despite the historical name, these functions intentionally do not force a
19
- * model anymore.
20
- */
21
8
  export function forceRequiredCodexModelArgs(args = []) {
22
9
  return preserveCodexModelArgs(args);
23
10
  }
24
11
  export function forceRequiredCodexModelConfigArgs(args = []) {
25
12
  return preserveCodexModelArgs(args);
26
13
  }
27
- /** No model is forbidden by SKS; availability is decided by Codex itself. */
28
14
  export function isForbiddenCodexModel(_value = '') {
29
15
  return false;
30
16
  }
@@ -1,4 +1,5 @@
1
1
  import path from 'node:path';
2
+ import os from 'node:os';
2
3
  import fs from 'node:fs/promises';
3
4
  import { findCodexBinary } from '../codex-adapter.js';
4
5
  import { codexAppIntegrationStatus } from '../codex-app.js';
@@ -9,12 +10,14 @@ import { detectCodex0139Capability } from '../codex-control/codex-0139-capabilit
9
10
  import { detectCodex0140Capability } from '../codex-control/codex-0140-capability.js';
10
11
  import { detectCodex0144Capability } from '../codex-control/codex-0144-capability.js';
11
12
  import { buildCodexPluginInventory } from '../codex-plugins/codex-plugin-json.js';
12
- import { nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
13
+ import { nowIso, runProcess, sha256, writeJsonAtomic } from '../fsx.js';
14
+ import { inspectConfinedPath } from '../managed-path-safety.js';
13
15
  import { MANAGED_OFFICIAL_SUBAGENT_ROLES, MANAGED_SKILLS, managedOfficialSubagentRoleOwnsText } from '../managed-assets/managed-assets-manifest.js';
14
16
  import { buildMcpPluginServerCandidates } from '../mcp/mcp-plugin-inventory.js';
15
17
  import { codexNativeFeatureState, computeCodexNativeInvocationDefaults } from './codex-native-feature-matrix.js';
18
+ import { currentCodexSkillRoots, currentSksSkillName, resolveAuthoritativeSksSkillSources } from './sks-skill-paths.js';
16
19
  const REPORT_PATH = '.sneakoscope/reports/codex-native-feature-matrix.json';
17
- const REQUIRED_SKILL_NAMES = MANAGED_SKILLS.map((skill) => skill.id);
20
+ const REQUIRED_SKILL_NAMES = MANAGED_SKILLS.map((skill) => currentSksSkillName(skill.id));
18
21
  const REQUIRED_AGENT_ROLES = MANAGED_OFFICIAL_SUBAGENT_ROLES.map((role) => role.id);
19
22
  const invocationMatrixCache = new Map();
20
23
  export async function buildCodexNativeFeatureMatrix(input = { root: process.cwd() }) {
@@ -218,24 +221,12 @@ export async function buildCodexNativeFeatureMatrix(input = { root: process.cwd(
218
221
  return matrix;
219
222
  }
220
223
  async function inspectManagedSkillState(root) {
221
- const skillRoots = [
222
- path.join(root, '.agents', 'skills'),
223
- ...(process.env.CODEX_HOME ? [path.join(process.env.CODEX_HOME, 'skills')] : [])
224
- ];
225
- let existingCount = 0;
226
- const managed = new Set();
227
- for (const dir of skillRoots) {
228
- const rows = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
229
- existingCount += rows.filter((row) => row.isDirectory()).length;
230
- for (const name of REQUIRED_SKILL_NAMES) {
231
- if (managed.has(name))
232
- continue;
233
- const text = await fs.readFile(path.join(dir, name, 'SKILL.md'), 'utf8').catch(() => '');
234
- if (text.includes('BEGIN SKS MANAGED SKILL') || text.includes('BEGIN SKS IMMUTABLE CORE SKILL'))
235
- managed.add(name);
236
- }
237
- }
224
+ const home = path.resolve(process.env.HOME || os.homedir());
225
+ const authoritativeRoot = currentCodexSkillRoots({ root, home }).find((entry) => entry.scope === 'global')?.root;
226
+ const resolution = await resolveAuthoritativeSksSkillSources({ root, home, skillNames: REQUIRED_SKILL_NAMES });
227
+ const managed = new Set(resolution.sources.map((source) => source.canonical_name));
238
228
  const missing = REQUIRED_SKILL_NAMES.filter((name) => !managed.has(name));
229
+ const existingCount = authoritativeRoot ? await countConfinedSkillDirectories(home, authoritativeRoot) : 0;
239
230
  return {
240
231
  ok: missing.length === 0,
241
232
  apply: false,
@@ -243,7 +234,10 @@ async function inspectManagedSkillState(root) {
243
234
  existing_count: existingCount,
244
235
  managed_count: managed.size,
245
236
  missing_required: missing,
246
- blockers: missing.length ? [`managed_skills_missing:${missing.join(',')}`] : [],
237
+ blockers: [
238
+ ...(missing.length ? [`managed_skills_missing:${missing.join(',')}`] : []),
239
+ ...resolution.blockers.map((blocker) => `managed_skill_${blocker}`)
240
+ ],
247
241
  warnings: existingCount > managed.size ? ['non_sks_skill_dirs_ignored'] : []
248
242
  };
249
243
  }
@@ -271,12 +265,17 @@ async function inspectManagedAgentRoleState(root) {
271
265
  };
272
266
  }
273
267
  async function readManagedAssetFingerprint(root) {
268
+ const home = path.resolve(process.env.HOME || os.homedir());
269
+ const authoritativeSkillRoots = currentCodexSkillRoots({ root, home })
270
+ .filter((entry) => entry.scope === 'global')
271
+ .map((entry) => entry.root);
274
272
  const dirs = [
275
- path.join(root, '.agents', 'skills'),
276
273
  path.join(root, '.codex', 'agents'),
277
- ...(process.env.CODEX_HOME ? [path.join(process.env.CODEX_HOME, 'skills'), path.join(process.env.CODEX_HOME, 'agents')] : [])
274
+ ...(process.env.CODEX_HOME ? [path.join(process.env.CODEX_HOME, 'agents')] : [])
278
275
  ];
279
276
  const rows = [];
277
+ for (const dir of authoritativeSkillRoots)
278
+ rows.push(...await readConfinedSkillRootFingerprint(home, dir));
280
279
  for (const dir of dirs) {
281
280
  const stat = await fs.stat(dir).catch(() => null);
282
281
  rows.push(`${dir}:${stat ? `${stat.mtimeMs}:${stat.size}` : 'missing'}`);
@@ -295,6 +294,52 @@ async function readManagedAssetFingerprint(root) {
295
294
  }
296
295
  return rows;
297
296
  }
297
+ async function countConfinedSkillDirectories(home, skillsRoot) {
298
+ try {
299
+ const inspection = await inspectConfinedPath(home, skillsRoot);
300
+ if (!inspection.exists || inspection.leafSymlink || !inspection.stat?.isDirectory())
301
+ return 0;
302
+ const rows = await fs.readdir(skillsRoot, { withFileTypes: true });
303
+ return rows.filter((row) => row.isDirectory()).length;
304
+ }
305
+ catch {
306
+ return 0;
307
+ }
308
+ }
309
+ async function readConfinedSkillRootFingerprint(home, skillsRoot) {
310
+ try {
311
+ const inspection = await inspectConfinedPath(home, skillsRoot);
312
+ if (!inspection.exists)
313
+ return [`${skillsRoot}:missing`];
314
+ if (inspection.leafSymlink || !inspection.stat?.isDirectory())
315
+ return [`${skillsRoot}:unsafe`];
316
+ const rows = [`${skillsRoot}:directory`];
317
+ const entries = await fs.readdir(skillsRoot, { withFileTypes: true });
318
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
319
+ const file = path.join(skillsRoot, entry.name, 'SKILL.md');
320
+ try {
321
+ const child = await inspectConfinedPath(home, file);
322
+ if (!child.exists) {
323
+ rows.push(`${entry.name}:missing`);
324
+ }
325
+ else if (child.leafSymlink || !child.stat?.isFile()) {
326
+ rows.push(`${entry.name}:unsafe`);
327
+ }
328
+ else {
329
+ const text = await fs.readFile(file, 'utf8');
330
+ rows.push(`${entry.name}:file:${sha256(text)}`);
331
+ }
332
+ }
333
+ catch {
334
+ rows.push(`${entry.name}:unsafe`);
335
+ }
336
+ }
337
+ return rows;
338
+ }
339
+ catch {
340
+ return [`${skillsRoot}:unsafe`];
341
+ }
342
+ }
298
343
  export async function writeCodexNativeFeatureMatrix(root, matrix, missionDir) {
299
344
  await writeJsonAtomic(path.join(root, REPORT_PATH), matrix);
300
345
  if (missionDir)
@@ -1,20 +1,33 @@
1
1
  import path from 'node:path';
2
2
  import os from 'node:os';
3
3
  import fs from 'node:fs/promises';
4
- import { nowIso, writeJsonAtomic } from '../fsx.js';
4
+ import { nowIso } from '../fsx.js';
5
5
  import { buildCodexPluginInventory } from '../codex-plugins/codex-plugin-json.js';
6
+ import { inspectConfinedPath, isLexicallyConfined } from '../managed-path-safety.js';
7
+ import { currentCodexSkillRoots } from './sks-skill-paths.js';
8
+ import { writeRootConfinedJsonReport } from './confined-report-writer.js';
6
9
  const RESERVED_EXTERNAL_ROUTE_SKILLS = ['ulw-loop', 'ulw-plan', 'start-work'];
7
10
  export async function buildCodexNativeInteropPolicy(input) {
8
11
  const root = path.resolve(input.root);
9
12
  const inventory = normalizeInventory(input.inventory || await buildCodexPluginInventory().catch((err) => ({ plugins: [], blockers: [messageOf(err)] })));
10
- const codexHome = input.codexHome || process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
11
- const skillNames = await discoverSkillNames([path.join(root, '.agents', 'skills'), path.join(codexHome, 'skills')]);
13
+ const home = path.resolve(process.env.HOME || os.homedir());
14
+ const codexHome = path.resolve(input.codexHome || process.env.CODEX_HOME || path.join(home, '.codex'));
15
+ const codexHomeBoundary = isLexicallyConfined(home, codexHome) ? home : path.dirname(codexHome);
16
+ const skillScan = await discoverSkillNames(currentCodexSkillRoots({ root, home, codexHome }).map((entry) => ({
17
+ ...entry,
18
+ boundary: entry.scope === 'global'
19
+ ? home
20
+ : entry.scope === 'project'
21
+ ? root
22
+ : codexHomeBoundary
23
+ })));
24
+ const skillNames = skillScan.names;
12
25
  const pluginIds = (inventory.plugins || []).map((plugin) => `${plugin.id || ''} ${plugin.name || ''}`.toLowerCase()).filter(Boolean);
13
26
  const preservedSkillNames = RESERVED_EXTERNAL_ROUTE_SKILLS.filter((name) => skillNames.includes(name));
14
27
  const report = {
15
28
  schema: 'sks.codex-native-interop-policy.v1',
16
29
  generated_at: nowIso(),
17
- ok: true,
30
+ ok: skillScan.blockers.length === 0,
18
31
  mode: input.mode || 'coexist',
19
32
  detection: {
20
33
  plugin_inventory_ids: pluginIds,
@@ -28,9 +41,18 @@ export async function buildCodexNativeInteropPolicy(input) {
28
41
  artifact_names_brand_neutral: true
29
42
  },
30
43
  actions: preservedSkillNames.map((name) => `preserve_existing_skill:${name}`),
31
- blockers: []
44
+ blockers: skillScan.blockers
32
45
  };
33
- await writeJsonAtomic(path.join(root, '.sneakoscope', 'reports', 'codex-native-interop-policy.json'), report).catch(() => undefined);
46
+ const reportPath = input.reportPath === null
47
+ ? null
48
+ : input.reportPath || path.join(root, '.sneakoscope', 'reports', 'codex-native-interop-policy.json');
49
+ if (reportPath) {
50
+ const written = await writeRootConfinedJsonReport({ root, reportPath, value: report });
51
+ if (!written) {
52
+ report.ok = false;
53
+ report.blockers = [...new Set([...report.blockers, 'codex_native_interop_report_path_unsafe'])].sort();
54
+ }
55
+ }
34
56
  return report;
35
57
  }
36
58
  function normalizeInventory(value) {
@@ -47,11 +69,61 @@ function messageOf(err) {
47
69
  }
48
70
  async function discoverSkillNames(roots) {
49
71
  const names = new Set();
50
- for (const root of roots) {
51
- const entries = await fs.readdir(root, { withFileTypes: true }).catch(() => []);
72
+ const blockers = new Set();
73
+ for (const candidate of roots) {
74
+ let inspection;
75
+ try {
76
+ inspection = await inspectConfinedPath(candidate.boundary, candidate.root);
77
+ }
78
+ catch (error) {
79
+ blockers.add(unsafeSkillScanRootBlocker(candidate.scope, skillScanRootInspectionFailureReason(error)));
80
+ continue;
81
+ }
82
+ if (!inspection.exists)
83
+ continue;
84
+ if (inspection.leafSymlink) {
85
+ blockers.add(unsafeSkillScanRootBlocker(candidate.scope, 'leaf_symlink'));
86
+ continue;
87
+ }
88
+ if (!inspection.stat?.isDirectory()) {
89
+ blockers.add(unsafeSkillScanRootBlocker(candidate.scope, 'not_directory'));
90
+ continue;
91
+ }
92
+ let entries;
93
+ try {
94
+ entries = await fs.readdir(candidate.root, { withFileTypes: true });
95
+ }
96
+ catch {
97
+ blockers.add(unsafeSkillScanRootBlocker(candidate.scope, 'readdir_failed'));
98
+ continue;
99
+ }
52
100
  for (const entry of entries)
53
101
  if (entry.isDirectory())
54
102
  names.add(entry.name);
55
103
  }
56
- return [...names].sort();
104
+ return { names: [...names].sort(), blockers: [...blockers].sort() };
105
+ }
106
+ function unsafeSkillScanRootBlocker(scope, reason) {
107
+ return `unsafe_skill_scan_root:${skillScanRootScopeCode(scope)}:${reason}`;
108
+ }
109
+ function skillScanRootScopeCode(scope) {
110
+ if (scope === 'global' || scope === 'project' || scope === 'codex-home')
111
+ return scope;
112
+ return 'unknown';
113
+ }
114
+ function skillScanRootInspectionFailureReason(error) {
115
+ const code = error && typeof error === 'object' && 'code' in error ? error.code : null;
116
+ if (code === 'managed_path_boundary_missing')
117
+ return 'boundary_missing';
118
+ if (code === 'managed_path_boundary_symlink_refused')
119
+ return 'boundary_symlink';
120
+ if (code === 'managed_path_boundary_not_directory')
121
+ return 'boundary_not_directory';
122
+ if (code === 'managed_path_escape_refused')
123
+ return 'escape_refused';
124
+ if (code === 'managed_path_ancestor_symlink_refused')
125
+ return 'ancestor_symlink';
126
+ if (code === 'managed_path_ancestor_not_directory')
127
+ return 'ancestor_not_directory';
128
+ return 'inspection_failed';
57
129
  }
@@ -0,0 +1,21 @@
1
+ import path from 'node:path';
2
+ import { writeJsonAtomic } from '../fsx.js';
3
+ import { ensureConfinedDirectory, inspectConfinedPath, isLexicallyConfined } from '../managed-path-safety.js';
4
+ export async function writeRootConfinedJsonReport(input) {
5
+ const root = path.resolve(input.root);
6
+ const reportPath = path.resolve(input.reportPath);
7
+ if (!isLexicallyConfined(root, reportPath) || reportPath === root)
8
+ return false;
9
+ try {
10
+ await ensureConfinedDirectory(root, path.dirname(reportPath));
11
+ const before = await inspectConfinedPath(root, reportPath);
12
+ if (before.exists && (before.leafSymlink || !before.stat?.isFile()))
13
+ return false;
14
+ await writeJsonAtomic(reportPath, input.value);
15
+ const after = await inspectConfinedPath(root, reportPath);
16
+ return after.exists && !after.leafSymlink && Boolean(after.stat?.isFile());
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }