sneakoscope 7.1.0 → 7.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (534) hide show
  1. package/README.md +9 -1
  2. package/config/architecture-budgets.v1.json +1 -8
  3. package/crates/sks-core/Cargo.lock +225 -1
  4. package/crates/sks-core/Cargo.toml +8 -1
  5. package/crates/sks-core/src/main.rs +7 -1
  6. package/crates/sks-core/src/search/files.rs +114 -0
  7. package/crates/sks-core/src/search/mod.rs +274 -0
  8. package/crates/sks-core/src/search/text.rs +175 -0
  9. package/dist/bin/sks-dispatch.js +4 -3
  10. package/dist/cli/command-manifest-lite.js +177 -6
  11. package/dist/cli/command-registry.js +42 -8
  12. package/dist/cli/help.js +30 -0
  13. package/dist/cli/install-helpers-codex-lb-config.js +9 -6
  14. package/dist/cli/install-helpers-codex-lb-selftest-chain.js +1 -1
  15. package/dist/cli/install-helpers-install-support.js +1 -1
  16. package/dist/cli/install-helpers.js +19 -9
  17. package/dist/cli/router.js +16 -3
  18. package/dist/commands/codex-app.js +40 -5
  19. package/dist/commands/doctor-profile.js +78 -0
  20. package/dist/commands/doctor.js +29 -69
  21. package/dist/commands/search.js +4 -0
  22. package/dist/config/skills-manifest.json +53 -60
  23. package/dist/core/agent-bridge/agent-manifest.js +22 -26
  24. package/dist/core/agent-bridge/host-capability-policy.js +109 -8
  25. package/dist/core/agent-bridge/host-capability-runtime.js +178 -50
  26. package/dist/core/agent-guidance/directive-registry.js +123 -0
  27. package/dist/core/agents/agent-effort-policy.js +45 -6
  28. package/dist/core/agents/agent-worker-pipeline.js +1 -3
  29. package/dist/core/agents/native-worker-backend-router.js +43 -19
  30. package/dist/core/auto-review.js +1 -3
  31. package/dist/core/code-structure.js +282 -19
  32. package/dist/core/codex/codex-config-guard.js +14 -4
  33. package/dist/core/codex/codex-config-toml.js +1 -3
  34. package/dist/core/codex-app/codex-agent-role-sync.js +1 -3
  35. package/dist/core/codex-app/codex-app-fast-ui-repair.js +14 -1
  36. package/dist/core/codex-app/codex-app-types.js +2 -3
  37. package/dist/core/codex-app/codex-desktop-routing-ownership.js +91 -0
  38. package/dist/core/codex-app/codex-hook-approval-probe.js +1 -3
  39. package/dist/core/codex-app/codex-hook-lifecycle.js +1 -3
  40. package/dist/core/codex-app/codex-init-deep.js +22 -10
  41. package/dist/core/codex-app/codex-model-catalog.js +384 -0
  42. package/dist/core/codex-app/codex-models-cache.js +160 -0
  43. package/dist/core/codex-app/desktop-routing-snapshot.js +233 -0
  44. package/dist/core/codex-app/glm-profile-installer.js +1 -3
  45. package/dist/core/codex-app/mcp-manager.js +1 -3
  46. package/dist/core/codex-app/menubar/constants.js +3 -0
  47. package/dist/core/codex-app/menubar/installer.js +11 -1
  48. package/dist/core/codex-app/multi-provider-router-support.js +202 -0
  49. package/dist/core/codex-app/multi-provider-router.js +379 -0
  50. package/dist/core/codex-app/openrouter-activate.js +189 -26
  51. package/dist/core/codex-app/openrouter-base-instructions.js +1 -0
  52. package/dist/core/codex-app/openrouter-model-catalog.js +217 -0
  53. package/dist/core/codex-app/role-model-catalog-priority.js +61 -0
  54. package/dist/core/codex-app.js +30 -6
  55. package/dist/core/codex-compat/codex-hook-semantic-validator.js +1 -3
  56. package/dist/core/codex-control/codex-app-server-v2-client.js +39 -2
  57. package/dist/core/codex-lb/codex-lb-env.js +1 -3
  58. package/dist/core/codex-lb/codex-lb-tool-catalog.js +6 -1
  59. package/dist/core/codex-native/codex-native-feature-broker.js +2 -6
  60. package/dist/core/codex-native/codex-native-interop-policy.js +1 -3
  61. package/dist/core/codex-native/codex-native-reference-cache.js +1 -3
  62. package/dist/core/codex-native/codex-native-reference-source.js +1 -3
  63. package/dist/core/codex-native/codex-native-repair-transaction.js +1 -3
  64. package/dist/core/codex-native/core-skill-manifest.js +3 -2
  65. package/dist/core/codex-native/native-capability-repair-matrix.js +1 -3
  66. package/dist/core/codex-plugins/codex-plugin-repair.js +1 -3
  67. package/dist/core/codex-runtime/codex-desktop-config-policy.js +4 -4
  68. package/dist/core/commands/agent-bridge-command.js +24 -3
  69. package/dist/core/commands/image-ux-review-command.js +5 -11
  70. package/dist/core/commands/menubar-command.js +1 -1
  71. package/dist/core/commands/naruto-command.js +40 -13
  72. package/dist/core/commands/pipeline-command.js +5 -2
  73. package/dist/core/commands/release-command.js +63 -1
  74. package/dist/core/commands/remote-command.js +18 -0
  75. package/dist/core/commands/search-command.js +151 -0
  76. package/dist/core/commands/telegram-command.js +251 -108
  77. package/dist/core/commands/uninstall-command.js +1 -1
  78. package/dist/core/config/secret-preservation.js +1 -3
  79. package/dist/core/context7-client.js +2 -1
  80. package/dist/core/db-review.js +704 -0
  81. package/dist/core/db-safety.js +17 -23
  82. package/dist/core/doctor/browser-use-repair.js +1 -3
  83. package/dist/core/doctor/codex-startup-config-repair.js +1 -3
  84. package/dist/core/doctor/computer-use-repair.js +1 -3
  85. package/dist/core/doctor/context7-mcp-repair.js +1 -3
  86. package/dist/core/doctor/current-project-guidance.js +1 -3
  87. package/dist/core/doctor/doctor-codex-startup-repair.js +1 -3
  88. package/dist/core/doctor/doctor-dirty-planner.js +2 -2
  89. package/dist/core/doctor/doctor-native-capability-repair.js +1 -3
  90. package/dist/core/doctor/doctor-transaction.js +1 -3
  91. package/dist/core/doctor/imagegen-repair.js +1 -3
  92. package/dist/core/doctor/legacy-global-hook-cleanup.js +1 -3
  93. package/dist/core/doctor/mcp-transport-collision-repair.js +1 -3
  94. package/dist/core/doctor/retired-managed-residue-private.js +1 -3
  95. package/dist/core/doctor/supabase-mcp-repair.js +1 -3
  96. package/dist/core/engineering-sanity-review.js +186 -0
  97. package/dist/core/errors/message.js +3 -0
  98. package/dist/core/evidence/evidence-schema.js +1 -3
  99. package/dist/core/feature-fixtures.js +1 -0
  100. package/dist/core/feature-registry.js +1 -3
  101. package/dist/core/fsx.js +13 -0
  102. package/dist/core/git-hygiene/shared-memory-publish.js +1 -3
  103. package/dist/core/git-hygiene/validators.js +1 -3
  104. package/dist/core/harness-guard.js +21 -3
  105. package/dist/core/hooks-runtime/hook-context.js +2 -2
  106. package/dist/core/image-ux-review/imagegen-adapter.js +52 -56
  107. package/dist/core/image-ux-review/real-callout-extractor.js +6 -1
  108. package/dist/core/image-ux-review.js +3 -5
  109. package/dist/core/imagegen/codex-lb-imagegen-target.js +70 -0
  110. package/dist/core/imagegen/imagegen-capability.js +11 -11
  111. package/dist/core/imagegen/imagegen-evidence.js +32 -0
  112. package/dist/core/init/skills.js +9 -11
  113. package/dist/core/init.js +4 -6
  114. package/dist/core/json/records.js +9 -0
  115. package/dist/core/json-schema-validator.js +1 -3
  116. package/dist/core/lean-engineering-policy.js +54 -0
  117. package/dist/core/loops/loop-continuation-enforcer.js +1 -3
  118. package/dist/core/mad-sks/sql-plane/mcp-executor.js +2 -1
  119. package/dist/core/mad-sks/sql-plane/policy.js +2 -1
  120. package/dist/core/managed-assets/managed-assets-manifest.js +4 -3
  121. package/dist/core/mcp-config/codex-cli-adapter.js +1 -3
  122. package/dist/core/mcp-config/config-reader.js +2 -3
  123. package/dist/core/mcp-config/guarded-patch.js +1 -1
  124. package/dist/core/mcp-config/health-check.js +2 -1
  125. package/dist/core/mcp-config/mutation.js +1 -1
  126. package/dist/core/mcp-config/restore.js +1 -1
  127. package/dist/core/mcp-config/secret-policy.js +1 -3
  128. package/dist/core/migration/migration-transaction-journal.js +3 -3
  129. package/dist/core/naruto/naruto-concurrency-governor.js +2 -2
  130. package/dist/core/perf/import-graph-budget.js +91 -1
  131. package/dist/core/pipeline/pipeline-plan-writer.js +1 -1
  132. package/dist/core/pipeline-internals/runtime-core.js +121 -23
  133. package/dist/core/pipeline-internals/runtime-gates.js +193 -4
  134. package/dist/core/pipeline.js +1 -1
  135. package/dist/core/ppt-review/slide-imagegen-review.js +7 -7
  136. package/dist/core/ppt.js +3 -3
  137. package/dist/core/product-design-app-server.js +2 -1
  138. package/dist/core/proof/fake-real-proof-policy.js +1 -3
  139. package/dist/core/proof/root-cause-policy.js +1 -3
  140. package/dist/core/proof/validation.js +1 -3
  141. package/dist/core/provider/model-router.js +4 -0
  142. package/dist/core/provider/provider-context.js +1 -3
  143. package/dist/core/providers/openrouter/openrouter-account.js +1 -3
  144. package/dist/core/quality/helper-dedup.js +0 -0
  145. package/dist/core/recallpulse.js +1 -1
  146. package/dist/core/release/file-ownership.js +26 -17
  147. package/dist/core/release/macos-menubar-proof.js +59 -1
  148. package/dist/core/release/main-push-guard.js +288 -24
  149. package/dist/core/release/main-push-receipt.js +10 -45
  150. package/dist/core/release/package-size-budget.js +1 -1
  151. package/dist/core/release/release-gate-contract.js +2 -0
  152. package/dist/core/release/release-pack-receipt.js +1 -1
  153. package/dist/core/release/release-proof-io.js +33 -0
  154. package/dist/core/release/release-upgrade-baseline.js +9 -0
  155. package/dist/core/release/runtime-script-pack-closure.js +153 -4
  156. package/dist/core/release/stage-publish.js +194 -0
  157. package/dist/core/remote/index.js +2 -0
  158. package/dist/core/remote/local-worker-client.js +35 -0
  159. package/dist/core/remote/machine-registry.js +18 -13
  160. package/dist/core/remote/owner-proof.js +1 -3
  161. package/dist/core/remote/protocol.js +1 -3
  162. package/dist/core/remote/readiness.js +1 -3
  163. package/dist/core/remote/session-binding.js +153 -0
  164. package/dist/core/remote/session-index.js +1 -3
  165. package/dist/core/remote/types.js +1 -0
  166. package/dist/core/remote/worker.js +228 -14
  167. package/dist/core/responses-stream.js +151 -0
  168. package/dist/core/routes/dollar-manifest-lite.js +1 -1
  169. package/dist/core/routes.js +8 -8
  170. package/dist/core/rust-accelerator.js +12 -2
  171. package/dist/core/safety/ssot-guard.js +1 -3
  172. package/dist/core/search/benchmark.js +358 -0
  173. package/dist/core/search/cache.js +65 -0
  174. package/dist/core/search/context.js +144 -0
  175. package/dist/core/search/doctor.js +74 -0
  176. package/dist/core/search/files.js +192 -0
  177. package/dist/core/search/index.js +5 -0
  178. package/dist/core/search/ipc.js +64 -0
  179. package/dist/core/search/provider.js +142 -0
  180. package/dist/core/search/rust-bridge.js +24 -0
  181. package/dist/core/search/structure.js +230 -0
  182. package/dist/core/search/symbol.js +272 -0
  183. package/dist/core/search/text.js +146 -0
  184. package/dist/core/search/types.js +22 -0
  185. package/dist/core/search/typescript-ls.js +215 -0
  186. package/dist/core/search-visibility/discovery.js +1 -3
  187. package/dist/core/skill-forge.js +1 -1
  188. package/dist/core/stop-gate/gate-evaluator.js +3 -3
  189. package/dist/core/stop-gate/stop-gate-check.js +1 -3
  190. package/dist/core/structured-output-adapter.js +62 -2
  191. package/dist/core/subagents/agent-catalog.js +56 -43
  192. package/dist/core/subagents/model-policy.js +17 -7
  193. package/dist/core/subagents/naruto-proof-projection.js +2 -6
  194. package/dist/core/subagents/official-subagent-config.js +1 -3
  195. package/dist/core/subagents/official-subagent-preparation.js +73 -10
  196. package/dist/core/subagents/official-subagent-prompt.js +85 -18
  197. package/dist/core/subagents/official-subagent-runner.js +10 -5
  198. package/dist/core/subagents/role-model-preferences.js +202 -44
  199. package/dist/core/subagents/subagent-evidence.js +1 -3
  200. package/dist/core/subagents/thread-budget.js +1 -1
  201. package/dist/core/subagents/triwiki-attention.js +1 -5
  202. package/dist/core/telegram/config.js +29 -12
  203. package/dist/core/telegram/hub.js +8 -2
  204. package/dist/core/telegram/index.js +2 -0
  205. package/dist/core/telegram/messages.js +8 -2
  206. package/dist/core/telegram/runtime-projection.js +8 -5
  207. package/dist/core/telegram/runtime.js +19 -9
  208. package/dist/core/telegram/service.js +181 -0
  209. package/dist/core/telegram/setup.js +220 -0
  210. package/dist/core/text/regex.js +3 -0
  211. package/dist/core/text/strings.js +6 -0
  212. package/dist/core/triwiki-wrongness/image-wrongness.js +1 -3
  213. package/dist/core/triwiki-wrongness/wrongness-ledger.js +1 -3
  214. package/dist/core/triwiki-wrongness/wrongness-proof-linker.js +1 -3
  215. package/dist/core/triwiki-wrongness/wrongness-retrieval.js +1 -3
  216. package/dist/core/triwiki-wrongness/wrongness-schema.js +1 -3
  217. package/dist/core/triwiki-wrongness/wrongness-trust-policy.js +1 -3
  218. package/dist/core/trust-kernel/completion-contract.js +1 -3
  219. package/dist/core/trust-kernel/route-contract.js +1 -3
  220. package/dist/core/update/update-migration-state.js +1 -3
  221. package/dist/core/update-check.js +20 -6
  222. package/dist/core/verification/diff-quality.js +3 -4
  223. package/dist/core/verification/impact-scan.js +36 -89
  224. package/dist/core/verification/mistake-rule-compiler.js +17 -4
  225. package/dist/core/version-manager.js +3 -20
  226. package/dist/core/version.js +1 -1
  227. package/dist/native/sks-menubar/Sources/ControlCenterWindowController.swift +23 -3
  228. package/dist/native/sks-menubar/Sources/ControlKit.swift +102 -0
  229. package/dist/native/sks-menubar/Sources/DiagnosticsViewController.swift +23 -11
  230. package/dist/native/sks-menubar/Sources/MCPServersViewController.swift +7 -3
  231. package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +17 -1
  232. package/dist/native/sks-menubar/Sources/OverviewViewController.swift +22 -15
  233. package/dist/native/sks-menubar/Sources/ProcessClient.swift +15 -5
  234. package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +324 -0
  235. package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +154 -214
  236. package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +252 -0
  237. package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +77 -71
  238. package/dist/native/sks-menubar/Sources/RemoteTelegramViewController.swift +167 -51
  239. package/dist/native/sks-menubar/Sources/SettingsViewController.swift +14 -5
  240. package/dist/native/sks-menubar/Sources/SidebarItem.swift +15 -1
  241. package/dist/native/sks-menubar/Sources/StatusItemController.swift +2 -2
  242. package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +16 -12
  243. package/dist/scripts/agent-guidance-dedup-check.js +23 -0
  244. package/dist/scripts/agent-message-bus-reader-check.js +1 -1
  245. package/dist/scripts/all-feature-deep-completion-check.js +1 -1
  246. package/dist/scripts/appshots-thread-attachment-discovery-check.js +1 -1
  247. package/dist/scripts/architecture-guard-check.js +1 -2
  248. package/dist/scripts/certificate-sla-check.js +1 -1
  249. package/dist/scripts/cli-output-consistency-check.js +1 -1
  250. package/dist/scripts/codex-0-134-runner-truth-check.js +1 -1
  251. package/dist/scripts/codex-0138-capability-artifact-check.js +1 -1
  252. package/dist/scripts/codex-0138-capability-check.js +1 -1
  253. package/dist/scripts/codex-0138-doctor-check.js +1 -1
  254. package/dist/scripts/codex-0138-feature-probes-check.js +1 -1
  255. package/dist/scripts/codex-0144-app-server-v2-check.js +1 -1
  256. package/dist/scripts/codex-0144-binary-identity-check.js +1 -1
  257. package/dist/scripts/codex-0144-capability-check.js +1 -1
  258. package/dist/scripts/codex-0144-core-real-probes-check.js +1 -1
  259. package/dist/scripts/codex-0144-manifest-check.js +1 -1
  260. package/dist/scripts/codex-0144-policy-check.js +1 -1
  261. package/dist/scripts/codex-0144-thread-store-check.js +1 -1
  262. package/dist/scripts/codex-agent-role-rich-content-check.js +2 -2
  263. package/dist/scripts/codex-agent-role-sync-check.js +2 -2
  264. package/dist/scripts/codex-agent-type-routing-check.js +2 -2
  265. package/dist/scripts/codex-app-execution-profile-check.js +2 -2
  266. package/dist/scripts/codex-app-handoff-check.js +1 -1
  267. package/dist/scripts/codex-app-handoff-launch-check.js +1 -1
  268. package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +1 -1
  269. package/dist/scripts/codex-lb-fast-ui-preservation-check.js +1 -3
  270. package/dist/scripts/codex-native-feature-broker-blackbox.js +2 -2
  271. package/dist/scripts/codex-native-feature-broker-check.js +2 -2
  272. package/dist/scripts/{sks-3-1-6-directive-check-lib.js → codex-native-gate-lib.js} +5 -5
  273. package/dist/scripts/codex-native-harness-compat-check.js +2 -2
  274. package/dist/scripts/codex-native-hook-lifecycle-proof-check.js +2 -2
  275. package/dist/scripts/codex-plugin-app-template-policy-check.js +1 -1
  276. package/dist/scripts/codex-sdk-backend-router-check.js +1 -1
  277. package/dist/scripts/codex-sdk-capability-check.js +1 -1
  278. package/dist/scripts/context7-evidence-dedupe-check.js +1 -1
  279. package/dist/scripts/core-skill-card-schema-check.js +1 -1
  280. package/dist/scripts/core-skill-deployment-snapshot-check.js +1 -1
  281. package/dist/scripts/core-skill-heldout-validation-check.js +1 -1
  282. package/dist/scripts/core-skill-no-inference-optimizer-check.js +1 -1
  283. package/dist/scripts/core-skill-patch-check.js +1 -1
  284. package/dist/scripts/core-skill-route-runtime-integration-check.js +1 -1
  285. package/dist/scripts/current-command-surface-check.js +1 -1
  286. package/dist/scripts/current-surface-update-e2e-check.js +4 -1
  287. package/dist/scripts/current-upgrade-matrix-check.js +1 -1
  288. package/dist/scripts/dfix-fixture-check.js +1 -1
  289. package/dist/scripts/dfix-patch-handoff-check.js +1 -1
  290. package/dist/scripts/dfix-verification-check.js +1 -1
  291. package/dist/scripts/dfix-verification-recommendation-check.js +1 -1
  292. package/dist/scripts/docs-truthfulness-check.js +16 -3
  293. package/dist/scripts/doctor-codex-app-harness-check.js +2 -2
  294. package/dist/scripts/evidence-flagship-coverage-check.js +1 -1
  295. package/dist/scripts/{sks-1-18-gate-lib.js → gate-lib.js} +1 -1
  296. package/dist/scripts/gate-policy-audit-check.js +4 -1
  297. package/dist/scripts/git-worktree-checkpoint-check.js +1 -1
  298. package/dist/scripts/git-worktree-cross-rebase-check.js +1 -1
  299. package/dist/scripts/git-worktree-diff-envelope-check.js +1 -1
  300. package/dist/scripts/git-worktree-dirty-lock-check.js +1 -1
  301. package/dist/scripts/git-worktree-dirty-main-detection-check.js +1 -1
  302. package/dist/scripts/git-worktree-integration-primary-check.js +1 -1
  303. package/dist/scripts/git-worktree-manifest-append-check.js +1 -1
  304. package/dist/scripts/git-worktree-untracked-diff-check.js +1 -1
  305. package/dist/scripts/harness-benchmark-check.js +1 -1
  306. package/dist/scripts/helper-dedup-check.js +62 -0
  307. package/dist/scripts/hook-latency-budget-check.js +1 -1
  308. package/dist/scripts/image-artifact-path-contract-check.js +1 -1
  309. package/dist/scripts/imagegen-real-smoke-check.js +2 -5
  310. package/dist/scripts/installed-package-smoke-check.js +1 -1
  311. package/dist/scripts/legacy-gate-inventory-check.js +1 -1
  312. package/dist/scripts/legacy-gate-purge-check.js +1 -1
  313. package/dist/scripts/legacy-strong-inventory-check.js +1 -1
  314. package/dist/scripts/lib/codex-sdk-gate-lib.js +1 -1
  315. package/dist/scripts/mad-sks-launch-sql-plane-boundary-check.js +1 -1
  316. package/dist/scripts/mad-sks-sql-plane-capability-check.js +1 -1
  317. package/dist/scripts/mad-sks-sql-plane-lifecycle-hook-decision-check.js +1 -1
  318. package/dist/scripts/mad-sks-sql-plane-result-lifecycle-check.js +1 -1
  319. package/dist/scripts/managed-config-merge-check.js +1 -1
  320. package/dist/scripts/mcp-plugin-inventory-check.js +1 -1
  321. package/dist/scripts/model-call-concurrency-check.js +1 -1
  322. package/dist/scripts/mutation-callsite-coverage-check.js +1 -1
  323. package/dist/scripts/naruto-ssot-gate-aliases-check.js +1 -1
  324. package/dist/scripts/naruto-ssot-pipeline-default-check.js +1 -1
  325. package/dist/scripts/naruto-ssot-route-normalization-check.js +1 -1
  326. package/dist/scripts/naruto-ssot-routing-check.js +1 -1
  327. package/dist/scripts/naruto-worktree-coding-blackbox.js +1 -1
  328. package/dist/scripts/native-capability-repair-matrix-check.js +1 -1
  329. package/dist/scripts/native-image-generation-repair-check.js +1 -1
  330. package/dist/scripts/official-subagent-workflow-check.js +3 -3
  331. package/dist/scripts/package-published-contract-check.js +37 -4
  332. package/dist/scripts/packlist-performance-check.js +17 -1
  333. package/dist/scripts/pipeline-codex-native-doctor-mad-routing-real-blackbox.js +1 -3
  334. package/dist/scripts/ppt-real-export-adapter-check.js +1 -1
  335. package/dist/scripts/ppt-real-imagegen-wiring-check.js +1 -1
  336. package/dist/scripts/ppt-reexport-rereview-check.js +1 -1
  337. package/dist/scripts/prepublish-fast-check.js +1 -1
  338. package/dist/scripts/probe-memoization-check.js +2 -2
  339. package/dist/scripts/prompt-placeholder-guard-check.js +1 -1
  340. package/dist/scripts/qa-loop-app-handoff-capability-check.js +1 -1
  341. package/dist/scripts/qa-loop-app-handoff-check.js +1 -1
  342. package/dist/scripts/qa-loop-app-handoff-cli-check.js +1 -1
  343. package/dist/scripts/qa-loop-app-handoff-confirmation-check.js +1 -1
  344. package/dist/scripts/qa-loop-app-handoff-gate-lifecycle-check.js +1 -1
  345. package/dist/scripts/qa-loop-app-handoff-launch-check.js +1 -1
  346. package/dist/scripts/qa-loop-app-handoff-status-lifecycle-check.js +1 -1
  347. package/dist/scripts/qa-loop-budget-policy-check.js +1 -1
  348. package/dist/scripts/qa-loop-effort-escalation-check.js +1 -1
  349. package/dist/scripts/qa-loop-execution-profile-routing-check.js +2 -2
  350. package/dist/scripts/qa-loop-image-path-exposure-check.js +1 -1
  351. package/dist/scripts/qa-loop-image-path-prompt-injection-check.js +1 -1
  352. package/dist/scripts/{sks-1-12-real-execution-check-lib.js → real-execution-check-lib.js} +1 -1
  353. package/dist/scripts/release-affected-selector-check.js +1 -1
  354. package/dist/scripts/release-aggressive-resource-governor-check.js +1 -1
  355. package/dist/scripts/release-cache-glob-hashing-check.js +1 -1
  356. package/dist/scripts/release-cache-input-classifier-check.js +1 -1
  357. package/dist/scripts/release-cache-neutralization-report-check.js +1 -1
  358. package/dist/scripts/release-cache-version-neutral-fixture-check.js +1 -1
  359. package/dist/scripts/release-dynamic-presets-check.js +2 -2
  360. package/dist/scripts/release-full-parallelism-blackbox.js +1 -1
  361. package/dist/scripts/release-gate-batch-runner-check.js +1 -1
  362. package/dist/scripts/release-gate-budget-check.js +1 -1
  363. package/dist/scripts/release-gate-dag-runner-check.js +1 -1
  364. package/dist/scripts/release-latency-slo-check.js +1 -1
  365. package/dist/scripts/release-metadata-check.js +256 -2
  366. package/dist/scripts/release-parallel-speed-budget-check.js +1 -1
  367. package/dist/scripts/release-proof-truth-check.js +1 -1
  368. package/dist/scripts/release-provenance-check.js +4 -2
  369. package/dist/scripts/release-runtime-truth-matrix-check.js +1 -1
  370. package/dist/scripts/research-blueprint-densifier-check.js +1 -1
  371. package/dist/scripts/research-claim-builder-check.js +1 -1
  372. package/dist/scripts/research-complete-package-fixture-check.js +1 -1
  373. package/dist/scripts/research-execution-profile-routing-check.js +2 -2
  374. package/dist/scripts/research-final-reviewer-blackbox.js +1 -1
  375. package/dist/scripts/{sks-3-1-4-directive-check-lib.js → runtime-domain-gate-lib.js} +2 -2
  376. package/dist/scripts/runtime-proof-summary-check.js +1 -1
  377. package/dist/scripts/runtime-script-pack-closure-check.js +7 -1
  378. package/dist/scripts/scheduler-batch-dispatch-check.js +1 -1
  379. package/dist/scripts/scheduler-parallel-proof-consistency-check.js +1 -1
  380. package/dist/scripts/scheduler-utilization-integral-check.js +1 -1
  381. package/dist/scripts/search-visibility-gate-lib.js +1 -1
  382. package/dist/scripts/secret-preservation-check.js +1 -1
  383. package/dist/scripts/seo-geo-geo-disambiguation-check.js +1 -1
  384. package/dist/scripts/seo-geo-skill-rich-content-check.js +1 -1
  385. package/dist/scripts/side-effect-runtime-report-check.js +1 -1
  386. package/dist/scripts/{sks-3-1-8-check-lib.js → skill-fixture-check-lib.js} +1 -1
  387. package/dist/scripts/skill-name-canonicalizer-check.js +1 -1
  388. package/dist/scripts/skills-manifest-continuity-check.js +1 -1
  389. package/dist/scripts/sks-uninstall-regression-check.js +1 -1
  390. package/dist/scripts/sksd-daemon-check.js +1 -1
  391. package/dist/scripts/super-search-provider-interface-check.js +1 -1
  392. package/dist/scripts/triwiki-cache-key-check.js +1 -1
  393. package/dist/scripts/triwiki-proof-bank-blackbox.js +2 -2
  394. package/dist/scripts/triwiki-proof-bank-check.js +1 -1
  395. package/dist/scripts/triwiki-proof-card-check.js +1 -1
  396. package/dist/scripts/type-surface-codex-app-check.js +2 -2
  397. package/dist/scripts/{sks-3-1-5-directive-check-lib.js → typed-routing-gate-lib.js} +2 -2
  398. package/dist/scripts/ultra-router-auto-router-check.js +1 -1
  399. package/dist/scripts/ux-review-extract-wires-real-extractor-check.js +1 -1
  400. package/dist/scripts/ux-review-patch-diff-recheck-check.js +1 -1
  401. package/dist/scripts/ux-review-run-wires-imagegen-check.js +9 -2
  402. package/package.json +5 -7
  403. package/release-gates.v2.json +66 -11
  404. package/runtime-required-scripts.json +138 -14
  405. package/config/bench-baseline.json +0 -7
  406. package/dist/core/codex-app/sks-menubar.js +0 -1
  407. package/dist/core/release/release-closure-contract.js +0 -30
  408. package/dist/core/release/release-closure-helpers.js +0 -293
  409. package/dist/core/release/release-closure-validation.js +0 -284
  410. package/dist/core/release/release-closure.js +0 -163
  411. package/dist/scripts/build-dist.js +0 -124
  412. package/dist/scripts/build-once-runner-check.js +0 -6
  413. package/dist/scripts/canonical-test-runner.js +0 -234
  414. package/dist/scripts/changelog-check.js +0 -45
  415. package/dist/scripts/check-architecture.js +0 -295
  416. package/dist/scripts/check-cli-entrypoint.js +0 -41
  417. package/dist/scripts/check-command-module-budget.js +0 -77
  418. package/dist/scripts/check-feature-quality.js +0 -51
  419. package/dist/scripts/check-legacy-free.js +0 -64
  420. package/dist/scripts/check-pipeline-budget.js +0 -49
  421. package/dist/scripts/check-pipeline-runtime.js +0 -16
  422. package/dist/scripts/check-publish-tag.js +0 -56
  423. package/dist/scripts/check-route-modularity.js +0 -72
  424. package/dist/scripts/codex-0140-capability-check.js +0 -14
  425. package/dist/scripts/codex-0140-feature-probes-check.js +0 -23
  426. package/dist/scripts/codex-permission-profiles-check.js +0 -34
  427. package/dist/scripts/codex-project-config-policy-splitter-check.js +0 -49
  428. package/dist/scripts/competitor-scorecard-check.js +0 -24
  429. package/dist/scripts/core-skill-no-drift-check.js +0 -23
  430. package/dist/scripts/db-route-materialization-check.js +0 -32
  431. package/dist/scripts/doctor-context7-mcp-repair-blackbox.js +0 -15
  432. package/dist/scripts/doctor-fastpath-check.js +0 -25
  433. package/dist/scripts/doctor-fix-production-blackbox.js +0 -35
  434. package/dist/scripts/doctor-idempotence-check.js +0 -6
  435. package/dist/scripts/doctor-ops-semantics-check.js +0 -83
  436. package/dist/scripts/doctor-startup-config-repair-blackbox.js +0 -18
  437. package/dist/scripts/doctor-supabase-mcp-repair-blackbox.js +0 -13
  438. package/dist/scripts/ensure-bin-executable.js +0 -16
  439. package/dist/scripts/fsx-hotpath-check.js +0 -9
  440. package/dist/scripts/high-risk-contracts-check.js +0 -183
  441. package/dist/scripts/hook-latency-quantum-check.js +0 -120
  442. package/dist/scripts/import-graph-budget-check.js +0 -9
  443. package/dist/scripts/mcp-tool-naming-parity-check.js +0 -14
  444. package/dist/scripts/naruto-codex-e2e-check.js +0 -105
  445. package/dist/scripts/naruto-write-e2e-check.js +0 -31
  446. package/dist/scripts/native-capability-postcheck-check.js +0 -16
  447. package/dist/scripts/ops-diagnostics-bundle-check.js +0 -11
  448. package/dist/scripts/parallel-production-smoke-check.js +0 -20
  449. package/dist/scripts/perf-budget-check.js +0 -12
  450. package/dist/scripts/project-skill-dedupe-blackbox.js +0 -62
  451. package/dist/scripts/release-dag-full-coverage-check.js +0 -98
  452. package/dist/scripts/release-dist-freshness-check.js +0 -6
  453. package/dist/scripts/release-file-ownership-check.js +0 -35
  454. package/dist/scripts/release-gate-script-parity-check.js +0 -148
  455. package/dist/scripts/release-macos-menubar-proof.js +0 -167
  456. package/dist/scripts/release-main-push-guard.js +0 -37
  457. package/dist/scripts/release-main-push-receipt.js +0 -43
  458. package/dist/scripts/release-metadata-1-19-check.js +0 -257
  459. package/dist/scripts/release-version-truth-check.js +0 -138
  460. package/dist/scripts/retention-apply-smoke-check.js +0 -19
  461. package/dist/scripts/retention-budget-check.js +0 -6
  462. package/dist/scripts/retention-dry-run-check.js +0 -8
  463. package/dist/scripts/rollback-recovery-smoke-check.js +0 -70
  464. package/dist/scripts/route-intent-regression-check.js +0 -42
  465. package/dist/scripts/runtime-current-terminal-check.js +0 -108
  466. package/dist/scripts/runtime-dist-parity-check.js +0 -76
  467. package/dist/scripts/runtime-no-src-mjs-check.js +0 -30
  468. package/dist/scripts/runtime-ts-rust-boundary-check.js +0 -58
  469. package/dist/scripts/runtime-ts-source-of-truth-check.js +0 -53
  470. package/dist/scripts/secret-preservation-guard-check.js +0 -36
  471. package/dist/scripts/seo-marketing-truthfulness-check.js +0 -98
  472. package/dist/scripts/seo-metadata-sync-check.js +0 -60
  473. package/dist/scripts/sizecheck.js +0 -148
  474. package/dist/scripts/sks-menubar-install-check.js +0 -333
  475. package/dist/scripts/supabase-secret-preservation-blackbox.js +0 -28
  476. package/dist/scripts/super-search-live-smoke-check.js +0 -115
  477. package/dist/scripts/super-search-local-http-smoke-check.js +0 -16
  478. package/dist/scripts/super-search-offline-contract-check.js +0 -43
  479. package/dist/scripts/update-fastpath-check.js +0 -28
  480. package/dist/scripts/update-preserves-supabase-keys-blackbox.js +0 -26
  481. package/dist/scripts/upgrade-migration-matrix-check.js +0 -351
  482. package/dist/scripts/write-build-manifest.js +0 -70
  483. package/dist/scripts/zellij-capability-check.js +0 -13
  484. package/dist/scripts/zellij-developer-controls-check.js +0 -16
  485. package/dist/scripts/zellij-doctor-readiness-check.js +0 -49
  486. package/dist/scripts/zellij-dynamic-pane-lifecycle-check.js +0 -19
  487. package/dist/scripts/zellij-fake-adapter-check.js +0 -31
  488. package/dist/scripts/zellij-first-slot-down-stack-check.js +0 -20
  489. package/dist/scripts/zellij-first-slot-down-stack-real-check.js +0 -348
  490. package/dist/scripts/zellij-homebrew-policy-check.js +0 -3
  491. package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -21
  492. package/dist/scripts/zellij-lane-renderer-check.js +0 -78
  493. package/dist/scripts/zellij-launch-command-truth-check.js +0 -62
  494. package/dist/scripts/zellij-layout-valid-check.js +0 -120
  495. package/dist/scripts/zellij-pane-creation-lock-metrics-check.js +0 -10
  496. package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -78
  497. package/dist/scripts/zellij-pane-lock-does-not-block-worker-check.js +0 -12
  498. package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -134
  499. package/dist/scripts/zellij-qa-app-handoff-status-check.js +0 -7
  500. package/dist/scripts/zellij-right-column-geometry-proof.js +0 -158
  501. package/dist/scripts/zellij-right-column-headless-overflow-check.js +0 -20
  502. package/dist/scripts/zellij-right-column-manager-check.js +0 -24
  503. package/dist/scripts/zellij-self-heal-check.js +0 -3
  504. package/dist/scripts/zellij-self-heal-dry-run-check.js +0 -3
  505. package/dist/scripts/zellij-self-heal-status-contract-check.js +0 -3
  506. package/dist/scripts/zellij-self-heal-typed-blackbox.js +0 -3
  507. package/dist/scripts/zellij-slot-column-anchor-check.js +0 -65
  508. package/dist/scripts/zellij-slot-column-anchor-telemetry-check.js +0 -8
  509. package/dist/scripts/zellij-slot-only-ui-check.js +0 -29
  510. package/dist/scripts/zellij-slot-pane-renderer-check.js +0 -149
  511. package/dist/scripts/zellij-slot-pane-stale-detection-check.js +0 -65
  512. package/dist/scripts/zellij-slot-pane-telemetry-renderer-check.js +0 -11
  513. package/dist/scripts/zellij-slot-renderer-proof-semantics-check.js +0 -58
  514. package/dist/scripts/zellij-slot-telemetry-check.js +0 -38
  515. package/dist/scripts/zellij-slot-telemetry-incremental-check.js +0 -46
  516. package/dist/scripts/zellij-slot-telemetry-live-flush-check.js +0 -55
  517. package/dist/scripts/zellij-slot-telemetry-performance-check.js +0 -32
  518. package/dist/scripts/zellij-slot-telemetry-real-blackbox.js +0 -19
  519. package/dist/scripts/zellij-slot-telemetry-renderer-check.js +0 -11
  520. package/dist/scripts/zellij-slot-telemetry-runtime-check.js +0 -23
  521. package/dist/scripts/zellij-spawn-on-demand-layout-check.js +0 -45
  522. package/dist/scripts/zellij-stacked-capability-routing-check.js +0 -9
  523. package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -78
  524. package/dist/scripts/zellij-stacked-version-matrix-check.js +0 -29
  525. package/dist/scripts/zellij-stacked-version-parser-check.js +0 -19
  526. package/dist/scripts/zellij-ui-design-check.js +0 -92
  527. package/dist/scripts/zellij-update-missing-self-heal-check.js +0 -3
  528. package/dist/scripts/zellij-update-prompt-matrix-check.js +0 -16
  529. package/dist/scripts/zellij-update-prompt-mode-check.js +0 -18
  530. package/dist/scripts/zellij-update-prompt-safety-check.js +0 -8
  531. package/dist/scripts/zellij-worker-pane-manager-check.js +0 -108
  532. package/dist/scripts/zellij-worker-pane-manager-single-owner-check.js +0 -47
  533. package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -199
  534. /package/dist/scripts/{sks-1-11-gate-lib.js → sks-cli-gate-lib.js} +0 -0
