sneakoscope 8.1.2 → 8.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. package/README.md +96 -58
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/dist/bin/fast-inline.js +5 -51
  5. package/dist/cli/command-manifest-lite.js +2 -1
  6. package/dist/cli/command-registry.js +2 -1
  7. package/dist/cli/global-mode-router.js +1 -1
  8. package/dist/cli/install-helpers-codex-lb-config.js +112 -914
  9. package/dist/cli/install-helpers-codex-lb-shared.js +3 -44
  10. package/dist/cli/install-helpers-install-support.js +4 -20
  11. package/dist/cli/install-helpers.js +36 -2716
  12. package/dist/cli/router.js +9 -9
  13. package/dist/commands/bridge-command-output.js +111 -0
  14. package/dist/commands/bridge.js +320 -0
  15. package/dist/commands/codex-app.js +39 -123
  16. package/dist/commands/doctor-helpers.js +380 -0
  17. package/dist/commands/doctor-profile.js +3 -0
  18. package/dist/commands/doctor.js +114 -873
  19. package/dist/commands/mad-sks.js +0 -4
  20. package/dist/config/skills-manifest.json +1 -1
  21. package/dist/core/agents/agent-effort-policy.js +11 -21
  22. package/dist/core/agents/agent-recursion-guard.js +26 -0
  23. package/dist/core/agents/agent-runner-codex-exec.js +7 -9
  24. package/dist/core/architecture-hardening/contracts/contracts.js +225 -161
  25. package/dist/core/architecture-hardening/state/state-service.js +49 -13
  26. package/dist/core/auto-review.js +15 -9
  27. package/dist/core/codex/codex-config-guard.js +8 -0
  28. package/dist/core/codex-adapter.js +8 -10
  29. package/dist/core/codex-app/codex-app-fast-ui-repair.js +7 -29
  30. package/dist/core/codex-app/codex-app-launcher.js +10 -12
  31. package/dist/core/codex-app/codex-app-restart.js +10 -12
  32. package/dist/core/codex-app/menubar/constants.js +2 -5
  33. package/dist/core/codex-app/menubar/global-install.js +3 -2
  34. package/dist/core/codex-app/menubar/installer/result.js +23 -0
  35. package/dist/core/codex-app/menubar/installer/runtime.js +28 -0
  36. package/dist/core/codex-app/menubar/installer.js +5 -96
  37. package/dist/core/codex-app/menubar/migration.js +1 -42
  38. package/dist/core/codex-app/openrouter-provider.js +0 -78
  39. package/dist/core/codex-app.js +97 -360
  40. package/dist/core/codex-control/codex-app-server-runtime-env.js +8 -28
  41. package/dist/core/codex-control/codex-current-image-path-real-probe.js +2 -3
  42. package/dist/core/codex-control/codex-current-web-search-probe.js +2 -3
  43. package/dist/core/codex-control/codex-sdk-adapter.js +5 -48
  44. package/dist/core/codex-control/codex-task-runner.js +16 -60
  45. package/dist/core/codex-control/desktop-bridge-launch-guard.js +227 -0
  46. package/dist/core/codex-exec-output-schema.js +11 -13
  47. package/dist/core/codex-lb/bridge-contracts.js +2 -0
  48. package/dist/core/codex-lb/bridge-runtime-validation/capability.js +104 -0
  49. package/dist/core/codex-lb/bridge-runtime-validation/catalog.js +52 -0
  50. package/dist/core/codex-lb/bridge-runtime-validation/shared.js +109 -0
  51. package/dist/core/codex-lb/bridge-runtime-validation/status.js +250 -0
  52. package/dist/core/codex-lb/bridge-runtime-validation.js +106 -0
  53. package/dist/core/codex-lb/capability-runner.js +505 -201
  54. package/dist/core/codex-lb/codex-lb-env.js +179 -12
  55. package/dist/core/codex-lb/combined-catalog/builder.js +86 -0
  56. package/dist/core/codex-lb/combined-catalog/contracts.js +5 -0
  57. package/dist/core/codex-lb/combined-catalog/normalize.js +170 -0
  58. package/dist/core/codex-lb/combined-catalog/persistence.js +207 -0
  59. package/dist/core/codex-lb/combined-catalog/shared.js +12 -0
  60. package/dist/core/codex-lb/combined-catalog/storage.js +171 -0
  61. package/dist/core/codex-lb/combined-catalog.js +12 -0
  62. package/dist/core/codex-lb/desktop-bridge/client.js +4 -1
  63. package/dist/core/codex-lb/desktop-bridge/header-policy.js +48 -63
  64. package/dist/core/codex-lb/desktop-bridge/http-forward.js +115 -83
  65. package/dist/core/codex-lb/desktop-bridge/launchd.js +20 -13
  66. package/dist/core/codex-lb/desktop-bridge/location-rewrite.js +4 -1
  67. package/dist/core/codex-lb/desktop-bridge/security.js +381 -267
  68. package/dist/core/codex-lb/desktop-bridge/server.js +148 -19
  69. package/dist/core/codex-lb/desktop-bridge/state.js +56 -70
  70. package/dist/core/codex-lb/desktop-bridge/types.js +6 -1
  71. package/dist/core/codex-lb/desktop-bridge/websocket-forward.js +281 -106
  72. package/dist/core/codex-lb/desktop-bridge-migration/historical-config.js +245 -0
  73. package/dist/core/codex-lb/desktop-bridge-migration/historical-toml.js +56 -0
  74. package/dist/core/codex-lb/desktop-bridge-migration/metadata.js +73 -0
  75. package/dist/core/codex-lb/desktop-bridge-migration/receipt.js +52 -0
  76. package/dist/core/codex-lb/desktop-bridge-migration/retired-runtime-cleanup.js +106 -0
  77. package/dist/core/codex-lb/desktop-bridge-migration/types.js +1 -0
  78. package/dist/core/codex-lb/desktop-bridge-migration.js +238 -0
  79. package/dist/core/codex-lb/desktop-controller-v3/catalog.js +257 -0
  80. package/dist/core/codex-lb/desktop-controller-v3/diagnostics.js +62 -0
  81. package/dist/core/codex-lb/desktop-controller-v3/lifecycle-commands.js +203 -0
  82. package/dist/core/codex-lb/desktop-controller-v3/live-probes.js +293 -0
  83. package/dist/core/codex-lb/desktop-controller-v3/preflight-probes.js +144 -0
  84. package/dist/core/codex-lb/desktop-controller-v3/provider-commands.js +182 -0
  85. package/dist/core/codex-lb/desktop-controller-v3/shared.js +279 -0
  86. package/dist/core/codex-lb/desktop-controller-v3/status.js +269 -0
  87. package/dist/core/codex-lb/desktop-controller-v3/types.js +1 -0
  88. package/dist/core/codex-lb/desktop-controller-v3/verification.js +89 -0
  89. package/dist/core/codex-lb/desktop-controller-v3.js +67 -0
  90. package/dist/core/codex-lb/desktop-controller.js +2 -1730
  91. package/dist/core/codex-lb/desktop-service.js +462 -627
  92. package/dist/core/codex-lb/migration-receipt.js +560 -118
  93. package/dist/core/codex-lb/probes/auxiliary-surfaces-probe.js +37 -53
  94. package/dist/core/codex-lb/probes/bridge-probe.js +125 -64
  95. package/dist/core/codex-lb/probes/catalog-probe.js +36 -136
  96. package/dist/core/codex-lb/probes/computer-use-probe.js +63 -39
  97. package/dist/core/codex-lb/probes/image-generation-probe.js +98 -41
  98. package/dist/core/codex-lb/probes/probe-evidence.js +32 -33
  99. package/dist/core/codex-lb/probes/voice-realtime-probe.js +69 -43
  100. package/dist/core/codex-lb/provider-credentials/configuration.js +127 -0
  101. package/dist/core/codex-lb/provider-credentials/locks.js +11 -0
  102. package/dist/core/codex-lb/provider-credentials/private-snapshot.js +28 -0
  103. package/dist/core/codex-lb/provider-credentials/removal.js +33 -0
  104. package/dist/core/codex-lb/provider-credentials/resolution.js +59 -0
  105. package/dist/core/codex-lb/provider-credentials/runtime.js +55 -0
  106. package/dist/core/codex-lb/provider-credentials/types.js +1 -0
  107. package/dist/core/codex-lb/provider-credentials/validation-store.js +137 -0
  108. package/dist/core/codex-lb/provider-credentials.js +5 -0
  109. package/dist/core/codex-lb/provider-registry.js +323 -0
  110. package/dist/core/codex-lb/provider-route-policy.js +118 -0
  111. package/dist/core/codex-lb/request-route-resolver.js +172 -0
  112. package/dist/core/codex-lb/route-index.js +148 -0
  113. package/dist/core/codex-lb/trusted-deep-evidence.js +158 -286
  114. package/dist/core/commands/basic-cli.js +1 -1
  115. package/dist/core/commands/check-command.js +3 -10
  116. package/dist/core/commands/gate-result-contract.js +10 -14
  117. package/dist/core/commands/intent-normalization/normalizer.js +1 -1
  118. package/dist/core/commands/mad-sks-command.js +2 -6
  119. package/dist/core/commands/release-command.js +11 -1
  120. package/dist/core/commands/telegram-command.js +46 -6
  121. package/dist/core/doctor/doctor-readiness-matrix.js +9 -7
  122. package/dist/core/doctor/skill-legacy-surface.js +5 -5
  123. package/dist/core/evidence/v2/evidence-key.js +30 -3
  124. package/dist/core/feature-fixtures.js +8 -1
  125. package/dist/core/feature-registry.js +3 -2
  126. package/dist/core/hooks-runtime/stop-finalization.js +11 -1
  127. package/dist/core/hooks-runtime/subagent-context.js +15 -1
  128. package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +1 -1
  129. package/dist/core/hooks-runtime/tool-output-quarantine.js +1 -1
  130. package/dist/core/hooks-runtime.js +73 -87
  131. package/dist/core/image-ux-review/imagegen-adapter.js +108 -94
  132. package/dist/core/image-ux-review/real-callout-extractor.js +144 -14
  133. package/dist/core/imagegen/desktop-bridge-imagegen-target.js +77 -0
  134. package/dist/core/imagegen/imagegen-capability.js +43 -151
  135. package/dist/core/init/skills/filesystem.js +89 -0
  136. package/dist/core/init/skills/inventory.js +97 -0
  137. package/dist/core/init/skills/manifest.js +151 -0
  138. package/dist/core/init/skills.js +5 -325
  139. package/dist/core/init.js +0 -63
  140. package/dist/core/install/installed-package-smoke.js +1 -1
  141. package/dist/core/managed-assets/managed-assets-manifest.js +0 -1
  142. package/dist/core/policy/latest-version-guidance.js +15 -2
  143. package/dist/core/preflight/parallel-preflight-engine.js +27 -51
  144. package/dist/core/provider/provider-badge.js +9 -4
  145. package/dist/core/provider/provider-context.js +57 -107
  146. package/dist/core/providers/openrouter/openrouter-account.js +3 -1
  147. package/dist/core/providers/openrouter/openrouter-secret-store.js +91 -22
  148. package/dist/core/release/desktop-bridge-release-evidence.js +457 -0
  149. package/dist/core/release/gate-manifest.js +0 -1
  150. package/dist/core/release/main-push-guard.js +13 -0
  151. package/dist/core/release/main-push-receipt.js +11 -0
  152. package/dist/core/release/physical-release-gates.js +664 -61
  153. package/dist/core/release/publish-preflight.js +3 -3
  154. package/dist/core/release/release-gate-batch-runner.js +19 -6
  155. package/dist/core/release/release-gate-dag.js +33 -6
  156. package/dist/core/release/release-gate-node.js +1 -3
  157. package/dist/core/release/release-gate-output-contract.js +55 -0
  158. package/dist/core/release/release-pack-contract.js +1 -1
  159. package/dist/core/release/release-pack-receipt.js +209 -8
  160. package/dist/core/release/release-real-contract.js +1 -1
  161. package/dist/core/release/stage-publish.js +106 -28
  162. package/dist/core/retention/temp-lease.js +204 -0
  163. package/dist/core/retention.js +18 -195
  164. package/dist/core/routes.js +1 -2
  165. package/dist/core/safety/intent-contract/intent-contract.js +3 -3
  166. package/dist/core/subagents/naruto-host-credentials.js +6 -1
  167. package/dist/core/subagents/official-subagent-config.js +27 -9
  168. package/dist/core/subagents/official-subagent-runner.js +14 -31
  169. package/dist/core/subagents/wave-lifecycle.js +36 -8
  170. package/dist/core/subagents/wave-parent-guidance.js +2 -1
  171. package/dist/core/telegram/doctor.js +2 -2
  172. package/dist/core/telegram/liveness.js +10 -4
  173. package/dist/core/triwiki/context-graph/compiler/index.js +18 -18
  174. package/dist/core/update/update-migration-state/fast-mode-config.js +172 -0
  175. package/dist/core/update/update-migration-state/session-state-split.js +247 -0
  176. package/dist/core/update/update-migration-state/simple-stages.js +46 -0
  177. package/dist/core/update/update-migration-state.js +4 -481
  178. package/dist/core/version.js +1 -1
  179. package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +28 -4
  180. package/dist/native/sks-menubar/Sources/OperationModels.swift +112 -2
  181. package/dist/native/sks-menubar/Sources/ProviderRouteExplanation.swift +21 -0
  182. package/dist/native/sks-menubar/Sources/ProvidersBridgeCatalog.swift +140 -0
  183. package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +107 -470
  184. package/dist/native/sks-menubar/Sources/ProvidersReliability.swift +27 -197
  185. package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +335 -269
  186. package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +233 -437
  187. package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +16 -7
  188. package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +39 -9
  189. package/dist/native/sks-menubar/Sources/TelegramSupport.swift +56 -0
  190. package/dist/scripts/canonical-test-runner.js +7 -1
  191. package/dist/scripts/check-runtime-schemas.js +7 -2
  192. package/dist/scripts/codex-sdk-real-smoke-check.js +3 -1
  193. package/dist/scripts/desktop-bridge-capabilities-check.js +123 -0
  194. package/dist/scripts/{codex-lb-desktop-bridge-latency-check.js → desktop-bridge-latency-check.js} +61 -16
  195. package/dist/scripts/desktop-bridge-real-evidence-check.js +64 -0
  196. package/dist/scripts/{codex-lb-desktop-bridge-check.js → desktop-bridge-transport-check.js} +92 -155
  197. package/dist/scripts/desktop-bridge-transport-client.js +116 -0
  198. package/dist/scripts/desktop-bridge-unification-check.js +276 -0
  199. package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +12 -8
  200. package/dist/scripts/gate-policy-audit-check.js +52 -2
  201. package/dist/scripts/provider-badge-context-check.js +55 -12
  202. package/dist/scripts/publish-preflight.js +1 -2
  203. package/dist/scripts/release-affected-selector-check.js +1 -2
  204. package/dist/scripts/release-aggressive-resource-governor-check.js +1 -1
  205. package/dist/scripts/release-cache-glob-hashing-check.js +1 -0
  206. package/dist/scripts/release-cache-version-neutral-fixture-check.js +1 -0
  207. package/dist/scripts/release-full-parallelism-blackbox.js +1 -1
  208. package/dist/scripts/release-gate-batch-runner-check.js +9 -0
  209. package/dist/scripts/release-gate-dag-runner-check.js +6 -0
  210. package/dist/scripts/release-gate-dag-runner.js +4 -2
  211. package/dist/scripts/release-metadata-check.js +16 -3
  212. package/dist/scripts/release-pack-receipt.js +29 -6
  213. package/dist/scripts/release-physical-gates-check.js +39 -0
  214. package/dist/scripts/release-real-check.js +7 -5
  215. package/package.json +6 -8
  216. package/release-gates.v2.json +156 -157
  217. package/runtime-required-scripts.json +11 -11
  218. package/schemas/codex/desktop-bridge-status-v3.schema.json +286 -0
  219. package/schemas/codex/desktop-capabilities-v3.schema.json +198 -0
  220. package/schemas/release/release-gate-node.schema.json +2 -3
  221. package/dist/cli/codex-lb-setup-warning-output.js +0 -17
  222. package/dist/cli/install-helpers-codex-lb-chain.js +0 -529
  223. package/dist/commands/codex-lb.js +0 -1232
  224. package/dist/core/architecture-hardening/migration/migration.js +0 -111
  225. package/dist/core/codex-app/auxiliary-oauth-policy.js +0 -36
  226. package/dist/core/codex-app/catalog-compat/catalog-service.js +0 -104
  227. package/dist/core/codex-app/child-policy/child-policy.js +0 -35
  228. package/dist/core/codex-app/desktop-routing-snapshot.js +0 -233
  229. package/dist/core/codex-app/glm-model-profile.js +0 -1
  230. package/dist/core/codex-app/glm-profile-installer.js +0 -191
  231. package/dist/core/codex-app/glm-profile-schema.js +0 -42
  232. package/dist/core/codex-app/multi-provider-router.js +0 -391
  233. package/dist/core/codex-app/openrouter-activate.js +0 -405
  234. package/dist/core/codex-app/openrouter-model-catalog.js +0 -217
  235. package/dist/core/codex-app/provider-child-policy.js +0 -64
  236. package/dist/core/codex-app/provider-mode.js +0 -91
  237. package/dist/core/codex-app/provider-session-policy.js +0 -85
  238. package/dist/core/codex-app/session-policy/session-pinning.js +0 -68
  239. package/dist/core/codex-control/codex-lb-launch-recovery.js +0 -319
  240. package/dist/core/codex-lb/codex-lb-setup.js +0 -293
  241. package/dist/core/codex-lb/codex-lb-tool-catalog.js +0 -456
  242. package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +0 -290
  243. package/dist/core/codex-lb/desktop-center-credentials.js +0 -1083
  244. package/dist/core/codex-lb/desktop-mode.js +0 -32
  245. package/dist/core/codex-lb/desktop-real-evidence.js +0 -168
  246. package/dist/core/codex-lb/legacy-migration.js +0 -576
  247. package/dist/core/codex-lb/native-openai-transport/transport.js +0 -68
  248. package/dist/core/codex-lb/provider-routing/provider-router.js +0 -58
  249. package/dist/core/codex-lb/routing-truth.js +0 -327
  250. package/dist/core/imagegen/codex-lb-imagegen-target.js +0 -92
  251. package/dist/native/sks-menubar/Sources/ProvidersConnectTest.swift +0 -118
  252. package/dist/native/sks-menubar/Sources/ProvidersFastMode.swift +0 -17
  253. package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +0 -331
  254. package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +0 -260
  255. package/dist/scripts/codex-lb-catalog-passthrough-check.js +0 -120
  256. package/dist/scripts/codex-lb-desktop-auth-invariant-check.js +0 -169
  257. package/dist/scripts/codex-lb-desktop-capabilities-check.js +0 -287
  258. package/dist/scripts/codex-lb-desktop-real-evidence-check.js +0 -123
  259. package/dist/scripts/codex-lb-fast-mode-truth-check.js +0 -114
  260. package/dist/scripts/codex-lb-fast-ui-preservation-check.js +0 -152
  261. package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +0 -231
