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
@@ -22,7 +22,6 @@ import { writeCodexCurrentCoreCapabilityArtifacts } from '../codex-control/codex
22
22
  import { resolveCodexNativeInvocationPlan } from '../codex-native/codex-native-invocation-router.js';
23
23
  import { assertNonGlmMadRoute } from '../routes/model-mode-router.js';
24
24
  import { evaluateGate } from '../stop-gate/gate-evaluator.js';
25
- import { CODEX_LB_TOOL_OUTPUT_RECOVERY_OVERRIDE_FLAG, codexLbToolOutputRecoveryOverrideAcknowledged } from '../codex-lb/codex-lb-tool-output-recovery.js';
26
25
  import { writeMadNativeSession } from './mad-sks-headless.js';
27
26
  const MAD_SKS_DEFAULT_TTL_MS = 10 * 60 * 1000;
28
27
  const UNSUPPORTED_MAD_ARGUMENT_NAMES = new Set([
@@ -92,7 +91,7 @@ export async function madHighCommand(args = [], deps = {}) {
92
91
  ok: false,
93
92
  status: 'blocked',
94
93
  blockers: retiredGlmFlagBlockers,
95
- hint: 'GLM MAD CLI was removed. Use SKS Center Providers or sks codex-app use-openrouter --model <id>.'
94
+ hint: 'GLM MAD CLI was removed. Use sks bridge provider configure|validate|enable, sks bridge catalog sync, and sks bridge route set-default.'
96
95
  };
97
96
  if (rawArgs.includes('--json'))
98
97
  console.log(JSON.stringify(result, null, 2));
@@ -142,15 +141,13 @@ export async function madHighCommand(args = [], deps = {}) {
142
141
  const strictUiSnapshot = process.env.SKS_MAD_STRICT_UI_SNAPSHOT === '1';
143
142
  const beforeUi = strictUiSnapshot ? await writeCodexAppUiSnapshot(launchRoot, `mad-before-${uiSnapshotId}`).catch(() => null) : null;
144
143
  const allowMadRepair = rawArgs.includes('--repair-config') || rawArgs.includes('--fix') || rawArgs.includes('--yes-repair');
145
- const allowUnverifiedToolOutputRecovery = codexLbToolOutputRecoveryOverrideAcknowledged({ args: rawArgs });
146
144
  const launchPreflightOpts = {
147
145
  fix: allowMadRepair,
148
146
  launchFast: process.env.SKS_LAUNCH_FULL_CODEX_PROBE !== '1',
149
147
  profile: profile.profile_name,
150
148
  sandbox: 'danger-full-access',
151
149
  serviceTier: 'fast',
152
- skipCodexLbToolOutputRecovery: false,
153
- allowUnverifiedToolOutputRecovery
150
+ skipDesktopBridgeStatus: false
154
151
  };
155
152
  let launchPreflight = await runCodexLaunchPreflight(launchRoot, launchPreflightOpts);
156
153
  if (!launchPreflight.ok && !fs.existsSync(path.join(launchRoot, '.codex', 'config.toml'))) {
@@ -375,7 +372,6 @@ function baseMadLaunchOnlyFlags() {
375
372
  '--dry-run',
376
373
  '--plan-only',
377
374
  '--ack',
378
- CODEX_LB_TOOL_OUTPUT_RECOVERY_OVERRIDE_FLAG
379
375
  ]);
380
376
  }
381
377
  function retiredGlmMadFlags() {
@@ -23,6 +23,10 @@ export function usage() {
23
23
  ' stage workflow, wait, download and verify the tarball.',
24
24
  ' Without it, stage only reports what it would do.',
25
25
  ' --version <semver> Version to stage (defaults to package.json).',
26
+ ' --physical-evidence-run-id <id>',
27
+ ' Successful trusted physical capture workflow run.',
28
+ ' --physical-evidence-archive <path>',
29
+ ' Optional local copy of the attested capture archive.',
26
30
  '',
27
31
  'stage never runs `npm stage approve`; that approval is a human 2FA step.'
28
32
  ].join('\n');
@@ -92,7 +96,13 @@ async function runStageSubcommand(root, args, json) {
92
96
  root,
93
97
  confirm: flag(args, '--confirm'),
94
98
  run: spawnRunner(root),
95
- ...(readOption(args, '--version') ? { version: readOption(args, '--version') } : {})
99
+ ...(readOption(args, '--version') ? { version: readOption(args, '--version') } : {}),
100
+ ...(readOption(args, '--physical-evidence-run-id')
101
+ ? { physicalEvidenceRunId: readOption(args, '--physical-evidence-run-id') }
102
+ : {}),
103
+ ...(readOption(args, '--physical-evidence-archive')
104
+ ? { physicalEvidenceArchive: readOption(args, '--physical-evidence-archive') }
105
+ : {})
96
106
  });
97
107
  await writeJsonAtomic(path.join(root, '.sneakoscope', 'reports', 'release-stage-publish.json'), report).catch(() => { });
98
108
  if (!report.ok)
@@ -6,7 +6,7 @@ import { TELEGRAM_TOKEN_ENV_NAMES, bindTelegramBotIdentity, issueTelegramPairing
6
6
  import { spawn } from 'node:child_process';
7
7
  import fs from 'node:fs/promises';
8
8
  import path from 'node:path';
9
- import { TelegramClient } from '../telegram/client.js';
9
+ import { TelegramApiError, TelegramClient } from '../telegram/client.js';
10
10
  import { redactTelegramError } from '../telegram/redaction.js';
11
11
  import { projectRoot } from '../fsx.js';
12
12
  import { projectRootRealpath } from '../session/project-namespace.js';
@@ -63,7 +63,7 @@ export function usage() {
63
63
  ' doctor Evaluate getMe, pairing, poller, and liveness evidence.',
64
64
  ' pair Issue a short-lived code for the intended private Telegram chat.',
65
65
  ' setup --token-stdin [--remove-webhook]',
66
- ' Verify and store an @BotFather token; an existing webhook requires explicit removal consent.',
66
+ ' Verify and store the token for any @BotFather bot you own; an existing webhook requires explicit removal consent.',
67
67
  ' prepare --stdin-json Validate an authorized native request through the typed contract.',
68
68
  ' execute --stdin-json Execute a prepared request; destructive requests also need --confirmed.',
69
69
  '',
@@ -108,16 +108,22 @@ export async function telegramCommand(args = [], dependencies = {}) {
108
108
  }
109
109
  if (action === 'setup') {
110
110
  if (!args.includes('--token-stdin'))
111
- return fail('telegram_token_stdin_required', json);
111
+ return telegramSetupFailure('telegram_token_stdin_required', json);
112
112
  if (args.includes('--drop-pending-updates'))
113
- return fail('telegram_drop_pending_updates_unsupported', json);
113
+ return telegramSetupFailure('telegram_drop_pending_updates_unsupported', json);
114
114
  const environment = dependencies.environment ?? process.env;
115
115
  const envOverrideActive = args.includes('--operator-env-override-active')
116
116
  || TELEGRAM_TOKEN_ENV_NAMES.some((name) => String(environment[name] ?? '').trim().length > 0);
117
117
  if (envOverrideActive)
118
118
  return telegramSetupEnvOverrideBlocked(json);
119
119
  const token = await (dependencies.readTokenStdin ?? readBoundedTokenStdin)();
120
- const identity = await (dependencies.verifyToken ?? verifyTelegramToken)(token);
120
+ let identity;
121
+ try {
122
+ identity = await (dependencies.verifyToken ?? verifyTelegramToken)(token);
123
+ }
124
+ catch (error) {
125
+ return telegramSetupFailure(telegramIdentityFailure(error), json, 'getme');
126
+ }
121
127
  const removeWebhook = args.includes('--remove-webhook');
122
128
  let webhook;
123
129
  try {
@@ -182,6 +188,7 @@ export async function telegramCommand(args = [], dependencies = {}) {
182
188
  webhook_configured_before: webhookConfigured,
183
189
  webhook_removed: webhookRemoved, pending_updates_dropped: false,
184
190
  bot_id: identity?.id ?? null,
191
+ bot_username: publicBotUsername(identity?.username),
185
192
  bot_rotated: binding?.rotated ?? false,
186
193
  bot_state_reset: binding?.state_reset ?? false,
187
194
  restart_required: true
@@ -214,7 +221,10 @@ export async function telegramCommand(args = [], dependencies = {}) {
214
221
  return fail('telegram_unknown_action', json, ['status', 'doctor', 'pair', 'setup', 'prepare', 'execute']);
215
222
  }
216
223
  catch (error) {
217
- return fail(error instanceof Error ? error.message : String(error), json);
224
+ const message = error instanceof Error ? error.message : String(error);
225
+ return action === 'setup'
226
+ ? telegramSetupFailure(redactTelegramError(error), json)
227
+ : fail(message, json);
218
228
  }
219
229
  }
220
230
  async function verifyTelegramToken(token) {
@@ -362,6 +372,36 @@ function fail(error, json, supported) {
362
372
  ...(supported ? { supported } : {})
363
373
  }, json);
364
374
  }
375
+ function telegramSetupFailure(error, json, failureStage) {
376
+ process.exitCode = 1;
377
+ return emit({
378
+ schema: 'sks.telegram-setup-command.v1',
379
+ ok: false,
380
+ error,
381
+ token_stored: false,
382
+ ...(failureStage ? { failure_stage: failureStage } : {})
383
+ }, json);
384
+ }
385
+ function telegramIdentityFailure(error) {
386
+ const message = redactTelegramError(error);
387
+ const code = error instanceof TelegramApiError ? error.code : null;
388
+ if (code === 401 || code === 404 || /\b(?:401|404|Unauthorized|Not Found)\b/i.test(message)) {
389
+ return 'telegram_token_rejected';
390
+ }
391
+ if (/telegram_(?:request_)?timeout|timed?\s*out/i.test(message)) {
392
+ return 'telegram_identity_verification_timeout';
393
+ }
394
+ if (/fetch failed|network|ENOTFOUND|ECONN|EAI_AGAIN|offline/i.test(message)) {
395
+ return 'telegram_identity_verification_network_failed';
396
+ }
397
+ if (message === 'telegram_token_invalid')
398
+ return message;
399
+ return 'telegram_identity_verification_failed';
400
+ }
401
+ function publicBotUsername(value) {
402
+ const normalized = String(value ?? '').trim();
403
+ return /^[A-Za-z0-9_]{5,64}$/.test(normalized) ? normalized : null;
404
+ }
365
405
  function telegramSetupPartialFailure(input, json) {
366
406
  process.exitCode = 1;
367
407
  return emit({
@@ -84,14 +84,16 @@ export function buildDoctorReadinessMatrix(input = {}) {
84
84
  if (codexAppHarness?.ok === false)
85
85
  for (const blocker of normalizeList(codexAppHarness.blockers))
86
86
  warnings.add(`codex_app_harness:${blocker}`);
87
- if (input.codex_lb?.ok === false)
88
- warnings.add(`codex_lb_${input.codex_lb?.circuit?.state || 'blocked'}`);
89
- if (input.codex_lb?.provider_status?.selected === true && input.codex_lb?.routing_ok !== true) {
90
- const routingBlockers = normalizeList(input.codex_lb?.routing_truth?.blockers);
91
- for (const blocker of routingBlockers)
87
+ const desktopBridge = input.desktop_bridge_status || input.desktop_bridge || null;
88
+ if (desktopBridge?.management?.managed === true && desktopBridge?.readiness?.ready !== true) {
89
+ const bridgeBlockers = normalizeList(desktopBridge?.readiness?.blockers);
90
+ for (const blocker of bridgeBlockers)
92
91
  blockers.add(blocker);
93
- if (!routingBlockers.length)
94
- blockers.add('codex_lb_routing_truth_unverified');
92
+ if (!bridgeBlockers.length)
93
+ blockers.add('desktop_bridge_not_ready');
94
+ }
95
+ if (desktopBridge?.management?.managed === true && desktopBridge?.service?.running !== true) {
96
+ warnings.add('desktop_bridge_service_not_running');
95
97
  }
96
98
  const localModel = input.local_model || {};
97
99
  const localStatus = String(localModel.status || (localModel.enabled ? 'enabled_unverified' : 'disabled'));
@@ -25,7 +25,7 @@ const REWRITE_RULES = [
25
25
  {
26
26
  id: 'cli-glm-profile',
27
27
  pattern: new RegExp(`${LEFT}sks\\s+codex-app\\s+glm-profile(?:\\s+[A-Za-z0-9_-]+)?${RIGHT}`, 'gi'),
28
- replace: '$1sks codex-app use-openrouter'
28
+ replace: '$1sks bridge provider configure openrouter --api-key-stdin'
29
29
  },
30
30
  { id: 'cli-mad-db', pattern: new RegExp(`${LEFT}sks\\s+mad-db${RIGHT}`, 'gi'), replace: '$1sks mad-sks' },
31
31
  { id: 'cli-team', pattern: new RegExp(`${LEFT}sks\\s+team${RIGHT}`, 'gi'), replace: '$1sks naruto' },
@@ -33,8 +33,8 @@ const REWRITE_RULES = [
33
33
  { id: 'cli-swarm', pattern: new RegExp(`${LEFT}sks\\s+swarm${RIGHT}`, 'gi'), replace: '$1sks naruto' },
34
34
  { id: 'cli-ralph', pattern: new RegExp(`${LEFT}sks\\s+ralph${RIGHT}`, 'gi'), replace: '$1sks loop' },
35
35
  { id: 'cli-tmux', pattern: new RegExp(`${LEFT}sks\\s+tmux${RIGHT}`, 'gi'), replace: '$1sks --mad' },
36
- { id: 'cli-xai', pattern: new RegExp(`${LEFT}sks\\s+xai${RIGHT}`, 'gi'), replace: '$1sks codex-app use-openrouter' },
37
- { id: 'cli-glm', pattern: new RegExp(`${LEFT}sks\\s+glm${RIGHT}`, 'gi'), replace: '$1sks codex-app use-openrouter' },
36
+ { id: 'cli-xai', pattern: new RegExp(`${LEFT}sks\\s+xai${RIGHT}`, 'gi'), replace: '$1sks bridge provider configure openrouter --api-key-stdin' },
37
+ { id: 'cli-glm', pattern: new RegExp(`${LEFT}sks\\s+glm${RIGHT}`, 'gi'), replace: '$1sks bridge provider configure openrouter --api-key-stdin' },
38
38
  { id: 'cli-ui', pattern: new RegExp(`${LEFT}sks\\s+ui${RIGHT}`, 'gi'), replace: '$1sks image-ux-review' },
39
39
  { id: 'cli-db', pattern: new RegExp(`${LEFT}sks\\s+db${RIGHT}`, 'gi'), replace: '$1sks mad-sks' },
40
40
  {
@@ -50,7 +50,7 @@ const REWRITE_RULES = [
50
50
  {
51
51
  id: 'cli-opt-glm',
52
52
  pattern: new RegExp(`${LEFT}sks\\s+--glm${RIGHT}`, 'gi'),
53
- replace: '$1sks codex-app use-openrouter'
53
+ replace: '$1sks bridge provider configure openrouter --api-key-stdin'
54
54
  },
55
55
  {
56
56
  id: 'cli-opt-naruto',
@@ -75,7 +75,7 @@ const REWRITE_RULES = [
75
75
  {
76
76
  id: 'opt-glm',
77
77
  pattern: new RegExp(`${LEFT}--glm${RIGHT}`, 'gi'),
78
- replace: '$1sks codex-app use-openrouter'
78
+ replace: '$1sks bridge provider configure openrouter --api-key-stdin'
79
79
  },
80
80
  {
81
81
  id: 'opt-naruto',
@@ -31,6 +31,7 @@ export function buildEvidenceKeyV2(input) {
31
31
  const projectId = validateProjectId(input.project_id);
32
32
  const directTargets = normalizeHashes(input.direct_target_hashes, 'evidence_target_hash_invalid');
33
33
  const directDependencies = normalizeHashes(input.direct_dependency_hashes, 'evidence_dependency_hash_invalid');
34
+ const routeContext = normalizeRouteContext(input.provider_route_context);
34
35
  const base = {
35
36
  schema: 'sks.evidence-key.v2',
36
37
  project_id: projectId,
@@ -38,23 +39,32 @@ export function buildEvidenceKeyV2(input) {
38
39
  check: safeId(input.check, 'evidence_check_invalid'),
39
40
  direct_target_hashes: directTargets,
40
41
  direct_dependency_merkle: merkle(directDependencies),
41
- auth_mode: input.auth_mode,
42
+ provider_route_context: routeContext,
42
43
  model_policy_hash: hashValue(input.model_policy_hash, 'evidence_model_policy_hash_invalid'),
43
44
  validator_rule: safeId(input.validator_rule, 'evidence_validator_rule_invalid'),
44
45
  validator_version: safeId(input.validator_version, 'evidence_validator_version_invalid'),
45
46
  environment_hash: hashValue(input.environment_hash, 'evidence_environment_hash_invalid'),
46
47
  toolchain_hash: hashValue(input.toolchain_hash, 'evidence_toolchain_hash_invalid')
47
48
  };
48
- return Object.freeze({ ...base, direct_target_hashes: Object.freeze(base.direct_target_hashes), key: sha256(canonicalJson(base)) });
49
+ return Object.freeze({
50
+ ...base,
51
+ direct_target_hashes: Object.freeze(base.direct_target_hashes),
52
+ provider_route_context: Object.freeze(base.provider_route_context),
53
+ key: sha256(canonicalJson(base))
54
+ });
49
55
  }
50
56
  export function selectAffectedReceipts(receipts, change) {
51
57
  const changedTargets = new Set(change.target_hashes || []);
52
58
  const changedDependencies = new Set(change.dependency_hashes || []);
59
+ const changedRouteContext = change.provider_route_context === undefined
60
+ ? undefined
61
+ : canonicalJson(normalizeRouteContext(change.provider_route_context));
53
62
  return receipts.filter((receipt) => {
54
63
  const evidence = receipt.evidence;
55
64
  return evidence.direct_target_hashes.some((value) => changedTargets.has(value))
56
65
  || receipt.direct_dependency_hashes.some((value) => changedDependencies.has(value))
57
- || (change.auth_mode !== undefined && change.auth_mode !== evidence.auth_mode)
66
+ || (changedRouteContext !== undefined
67
+ && changedRouteContext !== canonicalJson(evidence.provider_route_context))
58
68
  || (change.model_policy_hash !== undefined && change.model_policy_hash !== evidence.model_policy_hash)
59
69
  || (change.validator_rule !== undefined && change.validator_rule !== evidence.validator_rule)
60
70
  || (change.validator_version !== undefined && change.validator_version !== evidence.validator_version)
@@ -76,6 +86,18 @@ function normalizeHashes(values, code) {
76
86
  throw new Error(code);
77
87
  return normalized;
78
88
  }
89
+ function normalizeRouteContext(value) {
90
+ if (!value || !['codex-lb', 'openrouter'].includes(value.provider_id)) {
91
+ throw new Error('evidence_route_provider_invalid');
92
+ }
93
+ return {
94
+ provider_id: value.provider_id,
95
+ public_model: safeModelId(value.public_model, 'evidence_route_public_model_invalid'),
96
+ upstream_model: safeModelId(value.upstream_model, 'evidence_route_upstream_model_invalid'),
97
+ catalog_generation: safeId(value.catalog_generation, 'evidence_route_catalog_generation_invalid'),
98
+ route_policy_generation: safeId(value.route_policy_generation, 'evidence_route_policy_generation_invalid')
99
+ };
100
+ }
79
101
  function merkle(values) {
80
102
  let layer = values.map((value) => sha256(`leaf:${value}`));
81
103
  while (layer.length > 1) {
@@ -98,6 +120,11 @@ function safeId(value, code) {
98
120
  throw new Error(code);
99
121
  return value;
100
122
  }
123
+ function safeModelId(value, code) {
124
+ if (!/^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$/.test(String(value || '')))
125
+ throw new Error(code);
126
+ return value;
127
+ }
101
128
  function hashValue(value, code) {
102
129
  if (!/^[a-f0-9]{64}$/.test(String(value || '')))
103
130
  throw new Error(code);
@@ -28,7 +28,14 @@ const FIXTURES = Object.freeze({
28
28
  'cli-setup': fixture('real_optional', 'sks setup --json --local-only', [], 'pass'),
29
29
  'cli-codex': fixture('execute', 'sks codex compatibility --json', [], 'pass'),
30
30
  'cli-codex-app': fixture('real_optional', 'sks codex-app check --json', [], 'pass'),
31
- 'cli-codex-lb': fixture('execute_and_validate_artifacts', 'sks codex-lb metrics --json', [], 'pass'),
31
+ 'cli-bridge': fixture('execute', 'sks bridge status --json', [], 'pass', {
32
+ expected_stdout_fields: {
33
+ schema: 'sks.desktop-bridge-status.v3',
34
+ execution_ok: true,
35
+ 'routing.fallback': 'none'
36
+ },
37
+ reason: 'The read-only status command proves the installed Desktop Bridge JSON facade and fail-closed no-fallback routing contract without configuring a provider, starting a service, or reading a plaintext credential.'
38
+ }),
32
39
  'cli-telegram': fixture('execute', 'sks telegram --help', [], 'pass', {
33
40
  quality: 'wiring_only',
34
41
  reason: 'The non-mutating help path proves the installed Telegram command is wired without requiring a bot token, private-file state, resident poller, or network access; transport behavior is covered by focused Telegram tests.'
@@ -15,7 +15,6 @@ export const FEATURE_INVENTORY_SCHEMA = 'sks.feature-inventory.v1';
15
15
  export const ALL_FEATURES_SELFTEST_SCHEMA = 'sks.all-features-selftest.v1';
16
16
  export const ALL_FEATURE_COMPLETION_SCHEMA = 'sks.all-feature-completion.v1';
17
17
  const HANDLER_ALIAS_TO_COMMAND = Object.freeze({
18
- auth: 'codex-lb',
19
18
  hook: 'hooks',
20
19
  memory: 'gc',
21
20
  postinstall: 'postinstall',
@@ -536,7 +535,7 @@ const SAFE_EXECUTABLE_FIXTURE_ARGS = Object.freeze({
536
535
  'cli-wrongness': ['wrongness', 'validate', 'project', '--json'],
537
536
  'cli-wiki': ['wiki', 'image-ingest', 'test/fixtures/images/one-by-one.png', '--json'],
538
537
  'cli-codex': ['codex', 'compatibility', '--json'],
539
- 'cli-codex-lb': ['codex-lb', 'metrics', '--json'],
538
+ 'cli-bridge': ['bridge', 'status', '--json'],
540
539
  'cli-hooks': ['hooks', 'trust-report', '--json'],
541
540
  'cli-perf': ['perf', 'cold-start', '--json', '--iterations', '1'],
542
541
  'cli-bench': ['bench', 'core', '--tier', 'npx-one-shot', '--json', '--iterations', '1'],
@@ -937,6 +936,8 @@ function isExternalPromptCommandMention(mention) {
937
936
  '$CODEX_HOME',
938
937
  '$HOME',
939
938
  '$CODEX_LB_API_KEY',
939
+ '$CODEX_LB_KEY',
940
+ '$OPENROUTER_KEY',
940
941
  '$SKS_CODEX_APP_IMAGEGEN_OUTPUT',
941
942
  '$SKS_CODEX_APP_IMAGEGEN_OUTPUT_ID',
942
943
  '$SKS_CODEX_APP_IMAGEGEN_CREATED_AT',
@@ -97,6 +97,8 @@ function honestGapHeadingResolved(line, nextLine) {
97
97
  return /^(?:없음|없습니다|없다|none|no(?:ne)?|0|0개)[.!。]?$/i.test(String(nextLine || '').trim());
98
98
  }
99
99
  function honestGapLineResolved(line) {
100
+ if (honestIssueLineCompleted(line))
101
+ return true;
100
102
  if (/(?:unverified|미검증)\s*:\s*\[\s*\]/i.test(line) && /blockers?\s*:\s*\[\s*\]/i.test(line))
101
103
  return true;
102
104
  if (/(?:^|[\s*-])(?:unverified|미검증|blockers?)\s*:\s*\[\s*\](?:\s*(?:[,.;]|$).*)?$/i.test(line))
@@ -111,7 +113,7 @@ function honestGapLineResolved(line) {
111
113
  return true;
112
114
  if (/no\s+active\s+blocking\s+route\s+gate\s+detected/i.test(line))
113
115
  return true;
114
- if (/(?:blockers?|차단(?:\s*(?:항목|요소|건))?)\s*(?:[:=]\s*)?0(?:건|개)?\b/i.test(line))
116
+ if (/(?:blockers?(?:은|는|이|가)?|차단(?:\s*(?:항목|요소|건))?)\s*(?:[:=]\s*)?0(?:건|개)?\b/i.test(line))
115
117
  return true;
116
118
  if (/(non[-\s]?blocker|non[-\s]?blocking|not\s+(?:a\s+)?blocker|no\s+blocker|does\s+not\s+block|not\s+blocking|비\s*차단|blocker\s*(?:는|가)?\s*(?:아님|아닙니다|없음)|차단(?:하지|하진|하지는)\s*않|막(?:지|지는)\s*않)/i.test(line))
117
119
  return true;
@@ -123,6 +125,14 @@ function honestGapLineResolved(line) {
123
125
  return false;
124
126
  return /(없음|없습니다|없다|해당 없음|none|no unresolved|no remaining|no gaps|zero|0개|n\/a|not applicable)\.?\s*$/i.test(line);
125
127
  }
128
+ function honestIssueLineCompleted(line) {
129
+ const text = String(line || '').trim();
130
+ const unresolved = /(?:미해결|미완료|해결|수정|보완)\s*(?:필요|예정|대기|중)|(?:not|isn't|wasn't)\s+(?:fixed|resolved|addressed|implemented|completed)|(?:still|remains?|pending)\b/i;
131
+ if (unresolved.test(text))
132
+ return false;
133
+ return /(?:해결|수정|보완|정상화|완료)(?:했(?:습니다|다|음)?|됐(?:습니다|다)?|됨|함)?[.!。`*_)]*$/i.test(text)
134
+ || /(?:fixed|resolved|addressed|implemented|completed)[.!。`*_)]*$/i.test(text);
135
+ }
126
136
  export function shouldLoopBackAfterHonestMode(state = {}) {
127
137
  if (!state?.mission_id || state.implementation_allowed === false)
128
138
  return false;
@@ -45,7 +45,7 @@ function extractSubagentAgentName(payload = {}) {
45
45
  return '';
46
46
  }
47
47
  export function subagentRouteContext(state = {}) {
48
- if (!state?.route && !state?.mode)
48
+ if (state?.route_closed === true || (!state?.route && !state?.mode))
49
49
  return '';
50
50
  const route = state.route_command || state.route || state.mode;
51
51
  const mission = state.mission_id ? ` for mission ${state.mission_id}` : '';
@@ -57,3 +57,17 @@ export function subagentRouteContext(state = {}) {
57
57
  : '';
58
58
  return `You are a child thread on ${route}${mission}. Execute only the slice assigned by the parent.${artifacts} Do not spawn or delegate other agents, wait for sibling threads, integrate sibling results, close the parent route, or author the sks.subagent-parent-summary.v1 parent result. Return a concise slice result to the parent.${databaseBoundary}`;
59
59
  }
60
+ export function officialSubagentSkillGuardBinding(state = {}, options = {}) {
61
+ const missionId = String(state?.mission_id || '').trim();
62
+ const workflowRunId = String(state?.official_subagent_run_id || '').trim();
63
+ const routeIdentity = String(state?.mode || state?.route || state?.route_command || '').replace(/^\$/, '').toUpperCase();
64
+ const activeNaruto = routeIdentity === 'NARUTO' || routeIdentity === 'SKS-NARUTO';
65
+ if (state?.route_closed === true) {
66
+ return options.allowClosedOfficialChild && activeNaruto && missionId && workflowRunId
67
+ ? { missionId, workflowRunId }
68
+ : null;
69
+ }
70
+ if (!activeNaruto && (!missionId || !workflowRunId))
71
+ return null;
72
+ return { missionId, workflowRunId };
73
+ }
@@ -9,7 +9,7 @@ export const MAX_GUARD_DIRECTORY_ENTRIES = (HARD_NARUTO_MAX_THREADS * 2) + 16;
9
9
  export const MAX_LIFECYCLE_GUARD_BYTES = 64 * 1024;
10
10
  export const MAX_SUBAGENT_PLAN_BYTES = 256 * 1024;
11
11
  export const ADMISSION_SCHEMA = 'sks.subagent-skill-availability-admission.v1';
12
- export const SUBAGENT_ADMISSION_BLOCKER_RE = /^(?:authoritative_sks_skill_resolution_failed|authoritative_sks_skill_candidate_rejected|authoritative_sks_skill_unavailable:sks(?:-[a-z0-9]+)*|subagent_skill_availability_(?:artifact_dir_unsafe|blocker_artifact_write_failed|guard_persistence_failed))$/;
12
+ export const SUBAGENT_ADMISSION_BLOCKER_RE = /^(?:authoritative_sks_skill_resolution_failed|authoritative_sks_skill_candidate_rejected|authoritative_sks_skill_unavailable:sks(?:-[a-z0-9]+)*|subagent_skill_availability_(?:artifact_dir_unsafe|blocker_artifact_write_failed|guard_invalid|guard_persistence_failed))$/;
13
13
  export class SubagentSkillAvailabilityGuardError extends Error {
14
14
  childEvidence;
15
15
  constructor(childEvidence) {
@@ -87,6 +87,6 @@ export function interruptedToolOutputRecoveryBlockReason(input = {}) {
87
87
  `SKS blocked same-thread continuation because custom tool call ${callId} has no correlated output (active mission: ${missionId}).`,
88
88
  'The current Codex conversation state may be structurally invalid, so additional context cannot repair the pending Responses request.',
89
89
  'Treat the call result as unknown and do not replay a possibly mutating action.',
90
- 'Upgrade the selected codex-lb to the official latest stable release (`sks codex-lb status --json` reports whether the deployment satisfies tool-heavy continuation), or explicitly disable only codex-lb routing with `sks codex-lb disable`, then open a fresh Codex thread and continue the persisted mission after inspecting side effects. ChatGPT OAuth is not replaced by either action.'
90
+ 'Inspect the current provider with `sks bridge status --json` and verify it with `sks bridge verify --level deep --strict`; if codex-lb remains unavailable, disable only that provider with `sks bridge provider disable codex-lb`, then open a fresh Codex thread and continue the persisted mission after inspecting side effects. These actions do not replace ChatGPT OAuth or delete provider credentials.'
91
91
  ].join(' ');
92
92
  }