@@ -1,6 +1,6 @@
1
- import { COMMANDS } from '../../cli/command-registry.js';
1
+ import { COMMAND_MANIFEST_BY_NAME, COMMAND_MANIFEST_LITE, commandInputSchema, commandManifestNames } from '../../cli/command-manifest-lite.js';
2
2
  import { nowIso, PACKAGE_VERSION, sha256 } from '../fsx.js';
3
- import { NARUTO_ACTIONS, commandContract, validateCommandContractRegistry } from '../safety/command-contract/index.js';
3
+ import { NARUTO_ACTIONS } from '../safety/command-contract/types.js';
4
4
  export const HOST_CAPABILITY_DESCRIPTORS = [
5
5
  {
6
6
  id: 'host.workspace.files.v1',
@@ -121,29 +121,28 @@ function exampleInvocation(name, jsonSupported) {
121
121
  return jsonSupported ? `sks ${name} --json` : `sks ${name}`;
122
122
  }
123
123
  function buildEntry(name, command) {
124
- const contract = commandContract(name);
125
- if (!contract)
126
- throw new Error(`Missing command contract for ${name}`);
124
+ const remoteAllowed = command.risk === 'R3' ? false : command.remoteAllowed;
127
125
  return {
128
126
  name,
129
127
  description: command.summary,
130
- read_only: contract.read_only,
131
- requires_explicit_opt_in: contract.risk === 'R2' || contract.risk === 'R3',
132
- json_output_supported: contract.supports_json,
133
- latency_class: contract.latency,
134
- example_invocation: exampleInvocation(name, contract.supports_json),
128
+ read_only: command.risk === 'R0',
129
+ requires_explicit_opt_in: command.risk === 'R2' || command.risk === 'R3',
130
+ json_output_supported: command.supportsJson,
131
+ latency_class: command.latency,
132
+ example_invocation: exampleInvocation(name, command.supportsJson),
135
133
  maturity: command.maturity,
136
- contract_schema: contract.schema,
137
- risk: contract.risk,
138
- remote_allowed: contract.remote_allowed,
139
- telegram_allowed: contract.telegram_allowed,
140
- input_schema: contract.input_schema,
141
- required_capabilities: [...contract.required_capabilities]
134
+ contract_schema: 'sks.command-contract.v2',
135
+ risk: command.risk,
136
+ remote_allowed: remoteAllowed,
137
+ telegram_allowed: remoteAllowed && command.telegramAllowed,
138
+ input_schema: commandInputSchema(command.inputProfile),
139
+ required_capabilities: [...command.requiredCapabilities]
142
140
  };
143
141
  }
144
142
  export function buildAgentManifest() {
145
- const names = Object.keys(COMMANDS).sort();
146
- const tools = names.map((name) => buildEntry(name, COMMANDS[name]));
143
+ const tools = [...COMMAND_MANIFEST_LITE]
144
+ .sort((left, right) => compareCodePoint(left.name, right.name))
145
+ .map((command) => buildEntry(command.name, command));
147
146
  return {
148
147
  schema: 'sks.agent-manifest.v1',
149
148
  generated_at: nowIso(),
@@ -154,16 +153,15 @@ export function buildAgentManifest() {
154
153
  }
155
154
  export function validateAgentManifest(manifest) {
156
155
  const candidate = manifest;
157
- const expectedNames = Object.keys(COMMANDS).sort();
156
+ const expectedNames = commandManifestNames();
158
157
  const tools = Array.isArray(candidate?.tools) ? candidate.tools : [];
159
158
  const observedNames = tools.map((tool) => String(tool?.name || '')).filter(Boolean);
160
159
  const observedSet = new Set(observedNames);
161
160
  const duplicateNames = [...new Set(observedNames.filter((name, index) => observedNames.indexOf(name) !== index))].sort();
162
161
  const missingNames = expectedNames.filter((name) => !observedSet.has(name));
163
- const unexpectedNames = [...observedSet].filter((name) => !(name in COMMANDS)).sort();
162
+ const unexpectedNames = [...observedSet].filter((name) => !Object.hasOwn(COMMAND_MANIFEST_BY_NAME, name)).sort();
164
163
  const sortedNames = [...observedNames].sort();
165
164
  const issues = [];
166
- const contractValidation = validateCommandContractRegistry();
167
165
  if (candidate?.schema !== 'sks.agent-manifest.v1')
168
166
  issues.push('schema');
169
167
  if (!candidate?.compatibility || typeof candidate.compatibility !== 'object' || Array.isArray(candidate.compatibility)) {
@@ -247,8 +245,6 @@ export function validateAgentManifest(manifest) {
247
245
  issues.push(`host_capabilities:missing:${expected.id}`);
248
246
  }
249
247
  }
250
- if (!contractValidation.ok)
251
- issues.push(...contractValidation.issues.map((entry) => `command_contract:${entry}`));
252
248
  if (!Array.isArray(candidate?.tools))
253
249
  issues.push('tools');
254
250
  if (duplicateNames.length)
@@ -285,15 +281,15 @@ export function validateAgentManifest(manifest) {
285
281
  issues.push(`invalid_input_schema:${name || '<missing>'}`);
286
282
  }
287
283
  const naruto = tools.find((tool) => tool?.name === 'naruto');
288
- const expectedNaruto = commandContract('naruto');
284
+ const expectedNaruto = buildEntry('naruto', COMMAND_MANIFEST_BY_NAME.naruto);
289
285
  const narutoActions = naruto?.input_schema?.properties?.action?.enum;
290
286
  if (JSON.stringify(narutoActions) !== JSON.stringify(NARUTO_ACTIONS))
291
287
  issues.push('naruto_action_contract_mismatch');
292
288
  if (naruto?.risk !== expectedNaruto?.risk || naruto?.risk !== 'R2')
293
289
  issues.push('contract_risk_mismatch:naruto');
294
- if (naruto?.latency_class !== expectedNaruto?.latency || naruto?.latency_class !== 'long')
290
+ if (naruto?.latency_class !== expectedNaruto?.latency_class || naruto?.latency_class !== 'long')
295
291
  issues.push('contract_latency_mismatch:naruto');
296
- if (naruto?.json_output_supported !== expectedNaruto?.supports_json || naruto?.json_output_supported !== true)
292
+ if (naruto?.json_output_supported !== expectedNaruto?.json_output_supported || naruto?.json_output_supported !== true)
297
293
  issues.push('contract_json_mismatch:naruto');
298
294
  if (naruto?.remote_allowed !== expectedNaruto?.remote_allowed || naruto?.remote_allowed !== false)
299
295
  issues.push('contract_remote_mismatch:naruto');
@@ -2,6 +2,7 @@ import { sha256 } from '../fsx.js';
2
2
  import { testMcpConnection } from '../mcp-config/health-check.js';
3
3
  import { listMcpInventory } from '../mcp-config/inventory.js';
4
4
  import { HOST_CAPABILITY_DESCRIPTORS, hostCapabilityDigest } from './agent-manifest.js';
5
+ import { uniqueStringsSorted as uniqueStrings } from '../text/strings.js';
5
6
  export const HOST_CAPABILITY_RUNTIME_SCHEMA = 'sks.host-capability-runtime.v1';
6
7
  export const HOST_CAPABILITY_MCP_SERVER = 'acas-tools';
7
8
  const MAX_OBSERVED_TOOL_NAMES = 256;
@@ -22,11 +23,13 @@ export function requestHostCapabilities(goal) {
22
23
  ]);
23
24
  const spreadsheetCreate = blankWorkbook || matches(text, [
24
25
  /\b(?:create|generate|produce|deliver|make|build|prepare|convert|export)\b.{0,48}\b(?:xlsx|excel|spreadsheet|workbook)\b/i, /\b(?:xlsx|excel|spreadsheet|workbook)\b.{0,48}\b(?:create|generate|produce|deliver|make|build|prepare|convert|export)\b/i,
25
- /(?:엑셀|스프레드시트|xlsx).{0,32}(?:생성|작성|만들|납품)/i, /(?:생성|작성|만들|납품).{0,32}(?:엑셀|스프레드시트|xlsx)/i
26
+ /(?:엑셀|스프레드시트|xlsx).{0,32}(?:생성|작성|만들|납품)/i, /(?:생성|작성|만들|납품).{0,32}(?:엑셀|스프레드시트|xlsx)/i,
27
+ /(?:엑셀로 정리|엑셀 파일로 저장|엑셀로 내보내|스프레드시트 보고서|xlsx로 변환|표를 엑셀로)/i
26
28
  ]);
27
29
  const spreadsheetMutation = matches(text, [
28
30
  /\b(?:edit|update|modify|populate|fill|append|import)\b.{0,56}\b(?:xlsx|excel|spreadsheet|workbook)\b/i, /\b(?:xlsx|excel|spreadsheet|workbook)\b.{0,56}\b(?:edit|update|modify|populate|fill|append|import)\b/i,
29
- /(?:엑셀|스프레드시트|xlsx).{0,36}(?:수정|편집|업데이트|입력|채우|반영|추가)/i, /(?:수정|편집|업데이트|입력|채우|반영|추가).{0,36}(?:엑셀|스프레드시트|xlsx)/i
31
+ /(?:엑셀|스프레드시트|xlsx).{0,36}(?:수정|편집|업데이트|입력|채우|반영|추가)/i, /(?:수정|편집|업데이트|입력|채우|반영|추가).{0,36}(?:엑셀|스프레드시트|xlsx)/i,
32
+ /기존 엑셀 수식 오류를 고쳐/i
30
33
  ]);
31
34
  const spreadsheetInspection = matches(text, [
32
35
  /\binspect\b.{0,56}\b(?:xlsx|excel|spreadsheet|workbook)\b/i, /\b(?:xlsx|excel|spreadsheet|workbook)\b.{0,56}\binspect\b/i,
@@ -38,16 +41,36 @@ export function requestHostCapabilities(goal) {
38
41
  const queryPatterns = [
39
42
  /\b(?:query|retrieve|fetch|load|analy[sz]e|show|list)\b.{0,56}\b(?:database|datasource|data|rows?|records?|results?)\b/i, /\b(?:database|datasource|data|rows?|records?|results?)\b.{0,56}\b(?:query|retrieve|fetch|load|analy[sz]e|show|list)\b/i,
40
43
  /\b(?:get|read)\b.{0,56}\b(?:data|rows?|records?|results?)\b.{0,48}\b(?:from|in)\s+(?:the\s+)?(?:database|datasource|db)\b/i, /\bpull\b.{0,64}\b(?:from|out\s+of)\s+(?:the\s+)?(?:database|datasource|db)\b/i,
41
- /\b(?:from|in)\s+(?:the\s+)?(?:database|datasource|db)\b.{0,56}\b(?:get|read|pull)\b.{0,48}\b(?:data|rows?|records?|results?)\b/i, /(?:db|데이터베이스|데이터소스|데이터).{0,36}(?:조회|가져오|검색|분석|질의)/i, /(?:조회|가져오|검색|분석|질의).{0,36}(?:db|데이터베이스|데이터소스|데이터)/i
44
+ /\b(?:from|in)\s+(?:the\s+)?(?:database|datasource|db)\b.{0,56}\b(?:get|read|pull)\b.{0,48}\b(?:data|rows?|records?|results?)\b/i, /(?:db|데이터베이스|데이터소스|데이터).{0,36}(?:조회|가져오|검색|분석|질의)/i, /(?:조회|가져오|검색|분석|질의).{0,36}(?:db|데이터베이스|데이터소스|데이터)/i,
45
+ /(?:DB에서 뽑아|데이터베이스 집계)/i
46
+ ];
47
+ const genericAggregatePatterns = [/(?:월별 합계|통계 내줘|현황 조회|상위\s*(?:N|\d+)\s*건)/i];
48
+ const datasourceCuePatterns = [
49
+ /(?:\bdb\b|데이터베이스|데이터소스|\bmysql\b|\bpostgres(?:ql)?\b|\bsupabase\b|\bconnector\b)/i,
50
+ /\b[a-z][a-z0-9_-]*:[a-z0-9][a-z0-9_.-]*\b/i
51
+ ];
52
+ const fileDataContextPatterns = [
53
+ /(?:\bcsv\b|\bjson\b|\bxlsx\b|문서|파일)(?:\s*(?:안|내부))?(?:의|에서|에\s*있는)\s*(?:데이터|내용|행|레코드)?/i,
54
+ /(?:\bcsv\b|\bjson\b|\bxlsx\b)\s*(?:data|데이터)/i
55
+ ];
56
+ const queryExecutionExclusions = [
57
+ ...executionExclusions,
58
+ /(?:sql|쿼리|질의).{0,24}(?:실행(?:은|을)?\s*(?:금지|하지\s*마|없이)|만\s*(?:작성|생성))/i,
59
+ /(?:실행(?:은|을)?\s*(?:금지|하지\s*마|없이)|만\s*(?:작성|생성)).{0,24}(?:sql|쿼리|질의)/i
42
60
  ];
43
61
  const sqlGeneration = matches(text, sqlPatterns);
44
62
  const clauses = text.split(/\n+/).map((clause) => clause.trim()).filter(Boolean);
45
63
  const datasourceQuery = clauses.some((clause, index) => {
46
64
  const nearby = [clauses[index - 1], clause, clauses[index + 1]].filter((value) => Boolean(value));
47
- return !(matches(clause, sqlPatterns) && nearby.some((value) => matches(value, executionExclusions))) && matches(clause, queryPatterns);
65
+ if (matches(clause, fileDataContextPatterns) || matches(clause, queryExecutionExclusions))
66
+ return false;
67
+ if (matches(clause, sqlPatterns) && nearby.some((value) => matches(value, queryExecutionExclusions)))
68
+ return false;
69
+ return matches(clause, queryPatterns)
70
+ || (matches(clause, genericAggregatePatterns) && matches(clause, datasourceCuePatterns));
48
71
  });
49
- const documentRender = matches(text, [/\b(?:render|generate|create|export|deliver)\b.{0,48}\b(?:pdf|png|document screenshot)\b/i, /\b(?:pdf|png|document screenshot)\b.{0,48}\b(?:render|generate|create|export|deliver)\b/i, /(?:pdf|png|문서).{0,32}(?:렌더|생성|작성|내보내|납품)/i, /(?:렌더|생성|작성|내보내|납품).{0,32}(?:pdf|png|문서)/i]);
50
- const webCapture = matches(text, [/\b(?:capture|take|create)\b.{0,40}\b(?:url|web|page)\b.{0,24}\bscreenshot\b/i, /\b(?:url|web|page)\b.{0,40}\bscreenshot\b/i, /(?:url|웹|페이지).{0,32}(?:스크린샷|캡처)/i]);
72
+ const documentRender = matches(text, [/\b(?:render|generate|create|export|deliver)\b.{0,48}\b(?:pdf|png|document screenshot)\b/i, /\b(?:pdf|png|document screenshot)\b.{0,48}\b(?:render|generate|create|export|deliver)\b/i, /(?:pdf|png|문서).{0,32}(?:렌더|생성|작성|내보내|납품)/i, /(?:렌더|생성|작성|내보내|납품).{0,32}(?:pdf|png|문서)/i, /(?:PDF 파일로 저장|문서를 PDF로|화면을 PNG로)/i, /(?:html|문서|보고서).{0,32}(?:pdf|png|렌더|이미지로)/i]);
73
+ const webCapture = matches(text, [/\b(?:capture|take|create)\b.{0,40}\b(?:url|web|site|page)\b.{0,24}\bscreenshot\b/i, /\b(?:url|web|site|page)\b.{0,40}\bscreenshot\b/i, /(?:url|웹|사이트|페이지).{0,32}(?:스크린샷|캡처|이미지로)/i]);
51
74
  const workspace = (action, korean) => matches(text, [new RegExp(`\\bworkspace\\b.{0,48}\\b(?:${action})\\b`, 'i'), new RegExp(`\\b(?:${action})\\b.{0,48}\\bworkspace\\b`, 'i'), new RegExp(`워크스페이스.{0,36}(?:${korean})`, 'i'), new RegExp(`(?:${korean}).{0,36}워크스페이스`, 'i')]);
52
75
  const workspaceRead = workspace('read|open|inspect', '읽|열|검사|점검');
53
76
  const workspaceFind = workspace('find|search', '찾|검색');
@@ -72,7 +95,7 @@ export function requestHostCapabilities(goal) {
72
95
  workflows.add('spreadsheet_edit');
73
96
  }
74
97
  if (documentRender) {
75
- const tools = [...(/\bpdf\b/i.test(text) ? ['html_to_pdf'] : []), ...(/\b(?:png|document screenshot)\b/i.test(text) || /(?:png|문서 스크린샷)/i.test(text) ? ['html_to_screenshot'] : [])];
98
+ const tools = [...(/\bpdf\b/i.test(text) ? ['html_to_pdf'] : []), ...(/\b(?:png|document screenshot)\b/i.test(text) || /(?:png|문서 스크린샷|화면을 PNG로|페이지 이미지로)/i.test(text) ? ['html_to_screenshot'] : [])];
76
99
  request('host.workspace.files.v1', ['write_file']);
77
100
  request('host.document.render.v1', tools.length ? tools : ['html_to_pdf', 'html_to_screenshot']);
78
101
  workflows.add('workspace_files');
@@ -180,9 +203,87 @@ function codeMaintenance(text) {
180
203
  function directExecution(text) {
181
204
  return matches(text, [/\b(?:create|generate|make|build|prepare|render)\s+(?:an?\s+|the\s+)?(?:xlsx|excel workbook|excel report|spreadsheet(?: file| report)?|workbook(?: file)?|pdf(?: file| document| report)?|png(?: file| image)?)\b(?!\s+(?:parser|reader|writer|module|tests?|specs?|fixtures?|code|implementation)\b)/i, /\b(?:populate|fill)\b.{0,24}\b(?:new|blank|empty)\b.{0,24}\b(?:xlsx|excel(?: workbook)?|spreadsheet|workbook)\b/i, /\b(?:deliver|export|save|produce)\b.{0,32}\b(?:xlsx|excel|spreadsheet|workbook|pdf|png|artifact|deliverable)\b/i, /\b(?:edit|update|modify|populate|fill|append|import|inspect)\s+(?:the\s+|an?\s+)?(?:existing\s+)?(?:xlsx|excel(?: workbook)?|spreadsheet|workbook)\b(?!\s+(?:parser|reader|writer|module|tests?|specs?|fixtures?|code|implementation)\b)/i, /\b(?:edit|update|modify|populate|fill|append|import)\b.{0,48}\b[A-Za-z0-9._/-]+\.xlsx\b/i, /\b(?:inspect|open)\b.{0,64}\b[A-Za-z0-9._/-]+\.xlsx\b.{0,48}\b(?:and\s+)?(?:edit|update|modify|populate|fill|append|import)\s+(?:it|the\s+(?:file|workbook|spreadsheet))\b/i, /\b(?:run|execute)\b.{0,32}\b(?:read[- ]only\s+)?(?:query|select|cte)\b(?!\s+(?:(?:unit|integration|regression)\s+)?tests?\b)/i, /\b(?:query|retrieve|fetch|load)\b.{0,40}\b(?:database|datasource|rows?|records?|results?|(?:customer|sales|database)?\s*data)\b/i, /\b(?:get|read)\b.{0,56}\b(?:data|rows?|records?|results?)\b.{0,48}\b(?:from|in)\s+(?:the\s+)?(?:database|datasource|db)\b/i, /\bpull\b.{0,64}\b(?:from|out\s+of)\s+(?:the\s+)?(?:database|datasource|db)\b/i, /\b(?:from|in)\s+(?:the\s+)?(?:database|datasource|db)\b.{0,56}\b(?:get|read|pull)\b.{0,48}\b(?:data|rows?|records?|results?)\b/i, /\banaly[sz]e\b.{0,40}\b(?:database\s+data|datasource\s+data|rows?|records?|query\s+results?|customer\s+data|sales\s+data)\b/i, /\b(?:test|inspect|review)\b.{0,32}\b(?:pdf|png)\b.{0,24}\band\s+(?:export|deliver|save|render)\s+(?:it|the\s+(?:file|document|image))\b/i, /(?:엑셀|스프레드시트|xlsx)(?!\s*(?:파서|리더|라이터|모듈|코드|테스트|스펙|픽스처)).{0,20}(?:업데이트|수정|편집|입력|채우|반영)/i, /(?:업데이트|수정|편집|입력|채우|반영).{0,20}(?:엑셀|스프레드시트|xlsx)/i, /(?:엑셀|스프레드시트|xlsx|pdf|png).{0,24}(?:파일|문서|보고서|산출물).{0,24}(?:생성|작성|만들|렌더|내보내|납품|저장)/i, /(?:생성|작성|만들|렌더|내보내|납품|저장).{0,24}(?:엑셀|스프레드시트|xlsx|pdf|png)(?:\s*(?:파일|문서|보고서|산출물))?/i, /(?:실행|조회|가져오).{0,24}(?:읽기\s*전용\s*)?(?:쿼리|질의|행|레코드|결과)/i]);
182
205
  }
206
+ export function renderHostCapabilityBlockedLines(blockers, fallback) {
207
+ const codes = uniqueStrings(blockers
208
+ .map((value) => String(value || '').trim().split(/\r?\n/, 1)[0] || '')
209
+ .map((value) => value.match(/^[a-z][a-z0-9.-]*(?:_[a-z0-9.-]+)+(?::[a-z0-9_.-]+)*/i)?.[0] || '')
210
+ .map((value) => value.slice(0, 180))
211
+ .filter(Boolean));
212
+ const prioritized = [...codes].sort((left, right) => blockerPriority(left) - blockerPriority(right));
213
+ const primary = prioritized[0] || 'host_capability_blocked';
214
+ const guidance = blockerGuidance(primary, fallback);
215
+ return [
216
+ '상태: 차단',
217
+ `이유: ${guidance.reason}`,
218
+ `조치: ${guidance.action}`,
219
+ `코드: ${primary}`
220
+ ];
221
+ }
222
+ function blockerPriority(code) {
223
+ if (/^(?:host_capability_project_trust_missing|host_tool_call_not_allowed)/.test(code))
224
+ return 0;
225
+ if (/^(?:host_capability_missing|host_capability_unhealthy|host_capability_project_mcp_inventory_unhealthy)|mcp.*(?:connection|inventory|health|missing|tool)/.test(code))
226
+ return 1;
227
+ if (/(?:datasource|readonly_query).*(?:mismatch|schema)|spreadsheet.*(?:sequence|inspection_not_completed|resource_mismatch|update_count_invalid)|document.*(?:source|path|required|resource_mismatch)|(?:input|argument|contract).*(?:invalid|required|mismatch)/.test(code))
228
+ return 2;
229
+ if (/host_tool_response_malformed|artifact.*missing|receipt.*missing|error_cell/.test(code))
230
+ return 3;
231
+ if (/(?:proof|receipt).*mismatch|parent_receipts_mismatch/.test(code))
232
+ return 4;
233
+ return 4;
234
+ }
235
+ function blockerGuidance(code, fallback) {
236
+ if (code.startsWith('host_tool_call_not_allowed')) {
237
+ const tool = code.split(':')[1] || '요청한 도구';
238
+ return {
239
+ reason: `현재 에이전트에 ${tool === 'spreadsheet_update' ? '엑셀 수정' : '요청한'} 도구가 허용되지 않았습니다.`,
240
+ action: `ACAS 에이전트 도구 권한에서 ${tool}를 허용한 뒤 같은 요청을 다시 실행하세요.`
241
+ };
242
+ }
243
+ if (code.startsWith('host_capability_project_trust_missing'))
244
+ return {
245
+ reason: '프로젝트 신뢰가 확인되지 않아 호스트 도구를 사용할 수 없습니다.',
246
+ action: '프로젝트를 신뢰한 뒤 --trusted-project로 같은 요청을 다시 실행하세요.'
247
+ };
248
+ if (code.startsWith('host_capability_missing'))
249
+ return {
250
+ reason: '요청한 호스트 기능이 현재 ACAS 도구 목록에 없습니다.',
251
+ action: 'ACAS 에이전트 도구 권한과 acas-tools 구성을 확인한 뒤 다시 실행하세요.'
252
+ };
253
+ if (blockerPriority(code) === 1)
254
+ return {
255
+ reason: 'acas-tools MCP 연결 또는 상태 확인에 실패했습니다.',
256
+ action: '프로젝트 MCP inventory와 acas-tools health를 복구한 뒤 다시 실행하세요.'
257
+ };
258
+ if (code.startsWith('host_tool_response_malformed:datasource_query_readonly'))
259
+ return {
260
+ reason: 'DB 조회 결과가 SKS가 검증할 수 있는 응답 형식을 따르지 않았습니다.',
261
+ action: 'ACAS Agent를 최신 호환 버전으로 업데이트한 뒤 같은 mission을 재실행하세요.'
262
+ };
263
+ if (code.startsWith('host_tool_response_malformed'))
264
+ return {
265
+ reason: '호스트 도구 결과가 SKS가 검증할 수 있는 응답 형식을 따르지 않았습니다.',
266
+ action: 'ACAS Agent를 최신 호환 버전으로 업데이트한 뒤 같은 mission을 재실행하세요.'
267
+ };
268
+ if (/(?:datasource|readonly_query).*(?:mismatch|schema)/.test(code))
269
+ return {
270
+ reason: '데이터 조회가 선행 스키마 정보와 일치하지 않습니다.',
271
+ action: '같은 datasource의 schema context를 다시 받고 matching snapshot으로 조회하세요.'
272
+ };
273
+ if (/spreadsheet.*(?:sequence|inspection_not_completed|resource_mismatch|update_count_invalid)/.test(code))
274
+ return {
275
+ reason: '엑셀 작업 순서 또는 대상 파일이 검사 결과와 일치하지 않습니다.',
276
+ action: '같은 파일을 create/update 뒤 inspect하고 허용된 mutation 상한 안에서 다시 실행하세요.'
277
+ };
278
+ if (blockerPriority(code) >= 3)
279
+ return {
280
+ reason: '최종 산출물 또는 proof receipt 검증이 완료되지 않았습니다.',
281
+ action: '산출물을 다시 생성·검사하고 최종 mutation 또는 render receipt를 제출하세요.'
282
+ };
283
+ return fallback;
284
+ }
183
285
  function matches(text, patterns) { return patterns.some((pattern) => pattern.test(text)); }
184
286
  function tomlArray(values) { return `[${values.map((value) => JSON.stringify(value)).join(', ')}]`; }
185
- function uniqueStrings(values) { return [...new Set(values.map((value) => String(value || '').trim()).filter(Boolean))].sort(); }
186
287
  function uniqueWorkflows(values) {
187
288
  const valid = new Set(['datasource_sql_generation', 'datasource_query', 'spreadsheet_create', 'spreadsheet_edit', 'document_render', 'web_capture', 'workspace_files', 'artifact_delivery']);
188
289
  return uniqueStrings(values).filter((value) => valid.has(value));
@@ -1,6 +1,8 @@
1
1
  import { sha256 } from '../fsx.js';
2
2
  import { HOST_CAPABILITY_DESCRIPTORS, hostCapabilityDigest } from './agent-manifest.js';
3
3
  import { HOST_CAPABILITY_MCP_SERVER, HOST_CAPABILITY_RUNTIME_SCHEMA, hostCapabilityRuntimeDigest } from './host-capability-policy.js';
4
+ import { isRecord } from '../json/records.js';
5
+ import { uniqueStringsSorted as uniqueStrings } from '../text/strings.js';
4
6
  export { HOST_CAPABILITY_MCP_SERVER, HOST_CAPABILITY_RUNTIME_SCHEMA, hostCapabilityCodexConfigArgs, inspectHostCapabilityRuntime, requestHostCapabilities } from './host-capability-policy.js';
5
7
  export const HOST_CAPABILITY_EVIDENCE_SCHEMA = 'sks.host-capability-evidence.v1';
6
8
  export const HOST_CAPABILITY_HOOK_RUNTIME_SCHEMA = 'sks.host-capability-hook-runtime.v1';
@@ -10,7 +12,9 @@ export const HOST_CAPABILITY_HOOK_RUNTIME_FILENAME = 'host-capability-runtime.js
10
12
  export const HOST_CAPABILITY_HOOK_PENDING_RUNTIME_FILENAME = 'host-capability-runtime-pending.json';
11
13
  export const HOST_CAPABILITY_HOOK_OBSERVATIONS_FILENAME = 'host-capability-hook-observations.json';
12
14
  export const HOST_CAPABILITY_HOOK_EVIDENCE_FILENAME = 'host-capability-evidence.json';
13
- const MAX_EVENT_LINE_BYTES = 512 * 1024;
15
+ const MAX_HOST_TOOL_STRUCTURED_RESULT_BYTES = 4 * 1024 * 1024;
16
+ const MAX_EVENT_LINE_BYTES = 5 * 1024 * 1024;
17
+ const MAX_EVENT_BUFFER_BYTES = 10 * 1024 * 1024;
14
18
  const MAX_MCP_TOOL_CALLS = 1024;
15
19
  const MAX_PRE_TOOL_OBSERVATIONS = 2048;
16
20
  const MAX_RECEIPT_JSON_STRING_BYTES = 64 * 1024;
@@ -123,7 +127,15 @@ export function sanitizeHostCapabilityPreToolUse(runtime, payload) {
123
127
  if (!tool || !toolUseId)
124
128
  return null;
125
129
  const toolInput = isRecord(payload.tool_input) ? payload.tool_input : {};
126
- const resourceKey = extractToolResourceKey({ arguments: payload.tool_input });
130
+ const documentRender = tool === 'html_to_pdf' || tool === 'html_to_screenshot';
131
+ const documentSourcePath = documentRender ? normalizeDocumentSourcePath(toolInput.source_path) : null;
132
+ const documentSourceBlocker = documentRender
133
+ && (Object.prototype.hasOwnProperty.call(toolInput, 'html') || !documentSourcePath)
134
+ ? 'host_capability_document_source_path_required'
135
+ : null;
136
+ const resourceKey = documentRender
137
+ ? documentSourcePath && workspaceResourceKey(documentSourcePath)
138
+ : extractToolResourceKey({ arguments: payload.tool_input });
127
139
  const datasource = tool === 'datasource_schema_context' || tool === 'datasource_query_readonly'
128
140
  ? boundedIdentity(toolInput.datasource)
129
141
  : null;
@@ -132,14 +144,15 @@ export function sanitizeHostCapabilityPreToolUse(runtime, payload) {
132
144
  : null;
133
145
  const allowed = runtime.ok
134
146
  && runtime.allowed_tool_names.includes(tool)
135
- && !explicitlyDeniedHostCapabilityTool(tool);
147
+ && !explicitlyDeniedHostCapabilityTool(tool)
148
+ && !documentSourceBlocker;
136
149
  const blocker = !runtime.ok
137
150
  ? 'host_capability_runtime_unavailable'
138
151
  : explicitlyDeniedHostCapabilityTool(tool)
139
152
  ? `host_tool_call_explicitly_denied:${tool}`
140
153
  : !runtime.allowed_tool_names.includes(tool)
141
154
  ? `host_tool_call_not_allowed:${tool}`
142
- : null;
155
+ : documentSourceBlocker;
143
156
  return {
144
157
  tool_use_id_sha256: `sha256:${sha256(toolUseId)}`,
145
158
  tool,
@@ -170,9 +183,9 @@ export function sanitizeHostCapabilityPostToolUse(payload) {
170
183
  ? 'failed'
171
184
  : 'passed';
172
185
  const artifacts = status === 'passed'
173
- ? extractArtifactReceipts(payload.tool_response)
186
+ ? extractArtifactReceipts(response)
174
187
  : [];
175
- const resourceKey = extractToolResourceKey({
188
+ const resourceKey = extractHostToolResourceKey(tool, {
176
189
  arguments: payload.tool_input,
177
190
  result: payload.tool_response
178
191
  });
@@ -315,6 +328,19 @@ function authorizePreToolReservation(runtime, current, observation) {
315
328
  return denyPreToolReservation(observation, 'host_capability_spreadsheet_update_inspection_not_completed');
316
329
  }
317
330
  }
331
+ if (observation.tool === 'html_to_pdf' || observation.tool === 'html_to_screenshot') {
332
+ const completedSourceWrites = [
333
+ ...completedPassedToolCalls(current, 'write_file'),
334
+ ...completedPassedToolCalls(current, 'edit_file')
335
+ ];
336
+ if (completedSourceWrites.length === 0) {
337
+ return denyPreToolReservation(observation, 'host_capability_document_source_sequence_invalid');
338
+ }
339
+ if (!observation.resource_key
340
+ || !completedSourceWrites.some((call) => call.resource_key === observation.resource_key)) {
341
+ return denyPreToolReservation(observation, 'host_capability_document_source_resource_mismatch');
342
+ }
343
+ }
318
344
  return {
319
345
  ...observation,
320
346
  decision: 'allowed',
@@ -573,20 +599,20 @@ export function createHostCapabilityEventCollector(runtime) {
573
599
  event_sha256: rawHash,
574
600
  raw_hash: rawHash,
575
601
  index: callIndex,
576
- resource_key: extractToolResourceKey(item),
602
+ resource_key: extractHostToolResourceKey(tool, item),
577
603
  semantic_receipt: semantic.receipt
578
604
  });
579
605
  if (semantic.blocker)
580
606
  blockers.push(semantic.blocker);
581
607
  if (status === 'passed') {
582
- for (const artifact of extractArtifactReceipts(item.result?.structured_content ?? item.result?.structuredContent ?? item.result)) {
608
+ for (const artifact of extractArtifactReceipts(response)) {
583
609
  observedArtifacts.push({ ...artifact, source_tool: tool, source_hash: rawHash, source_index: callIndex });
584
610
  }
585
611
  }
586
612
  };
587
613
  const push = (chunk) => {
588
614
  buffer += String(chunk || '');
589
- if (Buffer.byteLength(buffer, 'utf8') > MAX_EVENT_LINE_BYTES * 2 && !buffer.includes('\n')) {
615
+ if (Buffer.byteLength(buffer, 'utf8') > MAX_EVENT_BUFFER_BYTES && !buffer.includes('\n')) {
590
616
  blockers.push('host_tool_event_buffer_too_large');
591
617
  buffer = '';
592
618
  return;
@@ -712,36 +738,47 @@ function validateCapabilityWorkflow(runtime, descriptor, calls, allCalls, artifa
712
738
  blockers.push('host_capability_schema_call_missing');
713
739
  }
714
740
  if (descriptor.id === 'host.datasource.query.readonly.v1') {
715
- const schemaCall = allCalls.find((call) => call.tool === 'datasource_schema_context' && call.status === 'passed') || null;
741
+ const schemaCalls = allCalls.filter((call) => (call.tool === 'datasource_schema_context' && call.status === 'passed'));
716
742
  const queryCalls = passed('datasource_query_readonly');
717
- const schemaIndex = schemaCall?.index ?? -1;
718
743
  if (queryCalls.length === 0)
719
744
  blockers.push('host_capability_readonly_query_call_missing');
720
745
  if (runtime.task_workflows.includes('datasource_query')
721
746
  && (queryCalls.length < 1 || queryCalls.length > MAX_DATASOURCE_QUERY_RESERVATIONS)) {
722
747
  blockers.push('host_capability_readonly_query_count_invalid');
723
748
  }
724
- if (runtime.task_workflows.includes('datasource_query')
725
- && (schemaIndex < 0 || queryCalls.some((call) => call.index <= schemaIndex))) {
726
- blockers.push('host_capability_datasource_sequence_invalid');
727
- }
728
- const schemaReceipt = schemaCall?.semantic_receipt?.kind === 'datasource_schema'
729
- ? schemaCall.semantic_receipt
730
- : null;
731
- const queryReceipts = queryCalls
732
- .map((call) => call.semantic_receipt?.kind === 'datasource_query' ? call.semantic_receipt : null);
733
- if (queryCalls.length > 0 && queryReceipts.some((receipt) => !receipt)) {
734
- blockers.push('host_capability_readonly_query_receipt_invalid');
735
- }
736
- if (schemaCall && !schemaReceipt)
737
- blockers.push('host_capability_schema_receipt_invalid');
738
- if (schemaReceipt && queryReceipts.some((receipt) => receipt
739
- && schemaReceipt.schema_snapshot_sha256 !== receipt.schema_snapshot_sha256)) {
740
- blockers.push('host_capability_readonly_query_schema_mismatch');
741
- }
742
- if (schemaReceipt && queryReceipts.some((receipt) => receipt
743
- && schemaReceipt.datasource_sha256 !== receipt.datasource_sha256)) {
744
- blockers.push('host_capability_readonly_query_datasource_mismatch');
749
+ for (const queryCall of queryCalls) {
750
+ const precedingSchemaCalls = schemaCalls.filter((call) => call.index < queryCall.index);
751
+ const sequenceInvalid = runtime.task_workflows.includes('datasource_query')
752
+ && precedingSchemaCalls.length === 0;
753
+ if (sequenceInvalid)
754
+ blockers.push('host_capability_datasource_sequence_invalid');
755
+ const precedingSchemaReceipts = precedingSchemaCalls
756
+ .map((call) => call.semantic_receipt?.kind === 'datasource_schema' ? call.semantic_receipt : null);
757
+ const validSchemaReceipts = precedingSchemaReceipts.filter(Boolean);
758
+ const queryReceipt = queryCall.semantic_receipt?.kind === 'datasource_query'
759
+ ? queryCall.semantic_receipt
760
+ : null;
761
+ if (!queryReceipt)
762
+ blockers.push('host_capability_readonly_query_receipt_invalid');
763
+ if (precedingSchemaCalls.length > 0 && validSchemaReceipts.length === 0) {
764
+ blockers.push('host_capability_schema_receipt_invalid');
765
+ }
766
+ if (!queryReceipt || sequenceInvalid || validSchemaReceipts.length === 0)
767
+ continue;
768
+ const matchingSchemaCall = [...precedingSchemaCalls]
769
+ .sort((left, right) => right.index - left.index)
770
+ .find((call) => (call.semantic_receipt?.kind === 'datasource_schema'
771
+ && call.semantic_receipt.datasource_sha256 === queryReceipt.datasource_sha256
772
+ && call.semantic_receipt.schema_snapshot_sha256 === queryReceipt.schema_snapshot_sha256));
773
+ if (matchingSchemaCall)
774
+ continue;
775
+ const matchingDatasourceReceipts = validSchemaReceipts.filter((receipt) => (receipt.datasource_sha256 === queryReceipt.datasource_sha256));
776
+ if (matchingDatasourceReceipts.length === 0) {
777
+ blockers.push('host_capability_readonly_query_datasource_mismatch');
778
+ }
779
+ else {
780
+ blockers.push('host_capability_readonly_query_schema_mismatch');
781
+ }
745
782
  }
746
783
  }
747
784
  if (descriptor.id === 'host.spreadsheet.workbook.v1') {
@@ -835,11 +872,17 @@ function validateCapabilityWorkflow(runtime, descriptor, calls, allCalls, artifa
835
872
  blockers.push('host_capability_document_render_call_missing');
836
873
  }
837
874
  else {
838
- const sourceWrite = allCalls.find((call) => (call.status === 'passed'
875
+ const firstRender = renderCalls[0];
876
+ const precedingSourceWrites = allCalls.filter((call) => (call.status === 'passed'
839
877
  && (call.tool === 'write_file' || call.tool === 'edit_file')
840
- && call.index < renderCalls[0].index));
841
- if (!sourceWrite)
878
+ && call.index < firstRender.index));
879
+ if (precedingSourceWrites.length === 0) {
842
880
  blockers.push('host_capability_document_source_sequence_invalid');
881
+ }
882
+ else if (!firstRender.resource_key
883
+ || !precedingSourceWrites.some((call) => call.resource_key === firstRender.resource_key)) {
884
+ blockers.push('host_capability_document_source_resource_mismatch');
885
+ }
843
886
  const finalRender = renderCalls.at(-1);
844
887
  if (!artifacts.some((artifact) => (artifact.source_tool === finalRender.tool
845
888
  && artifact.source_index === finalRender.index
@@ -853,18 +896,53 @@ function validateCapabilityWorkflow(runtime, descriptor, calls, allCalls, artifa
853
896
  && passed('capture_url_screenshot').length === 0) {
854
897
  blockers.push('host_capability_web_capture_call_missing');
855
898
  }
856
- if (descriptor.id === 'host.artifact.receipt.v1' && artifacts.length === 0) {
857
- blockers.push('host_capability_artifact_receipt_missing');
899
+ if (descriptor.id === 'host.artifact.receipt.v1') {
900
+ const artifactReceiptExceptions = new Set([
901
+ 'spreadsheet_inspect',
902
+ 'read_file',
903
+ 'find_workspace_files',
904
+ 'list_workspace'
905
+ ]);
906
+ const artifactProducingTools = new Set(descriptor.tool_names.filter((tool) => !artifactReceiptExceptions.has(tool)));
907
+ const passedArtifactCalls = calls.filter((call) => (call.status === 'passed' && artifactProducingTools.has(call.tool)));
908
+ if (artifacts.length === 0 || passedArtifactCalls.some((call) => !artifacts.some((artifact) => (artifact.source_tool === call.tool && artifact.source_index === call.index)))) {
909
+ blockers.push('host_capability_artifact_receipt_missing');
910
+ }
858
911
  }
859
912
  return uniqueStrings(blockers);
860
913
  }
914
+ function normalizeDocumentSourcePath(value) {
915
+ const normalized = normalizeWorkspaceResourcePath(value);
916
+ return typeof value === 'string'
917
+ && value === normalized
918
+ && /\.html$/i.test(normalized)
919
+ ? normalized
920
+ : null;
921
+ }
922
+ function workspaceResourceKey(resourcePath) {
923
+ return `sha256:${sha256(resourcePath)}`;
924
+ }
925
+ function extractHostToolResourceKey(tool, item) {
926
+ if ((tool === 'html_to_pdf' || tool === 'html_to_screenshot') && isRecord(item)) {
927
+ const toolInput = isRecord(item.arguments)
928
+ ? item.arguments
929
+ : isRecord(item.input)
930
+ ? item.input
931
+ : {};
932
+ const sourcePath = normalizeDocumentSourcePath(toolInput.source_path);
933
+ return sourcePath ? workspaceResourceKey(sourcePath) : null;
934
+ }
935
+ return extractToolResourceKey(item);
936
+ }
861
937
  function extractToolResourceKey(item) {
862
938
  if (!isRecord(item))
863
939
  return null;
940
+ const result = item.result;
941
+ const resultRecord = isRecord(result) ? result : null;
864
942
  const queue = [
865
943
  { value: item.arguments, depth: 0 },
866
944
  { value: item.input, depth: 0 },
867
- { value: item.result?.structured_content ?? item.result?.structuredContent ?? item.result, depth: 0 }
945
+ { value: resultRecord?.structured_content ?? resultRecord?.structuredContent ?? result, depth: 0 }
868
946
  ];
869
947
  let visited = 0;
870
948
  while (queue.length > 0 && visited < 256) {
@@ -883,7 +961,7 @@ function extractToolResourceKey(item) {
883
961
  if (/^(?:path|file_path|filepath|workbook_path|workbook|source_path|target_path|output_path)$/i.test(key)) {
884
962
  const resourcePath = normalizeWorkspaceResourcePath(value);
885
963
  if (resourcePath)
886
- return `sha256:${sha256(resourcePath)}`;
964
+ return workspaceResourceKey(resourcePath);
887
965
  }
888
966
  queue.push({ value, depth: current.depth + 1 });
889
967
  }
@@ -914,7 +992,7 @@ function isSpreadsheetDeliverable(artifact) {
914
992
  }
915
993
  function artifactMatchesResource(artifact, resourceKey) {
916
994
  const artifactPath = normalizeWorkspaceResourcePath(artifact.path);
917
- return Boolean(resourceKey && artifactPath && `sha256:${sha256(artifactPath)}` === resourceKey);
995
+ return Boolean(resourceKey && artifactPath && workspaceResourceKey(artifactPath) === resourceKey);
918
996
  }
919
997
  function isDocumentRenderDeliverable(artifact, tool) {
920
998
  const artifactPath = normalizeWorkspaceResourcePath(artifact.path);
@@ -1067,7 +1145,7 @@ function normalizePreToolObservation(value) {
1067
1145
  || (value.decision === 'allowed' && reservationStatus === 'denied'))
1068
1146
  return null;
1069
1147
  return {
1070
- tool_use_id_sha256: value.tool_use_id_sha256,
1148
+ tool_use_id_sha256: String(value.tool_use_id_sha256),
1071
1149
  tool: value.tool,
1072
1150
  resource_key: resourceKey,
1073
1151
  datasource_sha256: datasourceSha256,
@@ -1204,10 +1282,25 @@ function hostCapabilityRuntimeMatchesRequest(runtime, request) {
1204
1282
  function structuredHostToolResponse(value) {
1205
1283
  if (!isRecord(value))
1206
1284
  return null;
1207
- const nested = value.structured_content ?? value.structuredContent;
1208
- if (nested !== undefined)
1209
- return parseJsonObject(nested);
1210
- return value;
1285
+ const structuredContent = parseBoundedHostToolJsonObject(value.structured_content, MAX_HOST_TOOL_STRUCTURED_RESULT_BYTES) ?? parseBoundedHostToolJsonObject(value.structuredContent, MAX_HOST_TOOL_STRUCTURED_RESULT_BYTES);
1286
+ const contentObjects = Array.isArray(value.content)
1287
+ ? value.content
1288
+ .filter((item) => isRecord(item) && item.type === 'text')
1289
+ .map((item) => parseBoundedHostToolJsonObject(item.text, MAX_EVENT_LINE_BYTES))
1290
+ .filter((item) => item !== null)
1291
+ : [];
1292
+ const distinctContentObjects = distinctJsonObjects(contentObjects);
1293
+ if (distinctContentObjects.length > 1)
1294
+ return null;
1295
+ const contentObject = distinctContentObjects[0] ?? null;
1296
+ if (structuredContent) {
1297
+ return contentObject && !sameJsonObject(structuredContent, contentObject)
1298
+ ? null
1299
+ : structuredContent;
1300
+ }
1301
+ if (value.structured_content !== undefined || value.structuredContent !== undefined)
1302
+ return null;
1303
+ return contentObject;
1211
1304
  }
1212
1305
  function normalizeHostToolSemanticReceipt(tool, toolInput, response) {
1213
1306
  if (tool === 'datasource_schema_context') {
@@ -1425,8 +1518,46 @@ function parseJsonObject(value) {
1425
1518
  }
1426
1519
  return null;
1427
1520
  }
1428
- function uniqueStrings(values) {
1429
- return [...new Set(values.map((value) => String(value || '').trim()).filter(Boolean))].sort();
1521
+ function parseBoundedHostToolJsonObject(value, maxBytes) {
1522
+ if (isRecord(value)) {
1523
+ try {
1524
+ return Buffer.byteLength(JSON.stringify(value), 'utf8') <= maxBytes
1525
+ ? value
1526
+ : null;
1527
+ }
1528
+ catch {
1529
+ return null;
1530
+ }
1531
+ }
1532
+ if (typeof value !== 'string' || !value.trim())
1533
+ return null;
1534
+ const trimmed = value.trim();
1535
+ if (Buffer.byteLength(trimmed, 'utf8') > maxBytes)
1536
+ return null;
1537
+ try {
1538
+ const parsed = JSON.parse(trimmed);
1539
+ return isRecord(parsed) ? parsed : null;
1540
+ }
1541
+ catch {
1542
+ return null;
1543
+ }
1544
+ }
1545
+ function distinctJsonObjects(values) {
1546
+ const distinct = new Map();
1547
+ for (const value of values)
1548
+ distinct.set(canonicalJson(value), value);
1549
+ return [...distinct.values()];
1550
+ }
1551
+ function sameJsonObject(left, right) {
1552
+ return canonicalJson(left) === canonicalJson(right);
1553
+ }
1554
+ function canonicalJson(value) {
1555
+ if (Array.isArray(value))
1556
+ return `[${value.map(canonicalJson).join(',')}]`;
1557
+ if (isRecord(value)) {
1558
+ return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(',')}}`;
1559
+ }
1560
+ return JSON.stringify(value) ?? 'null';
1430
1561
  }
1431
1562
  function arrayStrings(value) {
1432
1563
  return Array.isArray(value)
@@ -1446,6 +1577,3 @@ function uniqueWorkflows(values) {
1446
1577
  ]);
1447
1578
  return uniqueStrings(values).filter((value) => valid.has(value));
1448
1579
  }
1449
- function isRecord(value) {
1450
- return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
1451
- }