@@ -1,216 +1,520 @@
1
- import { runAuxiliarySurfacesProbe } from './probes/auxiliary-surfaces-probe.js';
2
- import { runBridgeProbe, gatewayAuthTransportEvidence } from './probes/bridge-probe.js';
3
- import { runCatalogProbe } from './probes/catalog-probe.js';
4
- import { runComputerUseProbe } from './probes/computer-use-probe.js';
5
- import { runImageGenerationProbe } from './probes/image-generation-probe.js';
6
- import { probeEvidence } from './probes/probe-evidence.js';
7
- import { runVoiceRealtimeProbe } from './probes/voice-realtime-probe.js';
8
- import { CODEX_LB_DEEP_EVIDENCE_VALIDATION_SCHEMA } from './trusted-deep-evidence.js';
9
- const REQUIRED_FOR_FULL = [
10
- 'gateway_auth_transport',
11
- 'provider_identity',
12
- 'bridge',
13
- 'catalog',
14
- 'model_picker',
15
- 'fast_mode',
16
- 'image_generation',
17
- 'computer_use',
18
- 'browser_use',
19
- 'voice_mode',
20
- 'plugins',
21
- 'auxiliary_surfaces'
1
+ import { uniqueStrings } from './probes/probe-evidence.js';
2
+ import { redactCapabilityEvidence } from './trusted-deep-evidence.js';
3
+ export const DESKTOP_CAPABILITY_REQUIREMENTS_V3 = [
4
+ { scope: 'bridge', capability: 'runtime', minimum_level: 'shallow', readiness: 'routing' },
5
+ { scope: 'bridge', capability: 'http_health', minimum_level: 'transport', readiness: 'routing' },
6
+ { scope: 'bridge', capability: 'websocket_transport', minimum_level: 'transport', readiness: 'routing' },
7
+ { scope: 'native-identity', capability: 'oauth_identity', minimum_level: 'shallow', readiness: 'routing' },
8
+ { scope: 'provider:*', capability: 'credential', minimum_level: 'shallow', readiness: 'routing' },
9
+ { scope: 'provider:*', capability: 'provider_auth', minimum_level: 'transport', readiness: 'routing' },
10
+ { scope: 'provider:*', capability: 'catalog_sync', minimum_level: 'transport', readiness: 'routing' },
11
+ { scope: 'provider:*', capability: 'model_route', minimum_level: 'transport', readiness: 'routing' },
12
+ { scope: 'provider:*', capability: 'text_responses', minimum_level: 'transport', readiness: 'routing' },
13
+ { scope: 'catalog:combined', capability: 'route_policy', minimum_level: 'shallow', readiness: 'routing' },
14
+ { scope: 'catalog:combined', capability: 'catalog_sync', minimum_level: 'transport', readiness: 'routing' },
15
+ { scope: 'catalog:combined', capability: 'model_route', minimum_level: 'transport', readiness: 'routing' },
16
+ { scope: 'provider:*', capability: 'fast_mode', minimum_level: 'deep', readiness: 'full_feature' },
17
+ { scope: 'provider:*', capability: 'image_generation', minimum_level: 'deep', readiness: 'full_feature' },
18
+ { scope: 'provider:*', capability: 'computer_use', minimum_level: 'deep', readiness: 'full_feature' },
19
+ { scope: 'provider:*', capability: 'browser_use', minimum_level: 'deep', readiness: 'full_feature' },
20
+ { scope: 'provider:*', capability: 'voice_mode', minimum_level: 'deep', readiness: 'full_feature' },
21
+ { scope: 'provider:*', capability: 'plugins', minimum_level: 'deep', readiness: 'full_feature' },
22
+ { scope: 'provider:*', capability: 'auxiliary_surfaces', minimum_level: 'deep', readiness: 'full_feature' }
22
23
  ];
23
- const REQUIRED_FOR_CLI_PROVIDER = [
24
- 'gateway_auth_transport',
25
- 'provider_identity',
26
- 'catalog',
27
- 'model_picker',
28
- 'fast_mode',
29
- 'text_responses',
30
- 'image_generation'
24
+ const V3_SCOPES = [
25
+ 'bridge',
26
+ 'native-identity',
27
+ 'provider:codex-lb',
28
+ 'provider:openrouter',
29
+ 'catalog:combined'
31
30
  ];
32
- export function runCodexLbDesktopCapabilityReport(input) {
33
- const level = input.level || 'shallow';
31
+ const LEVEL_ORDER = {
32
+ shallow: 0,
33
+ transport: 1,
34
+ deep: 2
35
+ };
36
+ export function runDesktopCapabilityReportV3(input) {
34
37
  const checkedAt = input.checkedAt || new Date().toISOString();
35
- const manifest = input.manifest || null;
36
- const catalog = runCatalogProbe({
37
- mode: input.mode,
38
- level,
39
- checkedAt,
40
- manifest,
41
- ...(input.catalog || {})
42
- });
43
- const providerIdentityBlockers = [
44
- ...(input.providerIdentity?.blockers || []),
45
- ...(input.providerIdentity?.requiresOauth === true && input.oauthPreserved !== true
46
- ? ['chatgpt_oauth_identity_not_preserved']
47
- : [])
48
- ];
49
- const providerIdentity = probeEvidence({
50
- ...(input.providerIdentity || {}),
51
- blockers: providerIdentityBlockers,
52
- evidence: {
53
- ...(input.providerIdentity?.evidence || {}),
54
- oauth_required: input.providerIdentity?.requiresOauth === true,
55
- oauth_preserved: input.oauthPreserved === true
56
- }
57
- }, checkedAt);
58
- const bridge = runBridgeProbe({
59
- mode: input.mode,
60
- level,
61
- checkedAt,
62
- manifest,
63
- ...(input.bridge || {})
64
- });
65
- const reportWithoutOverall = {
66
- schema: 'sks.codex-lb-desktop-capabilities.v2',
67
- mode: input.mode,
68
- configured: input.configured === true,
69
- oauth_preserved: input.oauthPreserved === true,
70
- gateway_auth_transport: gatewayAuthTransportEvidence({
71
- checkedAt,
72
- ...(input.gatewayAuth || {})
73
- }),
74
- provider_identity: providerIdentity,
75
- bridge,
76
- catalog: catalog.catalog,
77
- model_picker: catalog.model_picker,
78
- fast_mode: catalog.fast_mode,
79
- text_responses: probeEvidence(input.textResponses || {
80
- skipped: true,
81
- evidence: { reason: 'text_responses_probe_not_run' }
82
- }, checkedAt),
83
- image_generation: runImageGenerationProbe({
84
- level,
85
- checkedAt,
86
- manifestRouteAdvertised: manifestFlag(manifest, 'routes', 'images_generations')
87
- ?? manifestFlag(manifest, 'routes', 'responses_http')
88
- ?? undefined,
89
- toolAdvertised: manifestFlag(manifest, 'tools', 'image_generation') ?? undefined,
90
- ...(input.imageGeneration || {})
91
- }),
92
- computer_use: runComputerUseProbe({
93
- level,
94
- checkedAt,
95
- toolAdvertised: manifestFlag(manifest, 'tools', 'computer_use_passthrough') ?? undefined,
96
- ...(input.computerUse || {})
97
- }),
98
- browser_use: probeEvidence(input.browserUse || {
99
- source: 'config',
100
- evidence: {
101
- independent_from_computer_use: true,
102
- independent_from_auth_mode: true,
103
- reason: 'browser_use_probe_not_run'
104
- }
105
- }, checkedAt),
106
- voice_mode: runVoiceRealtimeProbe({
107
- level,
108
- checkedAt,
109
- routeAdvertised: manifestFlag(manifest, 'routes', 'realtime_calls') ?? undefined,
110
- ...(input.voiceMode || {})
111
- }),
112
- plugins: probeEvidence(input.plugins || {
113
- source: 'config',
114
- evidence: {
115
- independent_from_auth_mode: true
116
- }
117
- }, checkedAt),
118
- auxiliary_surfaces: runAuxiliarySurfacesProbe({
119
- level,
120
- checkedAt,
121
- routesAdvertised: auxiliaryRoutesAdvertised(manifest),
122
- ...(input.auxiliarySurfaces || {})
123
- })
38
+ const executionBlockers = uniqueStrings(input.executionBlockers);
39
+ const executionWarnings = uniqueStrings(input.executionWarnings);
40
+ const catalogSync = validCatalogSync(input.catalogSync)
41
+ ? input.catalogSync
42
+ : invalidCatalogSync(checkedAt);
43
+ if (!validCatalogSync(input.catalogSync))
44
+ executionBlockers.push('capability_schema_invalid:catalog_sync_missing');
45
+ const activeProviders = providerSet(input.activeProviderIds);
46
+ const enabledProviders = providerSet(input.enabledProviderIds || input.activeProviderIds);
47
+ const candidates = [
48
+ ...(input.results || []).filter((result) => result.capability !== 'catalog_sync'),
49
+ ...catalogSyncResults(input, catalogSync, checkedAt)
50
+ ].map((result) => normalizeV3Result(result, input, checkedAt));
51
+ let selected = selectCurrentResults(candidates, input);
52
+ selected = addMissingRequirementResults(selected, input, checkedAt);
53
+ const initial = summariesFromResults(selected, checkedAt);
54
+ const bridgeReady = scopeRequirementsSatisfied(initial.bridge, input.requestedLevel, 'routing');
55
+ const withDependencies = bridgeReady
56
+ ? selected
57
+ : addBridgeDependencies(selected, input, checkedAt, bridgeTerminalCause(initial.bridge), new Set([...enabledProviders, ...activeProviders]));
58
+ const scopes = summariesFromResults(withDependencies, checkedAt);
59
+ const activeProviderSummaries = [...activeProviders].map((provider) => scopes.providers[provider]);
60
+ const activeProvidersReady = activeProviderSummaries.length > 0
61
+ && activeProviderSummaries.every((summary) => scopeRequirementsSatisfied(summary, input.requestedLevel, 'routing'));
62
+ const nativeReady = scopeRequirementsSatisfied(scopes.native_identity, input.requestedLevel, 'routing');
63
+ const catalogReady = scopeRequirementsSatisfied(scopes.combined_catalog, input.requestedLevel, 'routing');
64
+ const activeRoutesReady = bridgeReady && nativeReady && catalogReady && activeProvidersReady;
65
+ const transportSatisfied = LEVEL_ORDER[input.requestedLevel] >= LEVEL_ORDER.transport
66
+ && activeRoutesReady
67
+ && requiredScopesSatisfied(scopes, activeProviders, 'transport', 'routing');
68
+ const deepSatisfied = input.requestedLevel === 'deep'
69
+ && transportSatisfied
70
+ && activeProviderSummaries.every((summary) => scopeRequirementsSatisfied(summary, 'deep', 'full_feature'));
71
+ const levelSatisfied = input.requestedLevel === 'shallow'
72
+ ? activeRoutesReady
73
+ : input.requestedLevel === 'transport'
74
+ ? transportSatisfied
75
+ : deepSatisfied;
76
+ const inactiveProviderFailures = [];
77
+ for (const provider of ['codex-lb', 'openrouter']) {
78
+ if (activeProviders.has(provider) || !enabledProviders.has(provider))
79
+ continue;
80
+ const summary = scopes.providers[provider];
81
+ const failures = uniqueStrings([...summary.blockers, ...scopeRootCauses(summary)]);
82
+ inactiveProviderFailures.push(...failures.map((failure) => `${provider}:${failure}`));
83
+ }
84
+ const routingBlockers = activeRoutesReady
85
+ ? []
86
+ : uniqueStrings([
87
+ ...withoutDependencyBlocker(scopes.bridge.blockers),
88
+ ...scopes.native_identity.blockers,
89
+ ...scopes.combined_catalog.blockers,
90
+ ...activeProviderSummaries.flatMap((summary) => withoutDependencyBlocker(summary.blockers))
91
+ ]);
92
+ const pendingRequired = missingRequiredCapabilityWarnings(scopes, activeProviders, input.requestedLevel);
93
+ const partial = pendingRequired.length > 0;
94
+ return {
95
+ schema: 'sks.desktop-capabilities.v3',
96
+ report_id: input.reportId,
97
+ correlation_id: input.correlationId,
98
+ session_id: input.sessionId,
99
+ requested_level: input.requestedLevel,
100
+ checked_at: checkedAt,
101
+ catalog_generation: catalogSync.generation,
102
+ execution: {
103
+ ok: executionBlockers.length === 0,
104
+ status: executionBlockers.length > 0 ? 'failed' : partial ? 'partial' : 'completed',
105
+ blockers: uniqueStrings(executionBlockers)
106
+ },
107
+ ...scopes,
108
+ summary: {
109
+ bridge_ready: bridgeReady,
110
+ active_routes_ready: activeRoutesReady,
111
+ level_satisfied: levelSatisfied,
112
+ transport_level_satisfied: transportSatisfied,
113
+ deep_level_satisfied: deepSatisfied,
114
+ full_feature_verified: deepSatisfied,
115
+ inactive_provider_failures: uniqueStrings(inactiveProviderFailures).sort(),
116
+ blockers: routingBlockers,
117
+ warnings: uniqueStrings([
118
+ ...executionWarnings,
119
+ ...pendingRequired,
120
+ ...inactiveProviderFailures.map((failure) => `inactive_provider_failure:${failure}`),
121
+ ...scopes.bridge.warnings,
122
+ ...scopes.native_identity.warnings,
123
+ ...scopes.combined_catalog.warnings,
124
+ ...Object.values(scopes.providers).flatMap((summary) => summary.warnings)
125
+ ]).sort()
126
+ },
127
+ catalog_sync: catalogSync
124
128
  };
129
+ }
130
+ function catalogSyncResults(input, catalog, checkedAt) {
131
+ const results = [catalogResult(input, 'catalog:combined', activeCatalogCapabilityState(input, catalog), catalog.blockers, catalog.warnings, catalog.recovery_action, {
132
+ aggregate_state: catalog.state,
133
+ generation: catalog.generation,
134
+ digest: catalog.digest,
135
+ model_count: catalog.model_count,
136
+ route_count: catalog.route_count,
137
+ conflict_count: catalog.conflict_count
138
+ }, checkedAt)];
139
+ for (const provider of ['codex-lb', 'openrouter']) {
140
+ const row = catalog.providers[provider];
141
+ results.push(catalogResult(input, `provider:${provider}`, row.state, row.blockers, row.warnings, row.recovery_action, {
142
+ generation: row.generation,
143
+ digest: row.digest,
144
+ model_count: row.model_count,
145
+ expires_at: row.expires_at
146
+ }, checkedAt));
147
+ }
148
+ return results;
149
+ }
150
+ function activeCatalogCapabilityState(input, catalog) {
151
+ if (catalog.state !== 'degraded' || catalog.conflict_count > 0)
152
+ return catalog.state;
153
+ const active = providerSet(input.activeProviderIds);
154
+ if (active.size === 0)
155
+ return catalog.state;
156
+ const activeProvidersVerified = [...active].every((provider) => catalog.providers[provider]?.state === 'verified');
157
+ return activeProvidersVerified && Number(catalog.route_count || 0) > 0
158
+ ? 'verified'
159
+ : catalog.state;
160
+ }
161
+ function catalogResult(input, scope, state, blockers, warnings, recoveryAction, evidence, checkedAt) {
162
+ const probeState = state === 'verified'
163
+ ? 'verified'
164
+ : state === 'failed'
165
+ ? 'blocked'
166
+ : state === 'degraded'
167
+ ? 'degraded'
168
+ : state === 'stale'
169
+ ? 'stale'
170
+ : state === 'syncing'
171
+ ? 'running'
172
+ : 'not_attempted';
173
+ const rootCause = probeState === 'blocked' ? uniqueStrings(blockers)[0] || 'catalog_sync_failed' : null;
174
+ return {
175
+ schema: 'sks.capability-probe.v3',
176
+ capability: 'catalog_sync',
177
+ scope,
178
+ requested_level: input.requestedLevel,
179
+ stage: probeState === 'verified' ? 'complete' : 'catalog_sync',
180
+ state: probeState,
181
+ checked_at: checkedAt,
182
+ report_id: input.reportId,
183
+ correlation_id: input.correlationId,
184
+ session_id: input.sessionId,
185
+ attempt_id: 1,
186
+ terminal: probeState === 'blocked',
187
+ root_cause: rootCause,
188
+ blockers: probeState === 'not_attempted'
189
+ ? []
190
+ : rootCause
191
+ ? [rootCause]
192
+ : uniqueStrings(blockers),
193
+ warnings: uniqueStrings(warnings),
194
+ retryable: probeState === 'blocked' || probeState === 'stale',
195
+ recovery_action: recoveryAction,
196
+ source: 'transport',
197
+ evidence
198
+ };
199
+ }
200
+ function normalizeV3Result(value, input, checkedAt) {
201
+ const bindingMatches = value.schema === 'sks.capability-probe.v3'
202
+ && V3_SCOPES.includes(value.scope)
203
+ && value.requested_level === input.requestedLevel
204
+ && value.report_id === input.reportId
205
+ && value.correlation_id === input.correlationId
206
+ && value.session_id === input.sessionId;
207
+ if (!bindingMatches) {
208
+ return {
209
+ ...value,
210
+ schema: 'sks.capability-probe.v3',
211
+ requested_level: input.requestedLevel,
212
+ checked_at: checkedAt,
213
+ report_id: input.reportId,
214
+ correlation_id: input.correlationId,
215
+ session_id: input.sessionId,
216
+ state: 'stale',
217
+ terminal: false,
218
+ root_cause: null,
219
+ blockers: ['capability_result_binding_mismatch'],
220
+ warnings: uniqueStrings(value.warnings),
221
+ retryable: true,
222
+ recovery_action: 'rerun_capability_verification',
223
+ evidence: { ...redactCapabilityEvidence(value.evidence), stale_result_rejected: true }
224
+ };
225
+ }
226
+ const requirement = requirementsForScope(value.scope)
227
+ .find((candidate) => candidate.capability === value.capability);
228
+ const sourceCannotVerify = value.source === 'manifest'
229
+ || (value.source === 'config' && requirement?.minimum_level !== 'shallow')
230
+ || value.evidence.fixture === true;
231
+ const requestedBelowCapability = requirement
232
+ ? LEVEL_ORDER[input.requestedLevel] < LEVEL_ORDER[requirement.minimum_level]
233
+ : false;
234
+ if (requestedBelowCapability) {
235
+ return {
236
+ ...value,
237
+ state: 'not_attempted',
238
+ terminal: false,
239
+ root_cause: null,
240
+ blockers: [],
241
+ warnings: uniqueStrings([
242
+ ...value.warnings,
243
+ 'capability_level_not_requested',
244
+ ...(sourceCannotVerify ? ['non_live_evidence_cannot_verify'] : [])
245
+ ]),
246
+ retryable: false,
247
+ recovery_action: requirement?.minimum_level === 'deep' ? 'run_deep_verification' : value.recovery_action,
248
+ evidence: redactCapabilityEvidence(value.evidence)
249
+ };
250
+ }
251
+ if (value.state === 'verified' && sourceCannotVerify) {
252
+ return {
253
+ ...value,
254
+ state: 'not_attempted',
255
+ terminal: false,
256
+ root_cause: null,
257
+ blockers: [],
258
+ warnings: uniqueStrings([...value.warnings, 'non_live_evidence_cannot_verify']),
259
+ retryable: false,
260
+ recovery_action: requirement?.minimum_level === 'deep' ? 'run_deep_verification' : value.recovery_action,
261
+ evidence: redactCapabilityEvidence(value.evidence)
262
+ };
263
+ }
264
+ const rootCause = value.root_cause ? String(value.root_cause) : null;
265
+ const rawBlockers = uniqueStrings(value.blockers)
266
+ .filter((blocker) => blocker !== 'desktop_bridge_websocket_transport_failed');
267
+ const secondary = value.terminal && rootCause
268
+ ? rawBlockers.filter((blocker) => blocker !== rootCause)
269
+ : [];
270
+ return {
271
+ ...value,
272
+ root_cause: rootCause,
273
+ blockers: value.terminal && rootCause ? [rootCause] : rawBlockers,
274
+ warnings: uniqueStrings([
275
+ ...value.warnings,
276
+ ...secondary.map((blocker) => `secondary_diagnostic:${blocker}`)
277
+ ]),
278
+ evidence: redactCapabilityEvidence(value.evidence)
279
+ };
280
+ }
281
+ function selectCurrentResults(results, input) {
282
+ const byKey = new Map();
283
+ for (const result of results) {
284
+ const key = `${result.scope}\u0000${result.capability}`;
285
+ const rows = byKey.get(key) || [];
286
+ rows.push(result);
287
+ byKey.set(key, rows);
288
+ }
289
+ return [...byKey.values()].map((rows) => rows.sort((left, right) => {
290
+ const currentLeft = resultBindingCurrent(left, input) ? 1 : 0;
291
+ const currentRight = resultBindingCurrent(right, input) ? 1 : 0;
292
+ return currentRight - currentLeft
293
+ || Number(right.state !== 'stale') - Number(left.state !== 'stale')
294
+ || right.attempt_id - left.attempt_id
295
+ || right.checked_at.localeCompare(left.checked_at)
296
+ || canonicalResult(left).localeCompare(canonicalResult(right));
297
+ })[0]).sort(resultOrder);
298
+ }
299
+ function addMissingRequirementResults(results, input, checkedAt) {
300
+ const seen = new Set(results.map((result) => `${result.scope}\u0000${result.capability}`));
301
+ const scopes = ['bridge', 'native-identity', 'catalog:combined'];
302
+ for (const provider of ['codex-lb', 'openrouter'])
303
+ scopes.push(`provider:${provider}`);
304
+ for (const scope of scopes) {
305
+ for (const requirement of requirementsForScope(scope)) {
306
+ const key = `${scope}\u0000${requirement.capability}`;
307
+ if (seen.has(key))
308
+ continue;
309
+ results.push(notAttemptedResult(input, scope, requirement.capability, checkedAt));
310
+ seen.add(key);
311
+ }
312
+ }
313
+ return results.sort(resultOrder);
314
+ }
315
+ function addBridgeDependencies(results, input, checkedAt, upstreamRootCause, providers) {
316
+ const existing = new Set(results.map((result) => `${result.scope}\u0000${result.capability}`));
317
+ for (const provider of providers) {
318
+ const key = `provider:${provider}\u0000bridge_dependency`;
319
+ if (existing.has(key))
320
+ continue;
321
+ results.push({
322
+ schema: 'sks.capability-probe.v3',
323
+ capability: 'bridge_dependency',
324
+ scope: `provider:${provider}`,
325
+ requested_level: input.requestedLevel,
326
+ stage: 'preflight',
327
+ state: 'blocked',
328
+ checked_at: checkedAt,
329
+ report_id: input.reportId,
330
+ correlation_id: input.correlationId,
331
+ session_id: input.sessionId,
332
+ attempt_id: 1,
333
+ terminal: false,
334
+ root_cause: null,
335
+ blockers: ['bridge_dependency_unavailable'],
336
+ warnings: [],
337
+ retryable: true,
338
+ recovery_action: 'repair_bridge_service',
339
+ source: 'transport',
340
+ evidence: { upstream_root_cause: upstreamRootCause }
341
+ });
342
+ }
343
+ return results.sort(resultOrder);
344
+ }
345
+ function summariesFromResults(results, checkedAt) {
346
+ const summary = (scope) => scopeSummary(scope, results.filter((result) => result.scope === scope), checkedAt);
125
347
  return {
126
- ...reportWithoutOverall,
127
- deep_evidence_validation: input.deepEvidenceValidation || {
128
- schema: CODEX_LB_DEEP_EVIDENCE_VALIDATION_SCHEMA,
129
- state: 'available_unverified',
130
- trusted: false,
131
- evidence: null,
132
- producer_id: null,
133
- created_at: null,
134
- content_sha256: null,
135
- trust_anchor_id: null,
136
- blockers: ['codex_lb_deep_evidence_missing'],
137
- warnings: []
348
+ bridge: summary('bridge'),
349
+ native_identity: summary('native-identity'),
350
+ providers: {
351
+ 'codex-lb': summary('provider:codex-lb'),
352
+ openrouter: summary('provider:openrouter')
138
353
  },
139
- overall: overallCapabilityState(reportWithoutOverall)
354
+ combined_catalog: summary('catalog:combined')
140
355
  };
141
356
  }
142
- export function overallCapabilityState(report) {
143
- if (report.mode === 'disabled')
144
- return 'available_unverified';
145
- const required = report.mode === 'cli-provider'
146
- ? REQUIRED_FOR_CLI_PROVIDER
147
- : report.mode === 'desktop-native-bridge'
148
- ? REQUIRED_FOR_FULL
149
- : REQUIRED_FOR_FULL.filter((key) => key !== 'bridge');
150
- const states = required.map((key) => report[key].state);
151
- if (states.some((state) => state === 'blocked'))
357
+ function scopeSummary(scope, results, checkedAt) {
358
+ const ordered = [...results].sort(resultOrder);
359
+ const capabilities = Object.fromEntries(ordered.map((result) => [result.capability, result]));
360
+ return {
361
+ schema: 'sks.scope-capability-summary.v1',
362
+ scope,
363
+ state: aggregateScopeState(scope, ordered),
364
+ checked_at: ordered.map((result) => result.checked_at).sort().at(-1) || checkedAt,
365
+ capabilities,
366
+ blockers: uniqueStrings(ordered.flatMap((result) => result.blockers)).sort(),
367
+ warnings: uniqueStrings(ordered.flatMap((result) => result.warnings)).sort()
368
+ };
369
+ }
370
+ function aggregateScopeState(scope, results) {
371
+ const requestedLevel = results[0]?.requested_level || 'shallow';
372
+ const relevantCapabilities = new Set(requirementsForScope(scope)
373
+ .filter((requirement) => LEVEL_ORDER[requirement.minimum_level] <= LEVEL_ORDER[requestedLevel])
374
+ .map((requirement) => requirement.capability));
375
+ const relevant = results.filter((result) => (relevantCapabilities.has(result.capability)
376
+ || !requirementsForScope(scope).some((requirement) => requirement.capability === result.capability)));
377
+ const states = relevant.map((result) => result.state);
378
+ if (states.includes('failed'))
379
+ return 'failed';
380
+ if (states.includes('blocked'))
152
381
  return 'blocked';
153
- if (states.some((state) => state === 'unsupported'))
154
- return 'unsupported';
155
- if (report.configured && states.every((state) => state === 'verified'))
382
+ if (states.includes('stale'))
383
+ return 'stale';
384
+ if (states.includes('degraded'))
385
+ return 'degraded';
386
+ if (states.includes('running'))
387
+ return 'running';
388
+ if (states.length > 0 && states.every((state) => state === 'verified' || state === 'unsupported'))
156
389
  return 'verified';
157
- return 'available_unverified';
390
+ if (states.includes('not_attempted'))
391
+ return 'not_attempted';
392
+ if (states.includes('unsupported'))
393
+ return 'unsupported';
394
+ return 'not_attempted';
395
+ }
396
+ function scopeRequirementsSatisfied(summary, requestedLevel, readiness) {
397
+ const requirements = requirementsForScope(summary.scope)
398
+ .filter((requirement) => requirement.readiness === readiness)
399
+ .filter((requirement) => LEVEL_ORDER[requirement.minimum_level] <= LEVEL_ORDER[requestedLevel]);
400
+ return requirements.length > 0
401
+ && requirements.every((requirement) => summary.capabilities[requirement.capability]?.state === 'verified');
402
+ }
403
+ function requiredScopesSatisfied(scopes, activeProviders, requestedLevel, readiness) {
404
+ return scopeRequirementsSatisfied(scopes.bridge, requestedLevel, readiness)
405
+ && scopeRequirementsSatisfied(scopes.native_identity, requestedLevel, readiness)
406
+ && scopeRequirementsSatisfied(scopes.combined_catalog, requestedLevel, readiness)
407
+ && [...activeProviders].every((provider) => scopeRequirementsSatisfied(scopes.providers[provider], requestedLevel, readiness));
408
+ }
409
+ function requirementsForScope(scope) {
410
+ return DESKTOP_CAPABILITY_REQUIREMENTS_V3.filter((requirement) => (requirement.scope === scope
411
+ || (requirement.scope === 'provider:*' && scope.startsWith('provider:'))));
412
+ }
413
+ function missingRequiredCapabilityWarnings(scopes, activeProviders, level) {
414
+ const summaries = [scopes.bridge, scopes.native_identity, scopes.combined_catalog];
415
+ summaries.push(...[...activeProviders].map((provider) => scopes.providers[provider]));
416
+ const warnings = [];
417
+ for (const summary of summaries) {
418
+ for (const requirement of requirementsForScope(summary.scope)) {
419
+ if (LEVEL_ORDER[requirement.minimum_level] > LEVEL_ORDER[level])
420
+ continue;
421
+ const state = summary.capabilities[requirement.capability]?.state;
422
+ if (state === 'not_attempted' || state === 'running' || state == null) {
423
+ warnings.push(`required_capability_not_attempted:${summary.scope}:${requirement.capability}`);
424
+ }
425
+ }
426
+ }
427
+ return uniqueStrings(warnings).sort();
158
428
  }
159
- export function shapeCodexLbDesktopCapabilityStatus(report) {
160
- const entries = capabilityEntries(report);
429
+ function bridgeTerminalCause(summary) {
430
+ return Object.values(summary.capabilities)
431
+ .sort(resultOrder)
432
+ .find((result) => result.terminal && result.root_cause)?.root_cause || null;
433
+ }
434
+ function scopeRootCauses(summary) {
435
+ return Object.values(summary.capabilities)
436
+ .map((result) => result.root_cause)
437
+ .filter((value) => Boolean(value));
438
+ }
439
+ function withoutDependencyBlocker(blockers) {
440
+ return blockers.filter((blocker) => blocker !== 'bridge_dependency_unavailable');
441
+ }
442
+ function notAttemptedResult(input, scope, capability, checkedAt) {
443
+ const deepOnly = DESKTOP_CAPABILITY_REQUIREMENTS_V3.some((requirement) => ((requirement.scope === scope || (requirement.scope === 'provider:*' && scope.startsWith('provider:')))
444
+ && requirement.capability === capability
445
+ && requirement.minimum_level === 'deep'));
161
446
  return {
162
- schema: 'sks.codex-lb-desktop-capability-status.v2',
163
- ready: report.overall === 'verified',
164
- state: report.overall,
165
- configured: report.configured,
166
- oauth_preserved: report.oauth_preserved,
167
- gateway_auth_transport: String(report.gateway_auth_transport.evidence.configured_gateway_auth_transport || 'unknown'),
168
- model_picker: report.model_picker,
169
- verified: entries.filter(([, value]) => value.state === 'verified').map(([key]) => key),
170
- available_unverified: entries.filter(([, value]) => value.state === 'available_unverified').map(([key]) => key),
171
- blocked: Object.fromEntries(entries
172
- .filter(([, value]) => value.state === 'blocked')
173
- .map(([key, value]) => [key, value.blockers])),
174
- unsupported: entries.filter(([, value]) => value.state === 'unsupported').map(([key]) => key),
175
- skipped: entries.filter(([, value]) => value.state === 'skipped').map(([key]) => key)
447
+ schema: 'sks.capability-probe.v3',
448
+ capability,
449
+ scope,
450
+ requested_level: input.requestedLevel,
451
+ stage: 'preflight',
452
+ state: 'not_attempted',
453
+ checked_at: checkedAt,
454
+ report_id: input.reportId,
455
+ correlation_id: input.correlationId,
456
+ session_id: input.sessionId,
457
+ attempt_id: 0,
458
+ terminal: false,
459
+ root_cause: null,
460
+ blockers: [],
461
+ warnings: [],
462
+ retryable: false,
463
+ recovery_action: deepOnly ? 'run_deep_verification' : null,
464
+ source: 'config',
465
+ evidence: { reason: deepOnly ? 'deep_verification_not_run' : 'probe_not_run' }
176
466
  };
177
467
  }
178
- function capabilityEntries(report) {
179
- const keys = [
180
- 'gateway_auth_transport',
181
- 'provider_identity',
182
- 'bridge',
183
- 'catalog',
184
- 'model_picker',
185
- 'fast_mode',
186
- 'text_responses',
187
- 'image_generation',
188
- 'computer_use',
189
- 'browser_use',
190
- 'voice_mode',
191
- 'plugins',
192
- 'auxiliary_surfaces'
193
- ];
194
- return keys.map((key) => [key, report[key]]);
195
- }
196
- function manifestFlag(manifest, section, key) {
197
- const row = manifest?.[section];
198
- if (!row || typeof row !== 'object' || Array.isArray(row))
199
- return null;
200
- const value = row[key];
201
- return typeof value === 'boolean' ? value : null;
202
- }
203
- function auxiliaryRoutesAdvertised(manifest) {
204
- if (!manifest)
205
- return undefined;
206
- const flags = [
207
- manifestFlag(manifest, 'routes', 'files'),
208
- manifestFlag(manifest, 'routes', 'transcribe'),
209
- manifestFlag(manifest, 'routes', 'images_edits'),
210
- manifestFlag(manifest, 'routes', 'thread_goal'),
211
- manifestFlag(manifest, 'routes', 'memories_trace_summarize'),
212
- manifestFlag(manifest, 'routes', 'safety_arc'),
213
- manifestFlag(manifest, 'routes', 'agent_identities_jwks')
214
- ];
215
- return flags.some((flag) => flag === true);
468
+ function resultBindingCurrent(result, input) {
469
+ return result.report_id === input.reportId
470
+ && result.correlation_id === input.correlationId
471
+ && result.session_id === input.sessionId
472
+ && result.requested_level === input.requestedLevel;
473
+ }
474
+ function resultOrder(left, right) {
475
+ return left.scope.localeCompare(right.scope)
476
+ || left.capability.localeCompare(right.capability)
477
+ || right.attempt_id - left.attempt_id
478
+ || right.checked_at.localeCompare(left.checked_at);
479
+ }
480
+ function canonicalResult(value) {
481
+ return JSON.stringify(value, Object.keys(value).sort());
482
+ }
483
+ function providerSet(values) {
484
+ return new Set(values.filter((value) => value === 'codex-lb' || value === 'openrouter'));
485
+ }
486
+ function validCatalogSync(value) {
487
+ return value?.schema === 'sks.combined-catalog-sync.v1'
488
+ && value.providers?.['codex-lb']?.schema === 'sks.catalog-sync-state.v2'
489
+ && value.providers?.openrouter?.schema === 'sks.catalog-sync-state.v2';
490
+ }
491
+ function invalidCatalogSync(checkedAt) {
492
+ const provider = (providerId) => ({
493
+ schema: 'sks.catalog-sync-state.v2',
494
+ provider_id: providerId,
495
+ state: 'failed',
496
+ source: providerId === 'codex-lb' ? 'gateway' : 'openrouter',
497
+ generation: null,
498
+ digest: null,
499
+ model_count: null,
500
+ checked_at: checkedAt,
501
+ expires_at: null,
502
+ blockers: ['capability_schema_invalid:catalog_sync_missing'],
503
+ warnings: [],
504
+ recovery_action: 'update_sks_and_rebuild_menubar'
505
+ });
506
+ return {
507
+ schema: 'sks.combined-catalog-sync.v1',
508
+ state: 'failed',
509
+ generation: null,
510
+ digest: null,
511
+ model_count: null,
512
+ route_count: null,
513
+ conflict_count: 0,
514
+ checked_at: checkedAt,
515
+ providers: { 'codex-lb': provider('codex-lb'), openrouter: provider('openrouter') },
516
+ blockers: ['capability_schema_invalid:catalog_sync_missing'],
517
+ warnings: [],
518
+ recovery_action: 'update_sks_and_rebuild_menubar'
519
+ };
216
520
  }